From 2d2ce2bcb4af573dc91a759807355980feae6b7d Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Tue, 5 Nov 2024 13:54:40 -0600 Subject: [PATCH 001/451] created and set totalTravel --- include/BLE_Custom_Characteristic.h | 1 + include/ERG_Mode.h | 2 ++ include/SmartSpin_parameters.h | 4 ++++ src/BLE_Custom_Characteristic.cpp | 22 ++++++++++++++++++++++ src/Main.cpp | 3 +++ 5 files changed, 32 insertions(+) diff --git a/include/BLE_Custom_Characteristic.h b/include/BLE_Custom_Characteristic.h index ce91a0be..8cacbf1c 100644 --- a/include/BLE_Custom_Characteristic.h +++ b/include/BLE_Custom_Characteristic.h @@ -60,6 +60,7 @@ const uint8_t BLE_simulatedTargetWatts = 0x28; // current target watts const uint8_t BLE_simulateTargetWatts = 0x29; // are we sending target watts const uint8_t BLE_hMin = 0x2A; // Minimum homing value const uint8_t BLE_hMax = 0x2B; // Maximum homing value +const uint8_t BLE_totalTravel = 0x2C; // Total travel class BLE_ss2kCustomCharacteristic { public: diff --git a/include/ERG_Mode.h b/include/ERG_Mode.h index afdba436..4880333a 100644 --- a/include/ERG_Mode.h +++ b/include/ERG_Mode.h @@ -19,6 +19,7 @@ class PowerEntry { public: int watts; + int resistance; int32_t targetPosition; int cad; int readings; @@ -28,6 +29,7 @@ class PowerEntry { this->targetPosition = 0; this->cad = 0; this->readings = 0; + this->resistance = 0; } }; diff --git a/include/SmartSpin_parameters.h b/include/SmartSpin_parameters.h index d4ccd60d..1799c0b2 100644 --- a/include/SmartSpin_parameters.h +++ b/include/SmartSpin_parameters.h @@ -126,6 +126,7 @@ class userParameters { bool udpLogEnabled = false; int32_t hMin = INT32_MIN; int32_t hMax = INT32_MIN; + int32_t totalTravel; bool FTMSControlPointWrite = false; String ssid; @@ -196,6 +197,9 @@ class userParameters { void setShifterDir(bool shd) { shifterDir = shd; } bool getShifterDir() { return shifterDir; } + void setTotalTravel(int tT) { totalTravel = tT; } + bool getTotalTravel() { return totalTravel; } + void setUdpLogEnabled(bool enabled) { udpLogEnabled = enabled; } bool getUdpLogEnabled() { return udpLogEnabled; } diff --git a/src/BLE_Custom_Characteristic.cpp b/src/BLE_Custom_Characteristic.cpp index cce568ea..70baf77d 100644 --- a/src/BLE_Custom_Characteristic.cpp +++ b/src/BLE_Custom_Characteristic.cpp @@ -738,6 +738,22 @@ void BLE_ss2kCustomCharacteristic::process(std::string rxValue) { ss2k->setTargetPosition(int32_t((uint8_t)(rxValue[2]) << 0 | (uint8_t)(rxValue[3]) << 8 | (uint8_t)(rxValue[4]) << 16 | (uint8_t)(rxValue[5]) << 24)); logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, " (%f)", userConfig->getHMax()); } + + case BLE_totalTravel: // 0x2C + logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "<-totalTravel"); + if (rxValue[0] == cc_read) { + returnValue[0] = cc_success; + returnValue[2] = (uint8_t)(userConfig->getTotalTravel() & 0xff); + returnValue[3] = (uint8_t)(userConfig->getTotalTravel() >> 8); + returnValue[4] = (uint8_t)(userConfig->getTotalTravel() >> 16); + returnValue[5] = (uint8_t)(userConfig->getTotalTravel() >> 24); + returnLength += 4; + } + if (rxValue[0] == cc_write) { + returnValue[0] = cc_success; + ss2k->setTargetPosition(int32_t((uint8_t)(rxValue[2]) << 0 | (uint8_t)(rxValue[3]) << 8 | (uint8_t)(rxValue[4]) << 16 | (uint8_t)(rxValue[5]) << 24)); + logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, " (%f)", userConfig->getTotalTravel()); + } break; } @@ -900,4 +916,10 @@ void BLE_ss2kCustomCharacteristic::parseNemit() { BLE_ss2kCustomCharacteristic::notify(BLE_hMax); return; } + + if(userConfig->getTotalTravel() != _oldParams.getTotalTravel()){ + _oldParams.setTotalTravel(userConfig->getTotalTravel()); + BLE_ss2kCustomCharacteristic::notify(BLE_totalTravel); + return; + } } \ No newline at end of file diff --git a/src/Main.cpp b/src/Main.cpp index 13b2a0ff..dd7675fb 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -584,6 +584,7 @@ void SS2K::goHome(bool bothDirections) { vTaskDelay(2000 / portTICK_PERIOD_MS); rtConfig->setMaxStep(stepper->getCurrentPosition() - 200); SS2K_LOG(MAIN_LOG_TAG, "Max Position found: %d.", rtConfig->getMaxStep()); + rtConfig->setMaxResistance(rtConfig->resistance.getValue()); stepper->enableOutputs(); } stepper->runBackward(); @@ -600,12 +601,14 @@ void SS2K::goHome(bool bothDirections) { stepper->setCurrentPosition((int32_t)0); rtConfig->setMinStep(stepper->getCurrentPosition() + userConfig->getShiftStep()); SS2K_LOG(MAIN_LOG_TAG, "Min Position found: %d.", rtConfig->getMinStep()); + rtConfig->setMinResistance(rtConfig->resistance.getValue()); stepper->enableOutputs(); // Start Saving Settings if (bothDirections) { userConfig->setHMin(rtConfig->getMinStep()); userConfig->setHMax(rtConfig->getMaxStep()); + userConfig->setTotalTravel(userConfig->getHMax() - userConfig->getHMin()); } // In case this was only one direction homing. rtConfig->setMaxStep(userConfig->getHMax()); From 42787eb3cbc67cf9b8e233da7d78badbc5d7ab2f Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Thu, 26 Dec 2024 12:30:31 -0600 Subject: [PATCH 002/451] added CSC to the sensordatafactory --- lib/SS2K/include/sensors/CscSensorData.h | 35 +++++++++ lib/SS2K/src/sensors/CscSensorData.cpp | 90 ++++++++++++++++++++++ lib/SS2K/src/sensors/SensorDataFactory.cpp | 3 + 3 files changed, 128 insertions(+) create mode 100644 lib/SS2K/include/sensors/CscSensorData.h create mode 100644 lib/SS2K/src/sensors/CscSensorData.cpp diff --git a/lib/SS2K/include/sensors/CscSensorData.h b/lib/SS2K/include/sensors/CscSensorData.h new file mode 100644 index 00000000..86fe3245 --- /dev/null +++ b/lib/SS2K/include/sensors/CscSensorData.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2020 Anthony Doud & Joel Baranick + * All rights reserved + * + * SPDX-License-Identifier: GPL-2.0-only + */ + +#pragma once + +#include "SensorData.h" + +class CscSensorData : public SensorData { + public: + CscSensorData() : SensorData("CSC") {} + + bool hasHeartRate(); + bool hasCadence(); + bool hasPower(); + bool hasSpeed(); + bool hasResistance(); + int getHeartRate(); + float getCadence(); + int getPower(); + float getSpeed(); + int getResistance(); + void decode(uint8_t *data, size_t length); + + private: + float cadence = nanf(""); + float speed = nanf(""); + uint32_t lastWheelEventTime = 0; + uint32_t lastCrankEventTime = 0; + uint32_t lastWheelRevolutions = 0; + uint32_t lastCrankRevolutions = 0; +}; \ No newline at end of file diff --git a/lib/SS2K/src/sensors/CscSensorData.cpp b/lib/SS2K/src/sensors/CscSensorData.cpp new file mode 100644 index 00000000..1623c071 --- /dev/null +++ b/lib/SS2K/src/sensors/CscSensorData.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2020 Anthony Doud & Joel Baranick + * All rights reserved + * + * SPDX-License-Identifier: GPL-2.0-only + */ + +#include "Data.h" +#include "endian.h" +#include "sensors/CscSensorData.h" + +bool CscSensorData::hasHeartRate() { return false; } + +bool CscSensorData::hasCadence() { return !std::isnan(this->cadence); } + +bool CscSensorData::hasPower() { return false; } + +bool CscSensorData::hasSpeed() { return !std::isnan(this->speed); } + +bool CscSensorData::hasResistance() { return false; } + +int CscSensorData::getHeartRate() { return INT_MIN; } + +float CscSensorData::getCadence() { return this->cadence; } + +int CscSensorData::getPower() { return INT_MIN; } + +float CscSensorData::getSpeed() { return this->speed; } + +int CscSensorData::getResistance() { return INT_MIN; } + +void CscSensorData::decode(uint8_t *data, size_t length) { + uint8_t flags = data[0]; + int pos = 1; // Start after flags byte + + // Check wheel revolution data present flag (bit 0) + if (flags & 0x01) { + uint32_t wheelRevolutions = get_le32(&data[pos]); + pos += 4; + uint16_t wheelEventTime = get_le16(&data[pos]); + pos += 2; + + // Calculate speed if we have previous measurements + if (lastWheelEventTime > 0) { + // Handle timer wraparound (16-bit timer) + uint16_t timeDiff = (wheelEventTime >= lastWheelEventTime) ? + (wheelEventTime - lastWheelEventTime) : + (65535 - lastWheelEventTime + wheelEventTime); + + if (timeDiff > 0) { + // Convert to meters/second then km/h + // Time is in 1/1024th of a second + float wheelCircumference = 2.095f; // Default 700c wheel circumference in meters + float revolutions = wheelRevolutions - lastWheelRevolutions; + float timeSeconds = timeDiff / 1024.0f; + float speedMS = (revolutions * wheelCircumference) / timeSeconds; + this->speed = speedMS * 3.6f; // Convert m/s to km/h + } + } + + lastWheelRevolutions = wheelRevolutions; + lastWheelEventTime = wheelEventTime; + } + + // Check crank revolution data present flag (bit 1) + if (flags & 0x02) { + uint16_t crankRevolutions = get_le16(&data[pos]); + pos += 2; + uint16_t crankEventTime = get_le16(&data[pos]); + pos += 2; + + // Calculate cadence if we have previous measurements + if (lastCrankEventTime > 0) { + // Handle timer wraparound (16-bit timer) + uint16_t timeDiff = (crankEventTime >= lastCrankEventTime) ? + (crankEventTime - lastCrankEventTime) : + (65535 - lastCrankEventTime + crankEventTime); + + if (timeDiff > 0) { + // Time is in 1/1024th of a second + float revolutions = crankRevolutions - lastCrankRevolutions; + float timeMinutes = (timeDiff / 1024.0f) / 60.0f; + this->cadence = revolutions / timeMinutes; + } + } + + lastCrankRevolutions = crankRevolutions; + lastCrankEventTime = crankEventTime; + } +} \ No newline at end of file diff --git a/lib/SS2K/src/sensors/SensorDataFactory.cpp b/lib/SS2K/src/sensors/SensorDataFactory.cpp index a2eb32c2..cf6be01b 100644 --- a/lib/SS2K/src/sensors/SensorDataFactory.cpp +++ b/lib/SS2K/src/sensors/SensorDataFactory.cpp @@ -14,6 +14,7 @@ #include "sensors/HeartRateData.h" #include "sensors/EchelonData.h" #include "sensors/PelotonData.h" +#include "sensors/CscSensorData.h" std::shared_ptr SensorDataFactory::getSensorData(const NimBLEUUID characteristicUUID, const uint64_t peerAddress, uint8_t *data, size_t length) { for (auto &it : SensorDataFactory::knownDevices) { @@ -35,6 +36,8 @@ std::shared_ptr SensorDataFactory::getSensorData(const NimBLEUUID ch sensorData = std::shared_ptr(new EchelonData()); } else if (characteristicUUID == PELOTON_DATA_UUID) { sensorData = std::shared_ptr(new PelotonData()); + } else if (characteristicUUID == CSCMEASUREMENT_UUID) { + sensorData = std::shared_ptr(new CscSensorData()); } else { return NULL_SENSOR_DATA; } From 63718a37726df465db3ebd617f436e33e4c7ffac Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 1 Jan 2025 18:18:16 -0600 Subject: [PATCH 003/451] Supports Multipile Characteristics in notify Queue --- include/BLE_Common.h | 7 +++-- lib/SS2K/include/Constants.h | 4 +-- platformio.ini | 2 +- src/BLE_Client.cpp | 58 +++++++++++++++++------------------- src/BLE_Server.cpp | 2 +- src/Main.cpp | 2 +- 6 files changed, 37 insertions(+), 38 deletions(-) diff --git a/include/BLE_Common.h b/include/BLE_Common.h index 0fe36269..3c895a2a 100644 --- a/include/BLE_Common.h +++ b/include/BLE_Common.h @@ -98,6 +98,7 @@ void bleClientTask(void *pvParameters); // FLYWHEEL_UART_TX_UUID}; typedef struct NotifyData { + NimBLEUUID charUUID; uint8_t data[25]; size_t length; } NotifyData; @@ -136,7 +137,7 @@ class SpinBLEAdvertisedDevice { void set(BLEAdvertisedDevice *device, int id = BLE_HS_CONN_HANDLE_NONE, BLEUUID inServiceUUID = (uint16_t)0x0000, BLEUUID inCharUUID = (uint16_t)0x0000); void reset(); void print(); - bool enqueueData(uint8_t data[25], size_t length); + bool enqueueData(uint8_t data[25], size_t length, NimBLEUUID charUUID); NotifyData dequeueData(); }; @@ -183,10 +184,10 @@ class SpinBLEClient { // Disconnects all devices. They will then be reconnected if scanned and preferred again. void reconnectAllDevices(); - String adevName2UniqueName(NimBLEAdvertisedDevice *inDev); + String adevName2UniqueName(const NimBLEAdvertisedDevice *inDev); }; -class MyAdvertisedDeviceCallback : public NimBLEAdvertisedDeviceCallbacks { +class ScanCallbacks : public NimBLEScanCallbacks { public: void onResult(NimBLEAdvertisedDevice *); }; diff --git a/lib/SS2K/include/Constants.h b/lib/SS2K/include/Constants.h index c30fdee6..f5a66edb 100644 --- a/lib/SS2K/include/Constants.h +++ b/lib/SS2K/include/Constants.h @@ -77,8 +77,8 @@ #define ECHELON_DATA_UUID NimBLEUUID("0bf669f4-45f2-11e7-9598-0800200c9a66") // Dummy UUID for Peloton Serial Data Interface -#define PELOTON_DATA_UUID NimBLEUUID("00000000-0000-0000-0000-0000000000321") -#define PELOTON_ADDRESS NimBLEAddress("00:00:00:00:00:00:00") +#define PELOTON_DATA_UUID NimBLEUUID("00000000-0000-0000-0000-000000000321") +#define PELOTON_ADDRESS NimBLEAddress("00:00:00:00:00:00", 0) // peloton Serial #define PELOTON_RQ_SIZE 4 #define PELOTON_HEADER 0xF1 diff --git a/platformio.ini b/platformio.ini index 4837d707..07f1ac90 100644 --- a/platformio.ini +++ b/platformio.ini @@ -29,7 +29,7 @@ build_flags = -D CORE_DEBUG_LEVEL=1 -D ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=3500 lib_deps = - https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/1.4.0.zip + https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.1.2.zip https://github.com/teemuatlut/TMCStepper/archive/refs/tags/v0.7.3.zip https://github.com/bblanchon/ArduinoJson/archive/refs/tags/v6.20.0.zip https://github.com/gin66/FastAccelStepper/archive/refs/tags/0.31.2.zip diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index 67ef9ded..5fce7786 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -26,7 +26,7 @@ TaskHandle_t BLEClientTask; SpinBLEClient spinBLEClient; static MyClientCallback myClientCallback; -static MyAdvertisedDeviceCallback myAdvertisedDeviceCallbacks; +static ScanCallbacks myScanCallbacks; void SpinBLEClient::start() { // Create the task for the BLE Client loop @@ -53,8 +53,8 @@ static void onNotify(BLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t // enqueue sensor data for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { - if (pBLERemoteCharacteristic->getUUID() == spinBLEClient.myBLEDevices[i].charUUID) { - spinBLEClient.myBLEDevices[i].enqueueData(pData, length); + if (pBLERemoteCharacteristic->getClient()->getPeerAddress() == spinBLEClient.myBLEDevices[i].peerAddress) { + spinBLEClient.myBLEDevices[i].enqueueData(pData, length, pBLERemoteCharacteristic->getUUID()); } } } @@ -107,11 +107,11 @@ void bleClientTask(void *pvParameters) { } } // Spin Down process for the Server. It's here because it needs to be non-blocking for the maintenance loop. - // Checking for cadence also so that we don't home when nobody is around. + // Checking for cadence also so that we don't home when nobody is around. if (spinBLEServer.spinDownFlag && rtConfig->cad.getValue()) { if (spinBLEServer.spinDownFlag >= 2) { // Home Both Directions ss2k->goHome(true); - } else { // Startup Homing + } else { // Startup Homing ss2k->goHome(false); } spinBLEServer.spinDownFlag = 0; @@ -199,7 +199,7 @@ bool SpinBLEClient::connectToServer() { NimBLEClient *pClient = nullptr; /** Check if we have a client we should reuse first **/ - if (NimBLEDevice::getClientListSize()) { + if (NimBLEDevice::getCreatedClientCount()) { /** Special case when we already know this device, we send false as the * second argument in connect() to prevent refreshing the service database. * This saves considerable time and power. @@ -233,7 +233,7 @@ bool SpinBLEClient::connectToServer() { /** No client to reuse? Create a new one. */ if (!pClient) { - if (NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS) { + if (NimBLEDevice::getCreatedClientCount() >= NIMBLE_MAX_CONNECTIONS) { Serial.println("Max clients reached - no more connections available"); return false; } @@ -278,7 +278,7 @@ bool SpinBLEClient::connectToServer() { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Successful remote subscription."); spinBLEClient.myBLEDevices[device_number].doConnect = false; this->reconnectTries = MAX_RECONNECT_TRIES; - spinBLEClient.myBLEDevices[device_number].set(myDevice, pClient->getConnId(), serviceUUID, charUUID); + spinBLEClient.myBLEDevices[device_number].set(myDevice, pClient->getConnHandle(), serviceUUID, charUUID); spinBLEClient.myBLEDevices[device_number].peerAddress = pClient->getPeerAddress(); removeDuplicates(pClient); return true; @@ -330,7 +330,7 @@ bool SpinBLEClient::connectToServer() { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Successful %s subscription.", pChr->getUUID().toString().c_str()); spinBLEClient.myBLEDevices[device_number].doConnect = false; this->reconnectTries = MAX_RECONNECT_TRIES; - spinBLEClient.myBLEDevices[device_number].set(myDevice, pClient->getConnId(), serviceUUID, charUUID); + spinBLEClient.myBLEDevices[device_number].set(myDevice, pClient->getConnHandle(), serviceUUID, charUUID); spinBLEClient.myBLEDevices[device_number].peerAddress = pClient->getPeerAddress(); removeDuplicates(pClient); } @@ -401,7 +401,7 @@ void MyClientCallback::onAuthenticationComplete(ble_gap_conn_desc desc) { SS2K_L * Scan for BLE servers and find the first one that advertises the service we are looking for. */ -void MyAdvertisedDeviceCallback::onResult(BLEAdvertisedDevice *advertisedDevice) { +void ScanCallbacks::onResult(BLEAdvertisedDevice *advertisedDevice) { // Define granular constants for maximal reuse during logging const char *const MATCHED = "Matched "; const char *const DIDNT_MATCH_THE_SAVED = " didn't match the saved: "; @@ -483,18 +483,16 @@ void SpinBLEClient::scanProcess(int duration) { BLEScan *pBLEScan = BLEDevice::getScan(); pBLEScan->stop(); vTaskDelay(50 / portTICK_PERIOD_MS); - pBLEScan->clearDuplicateCache(); pBLEScan->clearResults(); - pBLEScan->setAdvertisedDeviceCallbacks(&myAdvertisedDeviceCallbacks); + pBLEScan->setScanCallbacks(&myScanCallbacks); pBLEScan->setInterval(49); // 97 pBLEScan->setWindow(33); // 67 pBLEScan->setDuplicateFilter(true); pBLEScan->setActiveScan(true); // might cause memory leak if true - undetermined. We don't get device names without it. - BLEScanResults foundDevices = pBLEScan->start(duration, false); - this->dontBlockScan = false; - - int count = foundDevices.getCount(); + pBLEScan->start(duration, false); + this->dontBlockScan = false; + int count = pBLEScan->getResults().getCount(); StaticJsonDocument<1000> devices; // Check if 'devices' JSON document already exists and has content; if so, deserialize it. @@ -504,32 +502,32 @@ void SpinBLEClient::scanProcess(int duration) { } for (int i = 0; i < count; i++) { - BLEAdvertisedDevice d = foundDevices.getDevice(i); + const NimBLEAdvertisedDevice* d = pBLEScan->getResults().getDevice(i); // Check for duplicates by name or address before adding bool isDuplicate = false; for (JsonPair kv : devices.as()) { JsonObject obj = kv.value().as(); - if (obj.containsKey("name") && obj["name"] == this->adevName2UniqueName(&d)) { + if (obj.containsKey("name") && obj["name"] == this->adevName2UniqueName(d)) { isDuplicate = true; break; } } // is this device advertising something we're interested in? - if (!isDuplicate && (d.isAdvertisingService(CYCLINGPOWERSERVICE_UUID) || d.isAdvertisingService(HEARTSERVICE_UUID) || d.isAdvertisingService(FLYWHEEL_UART_SERVICE_UUID) || - d.isAdvertisingService(FITNESSMACHINESERVICE_UUID) || d.isAdvertisingService(ECHELON_DEVICE_UUID) || d.isAdvertisingService(HID_SERVICE_UUID))) { + if (!isDuplicate && (d->isAdvertisingService(CYCLINGPOWERSERVICE_UUID) || d->isAdvertisingService(HEARTSERVICE_UUID) || d->isAdvertisingService(FLYWHEEL_UART_SERVICE_UUID) || + d->isAdvertisingService(FITNESSMACHINESERVICE_UUID) || d->isAdvertisingService(ECHELON_DEVICE_UUID) || d->isAdvertisingService(HID_SERVICE_UUID))) { String device = "device " + String(devices.size()); // Use the current size to index the new device - devices[device]["name"] = this->adevName2UniqueName(&d); + devices[device]["name"] = this->adevName2UniqueName(d); // Workaround for IC4 not advertising FTMS as the first service. // Potentially others may need to be added in the future. // The symptom was the bike name not showing up in the HTML. - if (d.haveServiceUUID() && d.isAdvertisingService(FITNESSMACHINESERVICE_UUID)) { + if (d->haveServiceUUID() && d->isAdvertisingService(FITNESSMACHINESERVICE_UUID)) { devices[device]["UUID"] = FITNESSMACHINESERVICE_UUID.toString(); } else { - devices[device]["UUID"] = d.getServiceUUID().toString(); + devices[device]["UUID"] = d->getServiceUUID().toString(); } } } @@ -661,7 +659,7 @@ void SpinBLEClient::postConnect() { } writeCharacteristic->writeValue(FitnessMachineControlPointProcedure::StartOrResume, 1); SS2K_LOG(BLE_CLIENT_LOG_TAG, "Updating Connection Params for: %s", _BLEd.peerAddress.toString().c_str()); - BLEDevice::getServer()->updateConnParams(pClient->getConnId(), 120, 120, 2, 1000); + BLEDevice::getServer()->updateConnParams(pClient->getConnHandle(), 120, 120, 2, 1000); spinBLEClient.handleBattInfo(pClient, true); } } @@ -669,7 +667,7 @@ void SpinBLEClient::postConnect() { } } -bool SpinBLEAdvertisedDevice::enqueueData(uint8_t *data, size_t length) { +bool SpinBLEAdvertisedDevice::enqueueData(uint8_t *data, size_t length, NimBLEUUID charUUID) { NotifyData notifyData; if (!uxQueueSpacesAvailable(this->dataBufferQueue)) { @@ -677,7 +675,8 @@ bool SpinBLEAdvertisedDevice::enqueueData(uint8_t *data, size_t length) { return pdFALSE; } - notifyData.length = length; + notifyData.length = length; + notifyData.charUUID = charUUID; for (size_t i = 0; i < length; i++) { notifyData.data[i] = data[i]; // Serial.printf("%02x ", notifyData.data[i]); @@ -756,9 +755,8 @@ void SpinBLEClient::connectBLE_HID(NimBLEClient *pClient) { // One real device reports 2 with the same UUID but // different handles. Using getCharacteristic() results // in subscribing to only one. - std::vector *charVector; - charVector = pSvc->getCharacteristics(true); - for (auto &it : *charVector) { + std::vector charVector = pSvc->getCharacteristics(true); + for (auto &it : charVector) { if (it->getUUID() == NimBLEUUID(HID_REPORT_DATA_UUID)) { Serial.println(it->toString().c_str()); if (it->canNotify()) { @@ -853,7 +851,7 @@ void SpinBLEClient::handleBattInfo(NimBLEClient *pClient, bool updateNow = false } } // Returns a device name with the las two of the peer address attached. This lets us distinguish between multiple devices with the same device name. -String SpinBLEClient::adevName2UniqueName(NimBLEAdvertisedDevice *inDev) { +String SpinBLEClient::adevName2UniqueName(const NimBLEAdvertisedDevice *inDev) { if (inDev->haveName()) { String _outDevName = String(inDev->getName().c_str()); // add the last two of the string diff --git a/src/BLE_Server.cpp b/src/BLE_Server.cpp index a2610c35..c5b5b002 100644 --- a/src/BLE_Server.cpp +++ b/src/BLE_Server.cpp @@ -62,7 +62,7 @@ void startBLEServer() { pAdvertising->addServiceUUID(WATTBIKE_SERVICE_UUID); pAdvertising->setMaxInterval(250); pAdvertising->setMinInterval(160); - pAdvertising->setScanResponse(true); + pAdvertising->enableScanResponse(true); BLEFirmwareSetup(); BLEDevice::startAdvertising(); diff --git a/src/Main.cpp b/src/Main.cpp index b495a40b..0224fa48 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -60,7 +60,7 @@ void SS2K::stopTasks() { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Shutting Down all BLE services"); spinBLEClient.reconnectTries = 0; spinBLEClient.intentionalDisconnect = NUM_BLE_DEVICES; - if (NimBLEDevice::getInitialized()) { + if (NimBLEDevice::isInitialized()) { NimBLEDevice::deinit(); ss2k->stopTasks(); } From 31901111b28cc72101b858c5747385c5d769ab6d Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Thu, 2 Jan 2025 20:16:13 -0600 Subject: [PATCH 004/451] WIP -Added new Queue -Migrating to New NimBLE --- include/BLE_Common.h | 38 ++++++----- include/BLE_Cycling_Power_Service.h | 2 +- include/BLE_Cycling_Speed_Cadence.h | 2 +- include/BLE_Fitness_Machine_Service.h | 2 +- include/BLE_Heart_Service.h | 2 +- include/settings.h | 12 ++-- platformio.ini | 4 +- src/BLE_Client.cpp | 91 +++++++++++++++------------ src/BLE_Cycling_Power_Service.cpp | 2 +- src/BLE_Cycling_Speed_Cadence.cpp | 2 +- src/BLE_Fitness_Machine_Service.cpp | 2 +- src/BLE_Heart_Service.cpp | 2 +- src/BLE_Server.cpp | 57 +++++++++++++---- src/BLE_Setup.cpp | 4 +- src/HTTP_Server_Basic.cpp | 18 +++--- src/Main.cpp | 2 +- 16 files changed, 149 insertions(+), 93 deletions(-) diff --git a/include/BLE_Common.h b/include/BLE_Common.h index 3c895a2a..2fa559c2 100644 --- a/include/BLE_Common.h +++ b/include/BLE_Common.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include #include #include @@ -38,9 +39,12 @@ void BLECommunications(); // *****************************Server**************************** class MyServerCallbacks : public NimBLEServerCallbacks { public: - void onConnect(BLEServer *, ble_gap_conn_desc *desc); - void onDisconnect(BLEServer *); - bool onConnParamsUpdateRequest(NimBLEClient *pClient, const ble_gap_upd_params *params); + void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo); + void onDisconnect(NimBLEServer* pServer); + void onMTUChange(uint16_t MTU, NimBLEConnInfo& connInfo); + uint32_t onPassKeyDisplay(); + void onAuthenticationComplete(NimBLEConnInfo& connInfo); + bool onConnParamsUpdateRequest(uint16_t handle, const ble_gap_upd_params* params); }; // TODO add the rest of the server to this class @@ -66,10 +70,12 @@ class SpinBLEServer { SpinBLEServer() { memset(&clientSubscribed, 0, sizeof(clientSubscribed)); } }; -class MyCallbacks : public NimBLECharacteristicCallbacks { +class MyCharacteristicCallbacks : public NimBLECharacteristicCallbacks { public: - void onWrite(BLECharacteristic *); - void onSubscribe(NimBLECharacteristic *pCharacteristic, ble_gap_conn_desc *desc, uint16_t subValue); + void onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) override; + void onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) override; + void onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) override; + void onStatus(NimBLECharacteristic* pCharacteristic, int code) override; }; extern SpinBLEServer spinBLEServer; @@ -120,7 +126,7 @@ class SpinBLEAdvertisedDevice { // } // } - NimBLEAdvertisedDevice *advertisedDevice = nullptr; + const NimBLEAdvertisedDevice *advertisedDevice = nullptr; NimBLEAddress peerAddress; int connectedClientID = BLE_HS_CONN_HANDLE_NONE; @@ -134,7 +140,7 @@ class SpinBLEAdvertisedDevice { bool doConnect = false; void setPostConnected(bool pc) { isPostConnected = pc; } bool getPostConnected() { return isPostConnected; } - void set(BLEAdvertisedDevice *device, int id = BLE_HS_CONN_HANDLE_NONE, BLEUUID inServiceUUID = (uint16_t)0x0000, BLEUUID inCharUUID = (uint16_t)0x0000); + void set(const NimBLEAdvertisedDevice *device, int id = BLE_HS_CONN_HANDLE_NONE, BLEUUID inServiceUUID = (uint16_t)0x0000, BLEUUID inCharUUID = (uint16_t)0x0000); void reset(); void print(); bool enqueueData(uint8_t data[25], size_t length, NimBLEUUID charUUID); @@ -188,17 +194,19 @@ class SpinBLEClient { }; class ScanCallbacks : public NimBLEScanCallbacks { - public: - void onResult(NimBLEAdvertisedDevice *); +public: + void onResult(const NimBLEAdvertisedDevice* advertisedDevice) override; + void onScanEnd(const NimBLEScanResults& results, int reason) override; +private: }; class MyClientCallback : public NimBLEClientCallbacks { public: - void onConnect(BLEClient *); - void onDisconnect(BLEClient *); - uint32_t onPassKeyRequest(); - bool onConfirmPIN(uint32_t); - void onAuthenticationComplete(ble_gap_conn_desc); + void onConnect(NimBLEClient* pClient) override; + void onDisconnect(NimBLEClient* pClient, int reason) override; + void onPassKeyEntry(NimBLEConnInfo& connInfo) override; + void onConfirmPasskey(NimBLEConnInfo& connInfo, uint32_t pass_key) override; + void onAuthenticationComplete(NimBLEConnInfo& connInfo) override; }; extern SpinBLEClient spinBLEClient; diff --git a/include/BLE_Cycling_Power_Service.h b/include/BLE_Cycling_Power_Service.h index 234bc86f..0eef8ac3 100644 --- a/include/BLE_Cycling_Power_Service.h +++ b/include/BLE_Cycling_Power_Service.h @@ -13,7 +13,7 @@ class BLE_Cycling_Power_Service { public: BLE_Cycling_Power_Service(); - void setupService(NimBLEServer *pServer, MyCallbacks *chrCallbacks); + void setupService(NimBLEServer *pServer, MyCharacteristicCallbacks *chrCallbacks); void update(); private: diff --git a/include/BLE_Cycling_Speed_Cadence.h b/include/BLE_Cycling_Speed_Cadence.h index 7e48b79e..bee802ab 100644 --- a/include/BLE_Cycling_Speed_Cadence.h +++ b/include/BLE_Cycling_Speed_Cadence.h @@ -13,7 +13,7 @@ class BLE_Cycling_Speed_Cadence { public: BLE_Cycling_Speed_Cadence(); - void setupService(NimBLEServer *pServer, MyCallbacks *chrCallbacks); + void setupService(NimBLEServer *pServer, MyCharacteristicCallbacks *chrCallbacks); void update(); private: diff --git a/include/BLE_Fitness_Machine_Service.h b/include/BLE_Fitness_Machine_Service.h index 2ecdef85..386ff7e9 100644 --- a/include/BLE_Fitness_Machine_Service.h +++ b/include/BLE_Fitness_Machine_Service.h @@ -13,7 +13,7 @@ class BLE_Fitness_Machine_Service { public: BLE_Fitness_Machine_Service(); - void setupService(NimBLEServer *pServer, MyCallbacks *chrCallbacks); + void setupService(NimBLEServer *pServer, MyCharacteristicCallbacks *chrCallbacks); void update(); bool spinDown(uint8_t response); diff --git a/include/BLE_Heart_Service.h b/include/BLE_Heart_Service.h index c3498c4b..49755e7e 100644 --- a/include/BLE_Heart_Service.h +++ b/include/BLE_Heart_Service.h @@ -13,7 +13,7 @@ class BLE_Heart_Service { public: BLE_Heart_Service(); - void setupService(NimBLEServer *pServer, MyCallbacks *chrCallbacks); + void setupService(NimBLEServer *pServer, MyCharacteristicCallbacks *chrCallbacks); void update(); private: diff --git a/include/settings.h b/include/settings.h index 51314d62..e2acf7f5 100644 --- a/include/settings.h +++ b/include/settings.h @@ -224,11 +224,11 @@ const char* const DEFAULT_PASSWORD = "password"; // Name of default Power Meter. any connects to anything, none connects to // nothing. -#define CONNECTED_POWER_METER "any" +#define CONNECTED_POWER_METER "none" // Name of default heart monitor. any connects to anything, none connects to // nothing. -#define CONNECTED_HEART_MONITOR "any" +#define CONNECTED_HEART_MONITOR "none" // Name of default remote. any connects to anything, none connects to // nothing. @@ -305,14 +305,14 @@ const char* const DEFAULT_PASSWORD = "password"; // Interval for polling ble battery updates #define BATTERY_UPDATE_INTERVAL_MILLIS 300000 -// Initial and web scan duration. -#define DEFAULT_SCAN_DURATION 5 +// Initial and web scan duration in milliseconds +#define DEFAULT_SCAN_DURATION 5000 // Default homing sensitivity value #define DEFAULT_HOMING_SENSITIVITY 50 -// BLE automatic reconnect duration. Set this low to avoid interruption. -#define BLE_RECONNECT_SCAN_DURATION 5 +// BLE automatic reconnect duration in milliseconds. Set this low to avoid interruption. +#define BLE_RECONNECT_SCAN_DURATION 5000 // Task Stack Sizes #define MAIN_STACK 6500 diff --git a/platformio.ini b/platformio.ini index 07f1ac90..764fa1f0 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,7 +13,7 @@ default_envs = release [esp32doit] lib_ldf_mode = chain lib_compat_mode = strict -platform = espressif32 @ 6.0.1 +platform = espressif32 @ 6.9.0 board = esp32doit-devkit-v1 framework = arduino board_build.partitions = min_spiffs.csv @@ -26,7 +26,7 @@ build_flags = !python build_date_macro.py -D CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 -D CONFIG_MDNS_STRICT_MODE=1 - -D CORE_DEBUG_LEVEL=1 + -D CORE_DEBUG_LEVEL=5 -D ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=3500 lib_deps = https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.1.2.zip diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index 5fce7786..0a369037 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -37,6 +37,13 @@ void SpinBLEClient::start() { 1, /* priority of the task */ &BLEClientTask, /* Task handle to keep track of created task */ 1); /* pin task to core */ + + NimBLEScan *pBLEScan = NimBLEDevice::getScan(); + pBLEScan->setScanCallbacks(&myScanCallbacks, false); + pBLEScan->setInterval(49); // 97 + pBLEScan->setWindow(33); // 67 + pBLEScan->setDuplicateFilter(true); + pBLEScan->setActiveScan(true); } static void onNotify(BLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t *pData, size_t length, bool isNotify) { @@ -63,6 +70,7 @@ static void onNotify(BLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t // Manages device connections and scanning. void bleClientTask(void *pvParameters) { long int scanDelay = millis(); + spinBLEClient.checkBLEReconnect(); for (;;) { vTaskDelay(BLE_CLIENT_DELAY / portTICK_PERIOD_MS); // Delay between loops. @@ -83,7 +91,7 @@ void bleClientTask(void *pvParameters) { } // Scan for BLE devices that we should connect to this client - if ((millis() - scanDelay) > ((BLE_RECONNECT_SCAN_DURATION * 1000) * 2)) { + if ((millis() - scanDelay) > ((BLE_RECONNECT_SCAN_DURATION) * 2)) { spinBLEClient.checkBLEReconnect(); scanDelay = millis(); #ifdef DEBUG_STACK @@ -92,7 +100,7 @@ void bleClientTask(void *pvParameters) { } if (spinBLEClient.doScan && (!ss2k->isUpdating)) { - spinBLEClient.scanProcess(); + spinBLEClient.scanProcess(DEFAULT_SCAN_DURATION); } // Connect BLE Servers to this client @@ -124,9 +132,9 @@ bool SpinBLEClient::connectToServer() { NimBLEUUID serviceUUID; NimBLEUUID charUUID; - int successful = 0; - BLEAdvertisedDevice *myDevice = nullptr; - int device_number = -1; + int successful = 0; + const NimBLEAdvertisedDevice *myDevice; + int device_number = -1; for (int i = 0; i < NUM_BLE_DEVICES; i++) { if (spinBLEClient.myBLEDevices[i].doConnect == true) { // Client wants to be connected @@ -250,9 +258,9 @@ bool SpinBLEClient::connectToServer() { */ pClient->setConnectionParams(6, 6, 0, 200); /** Set how long we are willing to wait for the connection to complete (seconds), default is 30. */ - pClient->setConnectTimeout(5); // 5 + pClient->setConnectTimeout(5 * 1000); // 5 seconds - if (!pClient->connect(myDevice->getAddress())) { + if (!pClient->connect(myDevice, false)) { SS2K_LOG(BLE_CLIENT_LOG_TAG, " - Failed to connect client"); /** Created a client but failed to connect, don't need to keep it as it has no data */ spinBLEClient.myBLEDevices[device_number].reset(); @@ -346,14 +354,12 @@ bool SpinBLEClient::connectToServer() { /** None of these are required as they will be handled by the library with defaults. ** ** Remove as you see fit for your needs */ -void MyClientCallback::onConnect(NimBLEClient *pClient) { - // additional characteristic subscriptions. -} +void MyClientCallback::onConnect(NimBLEClient *pClient) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Connected"); } -void MyClientCallback::onDisconnect(NimBLEClient *pClient) { +void MyClientCallback::onDisconnect(NimBLEClient *pClient, int reason) { if (!pClient->isConnected()) { NimBLEAddress addr = pClient->getPeerAddress(); - SS2K_LOG(BLE_CLIENT_LOG_TAG, "This disconnected client Address %s", addr.toString().c_str()); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Client %s Disconnected, reason = %d", addr.toString().c_str(), reason); for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { if (addr == spinBLEClient.myBLEDevices[i].peerAddress) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Detected %s Disconnect", spinBLEClient.myBLEDevices[i].serviceUUID.toString().c_str()); @@ -383,25 +389,34 @@ void MyClientCallback::onDisconnect(NimBLEClient *pClient) { } } -/***************** New - Security handled here ******************** -****** Note: these are the same return values as defaults ********/ -uint32_t MyClientCallback::onPassKeyRequest() { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Client PassKeyRequest"); - return 123456; +void MyClientCallback::onPassKeyEntry(NimBLEConnInfo &connInfo) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Client Passkey Entry"); + /** This should prompt the user to enter the passkey displayed on the peer device */ + NimBLEDevice::injectPassKey(connInfo, 123456); } -bool MyClientCallback::onConfirmPIN(uint32_t pass_key) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "The passkey YES/NO number: %ud", pass_key); - return true; + +void MyClientCallback::onConfirmPasskey(NimBLEConnInfo &connInfo, uint32_t pass_key) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "The passkey YES/NO number: %" PRIu32, pass_key); + /** Inject false if passkeys don't match. */ + NimBLEDevice::injectConfirmPasskey(connInfo, true); } -void MyClientCallback::onAuthenticationComplete(ble_gap_conn_desc desc) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Starting BLE work!"); } -/*******************************************************************/ +void MyClientCallback::onAuthenticationComplete(NimBLEConnInfo &connInfo) { + if (!connInfo.isEncrypted()) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Encrypt connection failed - disconnecting"); + /** Find the client with the connection handle provided in connInfo */ + NimBLEDevice::getClientByHandle(connInfo.getConnHandle())->disconnect(); + return; + } + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Starting BLE work!"); +} /** * Scan for BLE servers and find the first one that advertises the service we are looking for. */ -void ScanCallbacks::onResult(BLEAdvertisedDevice *advertisedDevice) { +void ScanCallbacks::onResult(const NimBLEAdvertisedDevice *advertisedDevice) { + Serial.printf("Advertised Device found: %s\n", advertisedDevice->toString().c_str()); // Define granular constants for maximal reuse during logging const char *const MATCHED = "Matched "; const char *const DIDNT_MATCH_THE_SAVED = " didn't match the saved: "; @@ -480,19 +495,17 @@ void SpinBLEClient::scanProcess(int duration) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Scanning for BLE servers and putting them into a list..."); - BLEScan *pBLEScan = BLEDevice::getScan(); - pBLEScan->stop(); - vTaskDelay(50 / portTICK_PERIOD_MS); + NimBLEScan *pBLEScan = NimBLEDevice::getScan(); + if (pBLEScan->isScanning()) { + return; + } pBLEScan->clearResults(); - pBLEScan->setScanCallbacks(&myScanCallbacks); - pBLEScan->setInterval(49); // 97 - pBLEScan->setWindow(33); // 67 - pBLEScan->setDuplicateFilter(true); - pBLEScan->setActiveScan(true); // might cause memory leak if true - undetermined. We don't get device names without it. - pBLEScan->start(duration, false); + pBLEScan->start(duration, false, true); this->dontBlockScan = false; +} - int count = pBLEScan->getResults().getCount(); +void ScanCallbacks::onScanEnd(const NimBLEScanResults &results, int reason) { + int count = results.getCount(); StaticJsonDocument<1000> devices; // Check if 'devices' JSON document already exists and has content; if so, deserialize it. @@ -502,13 +515,13 @@ void SpinBLEClient::scanProcess(int duration) { } for (int i = 0; i < count; i++) { - const NimBLEAdvertisedDevice* d = pBLEScan->getResults().getDevice(i); + const NimBLEAdvertisedDevice *d = results.getDevice(i); // Check for duplicates by name or address before adding bool isDuplicate = false; for (JsonPair kv : devices.as()) { JsonObject obj = kv.value().as(); - if (obj.containsKey("name") && obj["name"] == this->adevName2UniqueName(d)) { + if (obj.containsKey("name") && obj["name"] == spinBLEClient.adevName2UniqueName(d)) { isDuplicate = true; break; } @@ -519,7 +532,7 @@ void SpinBLEClient::scanProcess(int duration) { d->isAdvertisingService(FITNESSMACHINESERVICE_UUID) || d->isAdvertisingService(ECHELON_DEVICE_UUID) || d->isAdvertisingService(HID_SERVICE_UUID))) { String device = "device " + String(devices.size()); // Use the current size to index the new device - devices[device]["name"] = this->adevName2UniqueName(d); + devices[device]["name"] = spinBLEClient.adevName2UniqueName(d); // Workaround for IC4 not advertising FTMS as the first service. // Potentially others may need to be added in the future. @@ -534,7 +547,7 @@ void SpinBLEClient::scanProcess(int duration) { String output; serializeJson(devices, output); - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Bluetooth Client Found Devices: %s", output.c_str()); + // SS2K_LOG(BLE_CLIENT_LOG_TAG, "Bluetooth Client Found Devices: %s", output.c_str()); #ifdef USE_TELEGRAM SEND_TO_TELEGRAM("Bluetooth Client Found Devices: " + output); #endif @@ -863,9 +876,9 @@ String SpinBLEClient::adevName2UniqueName(const NimBLEAdvertisedDevice *inDev) { } } -void SpinBLEAdvertisedDevice::set(BLEAdvertisedDevice *device, int id, BLEUUID inServiceUUID, BLEUUID inCharUUID) { +void SpinBLEAdvertisedDevice::set(const NimBLEAdvertisedDevice *device, int id, BLEUUID inServiceUUID, BLEUUID inCharUUID) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Setting Device %s", device->getAddress().toString().c_str()); - this->advertisedDevice = device; + this->advertisedDevice = const_cast(device); this->peerAddress = device->getAddress(); this->connectedClientID = id; this->serviceUUID = BLEUUID(inServiceUUID); diff --git a/src/BLE_Cycling_Power_Service.cpp b/src/BLE_Cycling_Power_Service.cpp index 63058113..9d58257e 100644 --- a/src/BLE_Cycling_Power_Service.cpp +++ b/src/BLE_Cycling_Power_Service.cpp @@ -9,7 +9,7 @@ #include BLE_Cycling_Power_Service::BLE_Cycling_Power_Service() : pPowerMonitor(nullptr), cyclingPowerFeatureCharacteristic(nullptr), sensorLocationCharacteristic(nullptr){} -void BLE_Cycling_Power_Service::setupService(NimBLEServer *pServer, MyCallbacks *chrCallbacks) { +void BLE_Cycling_Power_Service::setupService(NimBLEServer *pServer, MyCharacteristicCallbacks *chrCallbacks) { // Power Meter service setup pPowerMonitor = spinBLEServer.pServer->createService(CYCLINGPOWERSERVICE_UUID); cyclingPowerMeasurementCharacteristic = pPowerMonitor->createCharacteristic(CYCLINGPOWERMEASUREMENT_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); diff --git a/src/BLE_Cycling_Speed_Cadence.cpp b/src/BLE_Cycling_Speed_Cadence.cpp index da333ede..384ef8d3 100644 --- a/src/BLE_Cycling_Speed_Cadence.cpp +++ b/src/BLE_Cycling_Speed_Cadence.cpp @@ -10,7 +10,7 @@ BLE_Cycling_Speed_Cadence::BLE_Cycling_Speed_Cadence() : pCyclingSpeedCadenceService(nullptr), cscMeasurement(nullptr), cscFeature(nullptr) {} -void BLE_Cycling_Speed_Cadence::setupService(NimBLEServer *pServer, MyCallbacks *chrCallbacks) { +void BLE_Cycling_Speed_Cadence::setupService(NimBLEServer *pServer, MyCharacteristicCallbacks *chrCallbacks) { pCyclingSpeedCadenceService = pServer->createService(CSCSERVICE_UUID); cscMeasurement = pCyclingSpeedCadenceService->createCharacteristic(CSCMEASUREMENT_UUID, NIMBLE_PROPERTY::NOTIFY); cscFeature = pCyclingSpeedCadenceService->createCharacteristic(CSCFEATURE_UUID, NIMBLE_PROPERTY::READ); diff --git a/src/BLE_Fitness_Machine_Service.cpp b/src/BLE_Fitness_Machine_Service.cpp index e3c9bac1..6c1b5434 100644 --- a/src/BLE_Fitness_Machine_Service.cpp +++ b/src/BLE_Fitness_Machine_Service.cpp @@ -21,7 +21,7 @@ BLE_Fitness_Machine_Service::BLE_Fitness_Machine_Service() uint8_t ftmsTrainingStatus[2] = {0x08, 0x00}; -void BLE_Fitness_Machine_Service::setupService(NimBLEServer *pServer, MyCallbacks *chrCallbacks) { +void BLE_Fitness_Machine_Service::setupService(NimBLEServer *pServer, MyCharacteristicCallbacks *chrCallbacks) { // Resistance, IPower, HeartRate uint8_t ftmsResistanceLevelRange[6] = {0x01, 0x00, 0x64, 0x00, 0x01, 0x00}; // 1:100 increment 1 uint8_t ftmsPowerRange[6] = {0x01, 0x00, 0xA0, 0x0F, 0x01, 0x00}; // 1:4000 watts increment 1 diff --git a/src/BLE_Heart_Service.cpp b/src/BLE_Heart_Service.cpp index 9a7b7372..09534574 100644 --- a/src/BLE_Heart_Service.cpp +++ b/src/BLE_Heart_Service.cpp @@ -10,7 +10,7 @@ BLE_Heart_Service::BLE_Heart_Service() : pHeartService(nullptr), heartRateMeasurementCharacteristic(nullptr) {} -void BLE_Heart_Service::setupService(NimBLEServer *pServer, MyCallbacks *chrCallbacks) { +void BLE_Heart_Service::setupService(NimBLEServer *pServer, MyCharacteristicCallbacks *chrCallbacks) { // HEART RATE MONITOR SERVICE SETUP pHeartService = spinBLEServer.pServer->createService(HEARTSERVICE_UUID); heartRateMeasurementCharacteristic = pHeartService->createCharacteristic(HEARTCHARACTERISTIC_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); diff --git a/src/BLE_Server.cpp b/src/BLE_Server.cpp index c5b5b002..8097454a 100644 --- a/src/BLE_Server.cpp +++ b/src/BLE_Server.cpp @@ -25,7 +25,7 @@ // BLE Server Settings SpinBLEServer spinBLEServer; -static MyCallbacks chrCallbacks; +static MyCharacteristicCallbacks chrCallbacks; BLE_Cycling_Speed_Cadence cyclingSpeedCadenceService; BLE_Cycling_Power_Service cyclingPowerService; @@ -53,7 +53,7 @@ void startBLEServer() { BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); // const std::string fitnessData = {0b00000001, 0b00100000, 0b00000000}; // pAdvertising->setServiceData(FITNESSMACHINESERVICE_UUID, fitnessData); - + pAdvertising->setName(userConfig->getDeviceName()); pAdvertising->addServiceUUID(FITNESSMACHINESERVICE_UUID); pAdvertising->addServiceUUID(CYCLINGPOWERSERVICE_UUID); pAdvertising->addServiceUUID(CSCSERVICE_UUID); @@ -127,8 +127,9 @@ void SpinBLEServer::updateWheelAndCrankRev() { } // Creating Server Connection Callbacks -void MyServerCallbacks::onConnect(BLEServer *pServer, ble_gap_conn_desc *desc) { - SS2K_LOG(BLE_SERVER_LOG_TAG, "Bluetooth Remote Client Connected: %s Connected Clients: %d", NimBLEAddress(desc->peer_ota_addr).toString().c_str(), pServer->getConnectedCount()); +void MyServerCallbacks::onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) { + SS2K_LOG(BLE_SERVER_LOG_TAG, "Bluetooth Remote Client Connected: %s Connected Clients: %d", + connInfo.getAddress().toString().c_str(), pServer->getConnectedCount()); if (pServer->getConnectedCount() < CONFIG_BT_NIMBLE_MAX_CONNECTIONS - NUM_BLE_DEVICES) { BLEDevice::startAdvertising(); @@ -138,7 +139,7 @@ void MyServerCallbacks::onConnect(BLEServer *pServer, ble_gap_conn_desc *desc) { } } -void MyServerCallbacks::onDisconnect(BLEServer *pServer) { +void MyServerCallbacks::onDisconnect(NimBLEServer* pServer) { SS2K_LOG(BLE_SERVER_LOG_TAG, "Bluetooth Remote Client Disconnected. Remaining Clients: %d", pServer->getConnectedCount()); BLEDevice::startAdvertising(); // client disconnected while trying to write fw - reboot to clear the faulty upload. @@ -148,27 +149,57 @@ void MyServerCallbacks::onDisconnect(BLEServer *pServer) { } } -bool MyServerCallbacks::onConnParamsUpdateRequest(NimBLEClient *pClient, const ble_gap_upd_params *params) { - SS2K_LOG(BLE_SERVER_LOG_TAG, "Updated Server Connection Parameters for %s", pClient->getPeerAddress().toString().c_str()); +void MyServerCallbacks::onMTUChange(uint16_t MTU, NimBLEConnInfo& connInfo) { + SS2K_LOG(BLE_SERVER_LOG_TAG, "MTU updated: %u for connection ID: %u", MTU, connInfo.getConnHandle()); +} + +uint32_t MyServerCallbacks::onPassKeyDisplay() { + uint32_t passkey = 123456; // Static passkey for demonstration + SS2K_LOG(BLE_SERVER_LOG_TAG, "Server Passkey Display: %u", passkey); + return passkey; +} + +void MyServerCallbacks::onAuthenticationComplete(NimBLEConnInfo& connInfo) { + if (!connInfo.isEncrypted()) { + SS2K_LOG(BLE_SERVER_LOG_TAG, "Encrypt connection failed - disconnecting client"); + NimBLEDevice::getServer()->disconnect(connInfo.getConnHandle()); + return; + } + SS2K_LOG(BLE_SERVER_LOG_TAG, "Secured connection to: %s", connInfo.getAddress().toString().c_str()); +} + +bool MyServerCallbacks::onConnParamsUpdateRequest(uint16_t handle, const ble_gap_upd_params *params) { + SS2K_LOG(BLE_SERVER_LOG_TAG, "Updated Server Connection Parameters for handle: %d", handle); return true; -}; +} // END SERVER CALLBACKS -void MyCallbacks::onWrite(BLECharacteristic *pCharacteristic) { +void MyCharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) { + SS2K_LOG(BLE_SERVER_LOG_TAG, "Read from %s by client: %s", + pCharacteristic->getUUID().toString().c_str(), + connInfo.getAddress().toString().c_str()); +} + +void MyCharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) { if (pCharacteristic->getUUID() == FITNESSMACHINECONTROLPOINT_UUID) { spinBLEServer.writeCache.push(pCharacteristic->getValue()); } else { - SS2K_LOG(BLE_SERVER_LOG_TAG, "Write to %s is not supported", pCharacteristic->getUUID().toString()); + SS2K_LOG(BLE_SERVER_LOG_TAG, "Write to %s is not supported", pCharacteristic->getUUID().toString().c_str()); } } -void MyCallbacks::onSubscribe(NimBLECharacteristic *pCharacteristic, ble_gap_conn_desc *desc, uint16_t subValue) { +void MyCharacteristicCallbacks::onStatus(NimBLECharacteristic* pCharacteristic, int code) { + SS2K_LOG(BLE_SERVER_LOG_TAG, "Notification/Indication status code: %d for characteristic: %s", + code, pCharacteristic->getUUID().toString().c_str()); +} + +void MyCharacteristicCallbacks::onSubscribe(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) { String str = "Client ID: "; NimBLEUUID pUUID = pCharacteristic->getUUID(); - str += desc->conn_handle; + str += connInfo.getConnHandle(); str += " Address: "; - str += std::string(NimBLEAddress(desc->peer_ota_addr)).c_str(); + str += connInfo.getAddress().toString().c_str(); if (subValue == 0) { str += " Unsubscribed to "; spinBLEServer.setClientSubscribed(pUUID, false); diff --git a/src/BLE_Setup.cpp b/src/BLE_Setup.cpp index 7d427c44..7bf90ab9 100644 --- a/src/BLE_Setup.cpp +++ b/src/BLE_Setup.cpp @@ -13,8 +13,8 @@ void setupBLE() { // Common BLE setup for both client and server SS2K_LOG(BLE_SETUP_LOG_TAG, "Starting Arduino BLE Client application..."); - BLEDevice::init(userConfig->getDeviceName()); - BLEDevice::setMTU(515); //-- enabling this is very important for BLE firmware updates. + NimBLEDevice::init(userConfig->getDeviceName()); + NimBLEDevice::setMTU(515); //-- enabling this is very important for BLE firmware updates. spinBLEClient.start(); startBLEServer(); SS2K_LOG(BLE_SETUP_LOG_TAG, "%s %s %s", userConfig->getConnectedPowerMeter(), userConfig->getConnectedHeartMonitor(), userConfig->getConnectedRemote()); diff --git a/src/HTTP_Server_Basic.cpp b/src/HTTP_Server_Basic.cpp index 180d7862..c09a5c15 100644 --- a/src/HTTP_Server_Basic.cpp +++ b/src/HTTP_Server_Basic.cpp @@ -51,11 +51,11 @@ void _staSetup() { } void _APSetup() { - // WiFi.eraseAP(); //Needed if we switch back to espressif32 @6.5.0 + //WiFi.eraseAP(); //Needed if we switch back to espressif32 @6.5.0 WiFi.mode(WIFI_AP); - WiFi.setHostname("reset"); // Fixes a bug when switching Arduino Core Versions - WiFi.softAPsetHostname("reset"); - WiFi.setHostname(userConfig->getDeviceName()); + //WiFi.setHostname("reset"); // Fixes a bug when switching Arduino Core Versions + //WiFi.softAPsetHostname("reset"); + //WiFi.setHostname(userConfig->getDeviceName()); WiFi.softAPsetHostname(userConfig->getDeviceName()); WiFi.enableAP(true); vTaskDelay(500); // Micro controller requires some time to reset the mode @@ -93,12 +93,15 @@ void startWifi() { // Couldn't connect to existing network, Create SoftAP if (WiFi.status() != WL_CONNECTED) { + SS2K_LOG(HTTP_SERVER_LOG_TAG, "Starting AP Mode"); _APSetup(); if (strcmp(userConfig->getSsid(), DEVICE_NAME) == 0) { // If default SSID is still in use, let the user select a new password. // Else fall back to the default password. WiFi.softAP(userConfig->getDeviceName(), userConfig->getPassword()); + SS2K_LOG(HTTP_SERVER_LOG_TAG, "Using Stored Password"); } else { + SS2K_LOG(HTTP_SERVER_LOG_TAG, "Using Default Password"); WiFi.softAP(userConfig->getDeviceName(), DEFAULT_PASSWORD); } vTaskDelay(50); @@ -405,6 +408,7 @@ void HTTP_Server::start() { 1); /* pin task to core 1 */ #endif // USE_TELEGRAM server.begin(); + server.enableDelay(false); SS2K_LOG(HTTP_SERVER_LOG_TAG, "HTTP server started"); } @@ -414,9 +418,9 @@ void HTTP_Server::webClientUpdate() { _webClientTimer = millis(); static unsigned long mDnsTimer = millis(); // NOLINT: There is no overload in String for uint64_t server.handleClient(); - if (WiFi.getMode() != WIFI_MODE_STA) { - dnsServer.processNextRequest(); - } + //if (WiFi.getMode() != WIFI_MODE_STA) { + // dnsServer.processNextRequest(); + //} // Keep MDNS alive if ((millis() - mDnsTimer) > 30000) { MDNS.addServiceTxt("http", "_tcp", "lf", String(mDnsTimer)); diff --git a/src/Main.cpp b/src/Main.cpp index 0224fa48..2baa4bf9 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -165,7 +165,7 @@ void setup() { NULL, /* parameter of the task */ 20, /* priority of the task */ &maintenanceLoopTask, /* Task handle to keep track of created task */ - 1); /* pin task to core */ + 0); /* pin task to core */ } void loop() { // Delete this task so we can make one that's more memory efficient. From e94538a68515267f2be4000c390e1594820115a6 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sat, 4 Jan 2025 17:13:49 -0500 Subject: [PATCH 005/451] Fixed Advertising --- src/BLE_Custom_Characteristic.cpp | 1 + src/BLE_Cycling_Power_Service.cpp | 2 ++ src/BLE_Cycling_Speed_Cadence.cpp | 1 + src/BLE_Fitness_Machine_Service.cpp | 1 + src/BLE_Heart_Service.cpp | 1 + src/BLE_Server.cpp | 14 ++++---------- src/BLE_Wattbike_Service.cpp | 1 + 7 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/BLE_Custom_Characteristic.cpp b/src/BLE_Custom_Characteristic.cpp index 69f2a89f..6681e7fe 100644 --- a/src/BLE_Custom_Characteristic.cpp +++ b/src/BLE_Custom_Characteristic.cpp @@ -95,6 +95,7 @@ void BLE_ss2kCustomCharacteristic::setupService(NimBLEServer *pServer) { smartSpin2kCharacteristic->setValue(ss2kCustomCharacteristicValue, sizeof(ss2kCustomCharacteristicValue)); smartSpin2kCharacteristic->setCallbacks(new ss2kCustomCharacteristicCallbacks()); pSmartSpin2kService->start(); + spinBLEServer.pServer->getAdvertising()->addServiceUUID(pSmartSpin2kService->getUUID()); } void BLE_ss2kCustomCharacteristic::update() {} diff --git a/src/BLE_Cycling_Power_Service.cpp b/src/BLE_Cycling_Power_Service.cpp index 9d58257e..bac42fe2 100644 --- a/src/BLE_Cycling_Power_Service.cpp +++ b/src/BLE_Cycling_Power_Service.cpp @@ -21,6 +21,8 @@ void BLE_Cycling_Power_Service::setupService(NimBLEServer *pServer, MyCharacteri sensorLocationCharacteristic->setValue(cpsLocation, sizeof(cpsLocation)); cyclingPowerMeasurementCharacteristic->setCallbacks(chrCallbacks); pPowerMonitor->start(); + //spinBLEServer.pServer->getAdvertising()->addServiceUUID(pPowerMonitor->getUUID()); + } void BLE_Cycling_Power_Service::update() { diff --git a/src/BLE_Cycling_Speed_Cadence.cpp b/src/BLE_Cycling_Speed_Cadence.cpp index 384ef8d3..37b06951 100644 --- a/src/BLE_Cycling_Speed_Cadence.cpp +++ b/src/BLE_Cycling_Speed_Cadence.cpp @@ -18,6 +18,7 @@ void BLE_Cycling_Speed_Cadence::setupService(NimBLEServer *pServer, MyCharacteri cscFeature->setValue(cscFeatureFlags, sizeof(cscFeatureFlags)); cscMeasurement->setCallbacks(chrCallbacks); pCyclingSpeedCadenceService->start(); + //spinBLEServer.pServer->getAdvertising()->addServiceUUID(pCyclingSpeedCadenceService->getUUID()); } void BLE_Cycling_Speed_Cadence::update() { diff --git a/src/BLE_Fitness_Machine_Service.cpp b/src/BLE_Fitness_Machine_Service.cpp index 6c1b5434..0e7e3d02 100644 --- a/src/BLE_Fitness_Machine_Service.cpp +++ b/src/BLE_Fitness_Machine_Service.cpp @@ -60,6 +60,7 @@ void BLE_Fitness_Machine_Service::setupService(NimBLEServer *pServer, MyCharacte fitnessMachineIndoorBikeData->setCallbacks(chrCallbacks); fitnessMachineControlPoint->setCallbacks(chrCallbacks); pFitnessMachineService->start(); + spinBLEServer.pServer->getAdvertising()->addServiceUUID(pFitnessMachineService->getUUID()); } void BLE_Fitness_Machine_Service::update() { diff --git a/src/BLE_Heart_Service.cpp b/src/BLE_Heart_Service.cpp index 09534574..87f64b7e 100644 --- a/src/BLE_Heart_Service.cpp +++ b/src/BLE_Heart_Service.cpp @@ -18,6 +18,7 @@ void BLE_Heart_Service::setupService(NimBLEServer *pServer, MyCharacteristicCall heartRateMeasurementCharacteristic->setValue(heartRateMeasurement, 2); heartRateMeasurementCharacteristic->setCallbacks(chrCallbacks); pHeartService->start(); + spinBLEServer.pServer->getAdvertising()->addServiceUUID(pHeartService->getUUID()); } void BLE_Heart_Service::update() { diff --git a/src/BLE_Server.cpp b/src/BLE_Server.cpp index 8097454a..60bd3313 100644 --- a/src/BLE_Server.cpp +++ b/src/BLE_Server.cpp @@ -50,24 +50,18 @@ void startBLEServer() { deviceInformationService.setupService(spinBLEServer.pServer); wattbikeService.setupService(spinBLEServer.pServer); // No callback needed - BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); + BLEAdvertising* pAdvertising = BLEDevice::getAdvertising(); // const std::string fitnessData = {0b00000001, 0b00100000, 0b00000000}; // pAdvertising->setServiceData(FITNESSMACHINESERVICE_UUID, fitnessData); - pAdvertising->setName(userConfig->getDeviceName()); - pAdvertising->addServiceUUID(FITNESSMACHINESERVICE_UUID); - pAdvertising->addServiceUUID(CYCLINGPOWERSERVICE_UUID); - pAdvertising->addServiceUUID(CSCSERVICE_UUID); - pAdvertising->addServiceUUID(HEARTSERVICE_UUID); - pAdvertising->addServiceUUID(SMARTSPIN2K_SERVICE_UUID); - pAdvertising->addServiceUUID(WATTBIKE_SERVICE_UUID); + pAdvertising->setName(static_cast(userConfig->getDeviceName())); pAdvertising->setMaxInterval(250); pAdvertising->setMinInterval(160); pAdvertising->enableScanResponse(true); BLEFirmwareSetup(); - BLEDevice::startAdvertising(); + pAdvertising->start(); - SS2K_LOG(BLE_SERVER_LOG_TAG, "Bluetooth Characteristic defined!"); + SS2K_LOG(BLE_SERVER_LOG_TAG, "Bluetooth Characteristics defined!"); } void SpinBLEServer::update() { diff --git a/src/BLE_Wattbike_Service.cpp b/src/BLE_Wattbike_Service.cpp index b4b479dc..56c39ac0 100644 --- a/src/BLE_Wattbike_Service.cpp +++ b/src/BLE_Wattbike_Service.cpp @@ -23,6 +23,7 @@ void BLE_Wattbike_Service::setupService(NimBLEServer *pServer) { // Start the service pWattbikeService->start(); + spinBLEServer.pServer->getAdvertising()->addServiceUUID(pWattbikeService->getUUID()); } void BLE_Wattbike_Service::parseNemit() { From ece6d5efc5bdb94ad428b8e7228ef4b56e17489c Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sat, 4 Jan 2025 22:23:12 -0500 Subject: [PATCH 006/451] NimBLE migration 90% complete --- include/BLE_Custom_Characteristic.h | 10 +++++----- platformio.ini | 6 +++--- src/BLE_Custom_Characteristic.cpp | 10 +++++++--- src/BLE_Server.cpp | 12 ++++++------ 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/include/BLE_Custom_Characteristic.h b/include/BLE_Custom_Characteristic.h index 21a5eb3a..2ccc3326 100644 --- a/include/BLE_Custom_Characteristic.h +++ b/include/BLE_Custom_Characteristic.h @@ -74,12 +74,12 @@ class BLE_ss2kCustomCharacteristic { static void parseNemit(); private: - BLEService *pSmartSpin2kService; - BLECharacteristic *smartSpin2kCharacteristic; + NimBLEService *pSmartSpin2kService; + NimBLECharacteristic *smartSpin2kCharacteristic; uint8_t ss2kCustomCharacteristicValue[3] = {0x00, 0x00, 0x00}; }; -class ss2kCustomCharacteristicCallbacks : public BLECharacteristicCallbacks { - void onWrite(BLECharacteristic *); - void onSubscribe(NimBLECharacteristic *pCharacteristic, ble_gap_conn_desc *desc, uint16_t subValue); +class ss2kCustomCharacteristicCallbacks : public NimBLECharacteristicCallbacks { + void onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) override; + void onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) override; }; diff --git a/platformio.ini b/platformio.ini index 764fa1f0..9a876eef 100644 --- a/platformio.ini +++ b/platformio.ini @@ -26,10 +26,10 @@ build_flags = !python build_date_macro.py -D CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 -D CONFIG_MDNS_STRICT_MODE=1 - -D CORE_DEBUG_LEVEL=5 + -D CORE_DEBUG_LEVEL=1 -D ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=3500 lib_deps = - https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.1.2.zip + https://github.com/h2zero/NimBLE-Arduino#bugfix/adv-data-sequencing https://github.com/teemuatlut/TMCStepper/archive/refs/tags/v0.7.3.zip https://github.com/bblanchon/ArduinoJson/archive/refs/tags/v6.20.0.zip https://github.com/gin66/FastAccelStepper/archive/refs/tags/0.31.2.zip @@ -71,4 +71,4 @@ check_flags = --suppress=unmatchedSuppression --suppress=missingIncludeSystem check_severity = medium, high -check_skip_packages = true \ No newline at end of file +check_skip_packages = true diff --git a/src/BLE_Custom_Characteristic.cpp b/src/BLE_Custom_Characteristic.cpp index 6681e7fe..ac8a90d4 100644 --- a/src/BLE_Custom_Characteristic.cpp +++ b/src/BLE_Custom_Characteristic.cpp @@ -100,12 +100,16 @@ void BLE_ss2kCustomCharacteristic::setupService(NimBLEServer *pServer) { void BLE_ss2kCustomCharacteristic::update() {} -void ss2kCustomCharacteristicCallbacks::onWrite(BLECharacteristic *pCharacteristic) { +void ss2kCustomCharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) { std::string rxValue = pCharacteristic->getValue(); + SS2K_LOG(CUSTOM_CHAR_LOG_TAG, "Write from %s", connInfo.getAddress().toString().c_str()); BLE_ss2kCustomCharacteristic::process(rxValue); } -void ss2kCustomCharacteristicCallbacks::onSubscribe(NimBLECharacteristic *pCharacteristic, ble_gap_conn_desc *desc, uint16_t subValue) { NimBLEDevice::setMTU(515); } +void ss2kCustomCharacteristicCallbacks::onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) { + SS2K_LOG(CUSTOM_CHAR_LOG_TAG, "Subscribe from %s", connInfo.getAddress().toString().c_str()); + NimBLEDevice::setMTU(515); +} void BLE_ss2kCustomCharacteristic::notify(char _item, int tableRow) { // regular non power table update @@ -926,4 +930,4 @@ void BLE_ss2kCustomCharacteristic::parseNemit() { BLE_ss2kCustomCharacteristic::notify(BLE_homingSensitivity); return; } -} \ No newline at end of file +} diff --git a/src/BLE_Server.cpp b/src/BLE_Server.cpp index 60bd3313..64912eb7 100644 --- a/src/BLE_Server.cpp +++ b/src/BLE_Server.cpp @@ -42,6 +42,8 @@ void startBLEServer() { spinBLEServer.pServer->setCallbacks(new MyServerCallbacks()); // start services + BLEAdvertising* pAdvertising = BLEDevice::getAdvertising(); + pAdvertising->enableScanResponse(true); cyclingSpeedCadenceService.setupService(spinBLEServer.pServer, &chrCallbacks); cyclingPowerService.setupService(spinBLEServer.pServer, &chrCallbacks); heartService.setupService(spinBLEServer.pServer, &chrCallbacks); @@ -49,16 +51,14 @@ void startBLEServer() { ss2kCustomCharacteristic.setupService(spinBLEServer.pServer); deviceInformationService.setupService(spinBLEServer.pServer); wattbikeService.setupService(spinBLEServer.pServer); // No callback needed - - BLEAdvertising* pAdvertising = BLEDevice::getAdvertising(); + BLEFirmwareSetup(); + // const std::string fitnessData = {0b00000001, 0b00100000, 0b00000000}; // pAdvertising->setServiceData(FITNESSMACHINESERVICE_UUID, fitnessData); pAdvertising->setName(static_cast(userConfig->getDeviceName())); pAdvertising->setMaxInterval(250); pAdvertising->setMinInterval(160); - pAdvertising->enableScanResponse(true); - BLEFirmwareSetup(); pAdvertising->start(); SS2K_LOG(BLE_SERVER_LOG_TAG, "Bluetooth Characteristics defined!"); @@ -184,8 +184,8 @@ void MyCharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, N } void MyCharacteristicCallbacks::onStatus(NimBLECharacteristic* pCharacteristic, int code) { - SS2K_LOG(BLE_SERVER_LOG_TAG, "Notification/Indication status code: %d for characteristic: %s", - code, pCharacteristic->getUUID().toString().c_str()); + //SS2K_LOG(BLE_SERVER_LOG_TAG, "Notification/Indication status code: %d for characteristic: %s", + // code, pCharacteristic->getUUID().toString().c_str()); } void MyCharacteristicCallbacks::onSubscribe(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) { From c1544a9997b7b3e381f7a96465a6f74f0c5cf02b Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sun, 5 Jan 2025 20:27:12 -0600 Subject: [PATCH 007/451] updated advertising --- src/BLE_Firmware_Update.cpp | 2 +- src/BLE_Heart_Service.cpp | 2 +- src/Main.cpp | 6 ++---- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/BLE_Firmware_Update.cpp b/src/BLE_Firmware_Update.cpp index c33db42a..640c932c 100644 --- a/src/BLE_Firmware_Update.cpp +++ b/src/BLE_Firmware_Update.cpp @@ -181,7 +181,7 @@ void BLEFirmwareSetup() { pService->start(); // 6. Start advertising - spinBLEServer.pServer->getAdvertising()->addServiceUUID(pService->getUUID()); + // spinBLEServer.pServer->getAdvertising()->addServiceUUID(pService->getUUID()); downloadFlag = false; } diff --git a/src/BLE_Heart_Service.cpp b/src/BLE_Heart_Service.cpp index 87f64b7e..0cf1afbc 100644 --- a/src/BLE_Heart_Service.cpp +++ b/src/BLE_Heart_Service.cpp @@ -18,7 +18,7 @@ void BLE_Heart_Service::setupService(NimBLEServer *pServer, MyCharacteristicCall heartRateMeasurementCharacteristic->setValue(heartRateMeasurement, 2); heartRateMeasurementCharacteristic->setCallbacks(chrCallbacks); pHeartService->start(); - spinBLEServer.pServer->getAdvertising()->addServiceUUID(pHeartService->getUUID()); + //spinBLEServer.pServer->getAdvertising()->addServiceUUID(pHeartService->getUUID()); } void BLE_Heart_Service::update() { diff --git a/src/Main.cpp b/src/Main.cpp index 2baa4bf9..0eefdce5 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -263,10 +263,8 @@ void SS2K::maintenanceLoop(void *pvParameters) { userPWC->saveToLittleFS(); } - // Things to do every two seconds - if ((millis() - intervalTimer) > 2003) { // add check here for when to restart WiFi - // maybe if in STA mode and 8.8.8.8 no ping return? - // ss2k->restartWifi(); + // Things to do every one seconds + if ((millis() - intervalTimer) > 1003) { logHandler.writeLogs(); webSocketAppender.Loop(); intervalTimer = millis(); From ccb35dfe5b3f5f63c1a9d158f945116628652f67 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sun, 5 Jan 2025 21:05:03 -0600 Subject: [PATCH 008/451] Added Supported Services vector --- include/BLE_Common.h | 18 ++++++ src/BLE_Client.cpp | 128 ++++++++++++++++++++++++------------------- 2 files changed, 90 insertions(+), 56 deletions(-) diff --git a/include/BLE_Common.h b/include/BLE_Common.h index 2fa559c2..27dcfeaa 100644 --- a/include/BLE_Common.h +++ b/include/BLE_Common.h @@ -13,9 +13,27 @@ #include #include #include +#include #include "Main.h" #include "BLE_Definitions.h" #include "BLE_Wattbike_Service.h" +#include "Constants.h" + +// Vector of supported BLE services and their corresponding characteristic UUIDs +struct BLEServiceInfo { + BLEUUID serviceUUID; + BLEUUID characteristicUUID; + String name; +}; + +inline const std::vector SUPPORTED_SERVICES = { + {CYCLINGPOWERSERVICE_UUID, CYCLINGPOWERMEASUREMENT_UUID, "Cycling Power Service"}, + {HEARTSERVICE_UUID, HEARTCHARACTERISTIC_UUID, "Heart Rate Service"}, + {FITNESSMACHINESERVICE_UUID, FITNESSMACHINEINDOORBIKEDATA_UUID, "Fitness Machine Service"}, + {HID_SERVICE_UUID, HID_REPORT_DATA_UUID, "HID Service"}, + {ECHELON_SERVICE_UUID, ECHELON_DATA_UUID, "Echelon Service"}, + {FLYWHEEL_UART_SERVICE_UUID, FLYWHEEL_UART_TX_UUID, "Flywheel UART Service"} +}; #define BLE_CLIENT_LOG_TAG "BLE_Client" #define BLE_COMMON_LOG_TAG "BLE_Common" diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index 0a369037..f88ed247 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -48,7 +48,7 @@ void SpinBLEClient::start() { static void onNotify(BLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t *pData, size_t length, bool isNotify) { // Parse BLE shifter info. - if (pBLERemoteCharacteristic->getRemoteService()->getUUID() == HID_SERVICE_UUID) { + if (pBLERemoteCharacteristic->getRemoteService()->getUUID().equals(HID_SERVICE_UUID)) { Serial.print(pData[0], HEX); if (pData[0] == 0x04) { rtConfig->setShifterPosition(rtConfig->getShifterPosition() + 1); @@ -139,17 +139,8 @@ bool SpinBLEClient::connectToServer() { for (int i = 0; i < NUM_BLE_DEVICES; i++) { if (spinBLEClient.myBLEDevices[i].doConnect == true) { // Client wants to be connected if (spinBLEClient.myBLEDevices[i].advertisedDevice) { // Client is assigned - // If this device is advertising HR service AND not advertising FTMS service AND there is no connected PM AND the next slot is set to connect, connect that one first - // and connect the HRM last. if (spinBLEClient.myBLEDevices[i].advertisedDevice->isAdvertisingService(HEARTSERVICE_UUID) && - // (!spinBLEClient.myBLEDevices[i].advertisedDevice->isAdvertisingService(FITNESSMACHINESERVICE_UUID)) && (!connectedPM) && - // (spinBLEClient.myBLEDevices[i + 1].doConnect == true)) { - // myDevice = spinBLEClient.myBLEDevices[i + 1].advertisedDevice; - // device_number = i + 1; - // SS2K_LOG(BLE_CLIENT_LOG_TAG, "Connecting HRM last."); - // } else { myDevice = spinBLEClient.myBLEDevices[i].advertisedDevice; device_number = i; - // } break; } else { SS2K_LOG(BLE_CLIENT_LOG_TAG, "doConnect and client out of alignment. Resetting device slot."); @@ -164,34 +155,31 @@ bool SpinBLEClient::connectToServer() { SS2K_LOG(BLE_CLIENT_LOG_TAG, "No Device Found to Connect"); return false; } - // FUTURE - Iterate through an array of UUID's we support instead of all the if checks. if (myDevice->getServiceUUIDCount() > 0) { - if (myDevice->isAdvertisingService(FLYWHEEL_UART_SERVICE_UUID) && (myDevice->getName() == FLYWHEEL_BLE_NAME)) { - serviceUUID = FLYWHEEL_UART_SERVICE_UUID; - charUUID = FLYWHEEL_UART_TX_UUID; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "trying to connect to Flywheel Bike"); - } else if (myDevice->isAdvertisingService(FITNESSMACHINESERVICE_UUID)) { - serviceUUID = FITNESSMACHINESERVICE_UUID; - charUUID = FITNESSMACHINEINDOORBIKEDATA_UUID; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "trying to connect to Fitness Machine Service"); - } else if (myDevice->isAdvertisingService(CYCLINGPOWERSERVICE_UUID)) { - serviceUUID = CYCLINGPOWERSERVICE_UUID; - charUUID = CYCLINGPOWERMEASUREMENT_UUID; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "trying to connect to Cycling Power Service"); - } else if (myDevice->isAdvertisingService(ECHELON_DEVICE_UUID)) { - serviceUUID = ECHELON_SERVICE_UUID; - charUUID = ECHELON_DATA_UUID; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Trying to connect to Echelon Bike"); - } else if (myDevice->isAdvertisingService(HEARTSERVICE_UUID)) { - serviceUUID = HEARTSERVICE_UUID; - charUUID = HEARTCHARACTERISTIC_UUID; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Trying to connect to HRM"); - } else if (myDevice->isAdvertisingService(HID_SERVICE_UUID)) { - serviceUUID = HID_SERVICE_UUID; - charUUID = HID_REPORT_DATA_UUID; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Trying to connect to BLE HID remote"); - } else { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "No advertised UUID found"); + bool found = false; + for (const auto& service : SUPPORTED_SERVICES) { + // Special case for Flywheel which requires name check + if (service.serviceUUID.equals(FLYWHEEL_UART_SERVICE_UUID)) { + if (myDevice->isAdvertisingService(service.serviceUUID) && myDevice->getName() == FLYWHEEL_BLE_NAME) { + serviceUUID = service.serviceUUID; + charUUID = service.characteristicUUID; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "trying to connect to %s", service.name.c_str()); + found = true; + break; + } + } + // For all other services + else if (myDevice->isAdvertisingService(service.serviceUUID)) { + serviceUUID = service.serviceUUID; + charUUID = service.characteristicUUID; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "trying to connect to %s", service.name.c_str()); + found = true; + break; + } + } + + if (!found) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "No supported service UUID found"); spinBLEClient.myBLEDevices[device_number].reset(); return false; } @@ -280,7 +268,7 @@ bool SpinBLEClient::connectToServer() { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Connected to: %s - %s RSSI %d", this->adevName2UniqueName(myDevice).c_str(), pClient->getPeerAddress().toString().c_str(), pClient->getRssi()); - if (serviceUUID == HID_SERVICE_UUID) { + if (serviceUUID.equals(HID_SERVICE_UUID)) { connectBLE_HID(pClient); this->reconnectTries = MAX_RECONNECT_TRIES; SS2K_LOG(BLE_CLIENT_LOG_TAG, "Successful remote subscription."); @@ -430,14 +418,28 @@ void ScanCallbacks::onResult(const NimBLEAdvertisedDevice *advertisedDevice) { String aDevName = spinBLEClient.adevName2UniqueName(advertisedDevice); const char *aDevAddr = advertisedDevice->getAddress().toString().c_str(); - if ((advertisedDevice->haveServiceUUID()) && (advertisedDevice->isAdvertisingService(CYCLINGPOWERSERVICE_UUID) || - (advertisedDevice->isAdvertisingService(FLYWHEEL_UART_SERVICE_UUID) && aDevName == String(FLYWHEEL_BLE_NAME)) || - advertisedDevice->isAdvertisingService(FITNESSMACHINESERVICE_UUID) || advertisedDevice->isAdvertisingService(HEARTSERVICE_UUID) || - advertisedDevice->isAdvertisingService(ECHELON_DEVICE_UUID) || advertisedDevice->isAdvertisingService(HID_SERVICE_UUID))) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Trying to match found device name: %s", aDevName.c_str()); + if (advertisedDevice->haveServiceUUID()) { + bool isSupported = false; + for (const auto& service : SUPPORTED_SERVICES) { + // Special case for Flywheel which requires name check + if (service.serviceUUID.equals(FLYWHEEL_UART_SERVICE_UUID)) { + if (advertisedDevice->isAdvertisingService(service.serviceUUID.toString()) && aDevName == String(FLYWHEEL_BLE_NAME)) { + isSupported = true; + break; + } + } + // For all other services + else if (advertisedDevice->isAdvertisingService(service.serviceUUID.toString())) { + isSupported = true; + break; + } + } + + if (isSupported) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Trying to match found device name: %s", aDevName.c_str()); // Handling for BLE connected remotes - if (advertisedDevice->getServiceUUID() == HID_SERVICE_UUID) { + if (advertisedDevice->getServiceUUID().equals(HID_SERVICE_UUID)) { if (strcmp(userConfig->getConnectedRemote(), "any") == 0) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s", REMOTE, STRING_MATCHED_ANY); } else { @@ -450,7 +452,7 @@ void ScanCallbacks::onResult(const NimBLEAdvertisedDevice *advertisedDevice) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s %s%s", REMOTE, NAME, MATCHED, aDevName); } } - } else if (advertisedDevice->getServiceUUID() == HEARTSERVICE_UUID) { + } else if (advertisedDevice->getServiceUUID().equals(HEARTSERVICE_UUID)) { if (strcmp(userConfig->getConnectedHeartMonitor(), "any") == 0) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s", HRM, STRING_MATCHED_ANY); } else { @@ -487,6 +489,7 @@ void ScanCallbacks::onResult(const NimBLEAdvertisedDevice *advertisedDevice) { } SS2K_LOG(BLE_CLIENT_LOG_TAG, "Checking Slot %d", i); } + } } } @@ -527,9 +530,22 @@ void ScanCallbacks::onScanEnd(const NimBLEScanResults &results, int reason) { } } - // is this device advertising something we're interested in? - if (!isDuplicate && (d->isAdvertisingService(CYCLINGPOWERSERVICE_UUID) || d->isAdvertisingService(HEARTSERVICE_UUID) || d->isAdvertisingService(FLYWHEEL_UART_SERVICE_UUID) || - d->isAdvertisingService(FITNESSMACHINESERVICE_UUID) || d->isAdvertisingService(ECHELON_DEVICE_UUID) || d->isAdvertisingService(HID_SERVICE_UUID))) { + // Check if device advertises any of our supported services + bool isSupported = false; + for (const auto& service : SUPPORTED_SERVICES) { + if (service.serviceUUID.equals(FLYWHEEL_UART_SERVICE_UUID)) { + if (d->isAdvertisingService(service.serviceUUID) && spinBLEClient.adevName2UniqueName(d) == String(FLYWHEEL_BLE_NAME)) { + isSupported = true; + break; + } + } + else if (d->isAdvertisingService(service.serviceUUID.toString())) { + isSupported = true; + break; + } + } + + if (!isDuplicate && isSupported) { String device = "device " + String(devices.size()); // Use the current size to index the new device devices[device]["name"] = spinBLEClient.adevName2UniqueName(d); @@ -569,7 +585,7 @@ void SpinBLEClient::removeDuplicates(NimBLEClient *pClient) { for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { // Disconnect oldest PM to avoid two connected. oldBLEd = this->myBLEDevices[i]; if (oldBLEd.advertisedDevice) { - if ((tBLEd.serviceUUID == oldBLEd.serviceUUID) && (tBLEd.peerAddress != oldBLEd.peerAddress)) { + if ((tBLEd.serviceUUID.equals(oldBLEd.serviceUUID)) && (tBLEd.peerAddress != oldBLEd.peerAddress)) { if (BLEDevice::getClientByPeerAddress(oldBLEd.peerAddress)) { if (BLEDevice::getClientByPeerAddress(oldBLEd.peerAddress)->isConnected()) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s Matched another service. Disconnecting: %s", tBLEd.peerAddress.toString().c_str(), oldBLEd.peerAddress.toString().c_str()); @@ -602,7 +618,7 @@ void SpinBLEClient::FTMSControlPointWrite(const uint8_t *pData, int length) { modData[i] = pData[i]; } for (int i = 0; i < NUM_BLE_DEVICES; i++) { - if (myBLEDevices[i].getPostConnected() && (myBLEDevices[i].serviceUUID == FITNESSMACHINESERVICE_UUID)) { + if (myBLEDevices[i].getPostConnected() && (myBLEDevices[i].serviceUUID.equals(FITNESSMACHINESERVICE_UUID))) { if (NimBLEDevice::getClientByPeerAddress(myBLEDevices[i].peerAddress)->getService(FITNESSMACHINESERVICE_UUID)) { pClient = NimBLEDevice::getClientByPeerAddress(myBLEDevices[i].peerAddress); break; @@ -770,7 +786,7 @@ void SpinBLEClient::connectBLE_HID(NimBLEClient *pClient) { // in subscribing to only one. std::vector charVector = pSvc->getCharacteristics(true); for (auto &it : charVector) { - if (it->getUUID() == NimBLEUUID(HID_REPORT_DATA_UUID)) { + if (it->getUUID().equals(NimBLEUUID(HID_REPORT_DATA_UUID))) { Serial.println(it->toString().c_str()); if (it->canNotify()) { if (!it->subscribe(true, onNotify)) { @@ -884,20 +900,20 @@ void SpinBLEAdvertisedDevice::set(const NimBLEAdvertisedDevice *device, int id, this->serviceUUID = BLEUUID(inServiceUUID); this->charUUID = BLEUUID(inCharUUID); this->dataBufferQueue = xQueueCreate(4, sizeof(NotifyData)); - if (inServiceUUID == HEARTSERVICE_UUID) { + if (inServiceUUID.equals(HEARTSERVICE_UUID)) { this->isHRM = true; spinBLEClient.connectedHRM = true; SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered HRM on Connect"); - } else if (inServiceUUID == CSCSERVICE_UUID) { + } else if (inServiceUUID.equals(CSCSERVICE_UUID)) { this->isCSC = true; spinBLEClient.connectedCD = true; SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered CSC on Connect"); - } else if (inServiceUUID == CYCLINGPOWERSERVICE_UUID || inServiceUUID == FITNESSMACHINESERVICE_UUID || inServiceUUID == FLYWHEEL_UART_SERVICE_UUID || - inServiceUUID == ECHELON_SERVICE_UUID || inServiceUUID == PELOTON_DATA_UUID) { + } else if (inServiceUUID.equals(CYCLINGPOWERSERVICE_UUID) || inServiceUUID.equals(FITNESSMACHINESERVICE_UUID) || inServiceUUID.equals(FLYWHEEL_UART_SERVICE_UUID) || + inServiceUUID.equals(ECHELON_SERVICE_UUID) || inServiceUUID.equals(PELOTON_DATA_UUID)) { this->isPM = true; spinBLEClient.connectedPM = true; SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered PM on Connect"); - } else if (inServiceUUID == HID_SERVICE_UUID) { + } else if (inServiceUUID.equals(HID_SERVICE_UUID)) { this->isRemote = true; spinBLEClient.connectedRemote = true; SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered Remote on Connect"); From 841ec90628097a776caab982c1d9e148dd6bf606 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Mon, 6 Jan 2025 11:05:51 -0600 Subject: [PATCH 009/451] WIP --- include/BLE_Common.h | 27 +++++--- platformio.ini | 5 +- src/BLE_Client.cpp | 160 ++++++++++++++++++------------------------- src/BLE_Common.cpp | 36 ++++++++-- 4 files changed, 120 insertions(+), 108 deletions(-) diff --git a/include/BLE_Common.h b/include/BLE_Common.h index 27dcfeaa..c0fbb3d5 100644 --- a/include/BLE_Common.h +++ b/include/BLE_Common.h @@ -26,14 +26,19 @@ struct BLEServiceInfo { String name; }; -inline const std::vector SUPPORTED_SERVICES = { - {CYCLINGPOWERSERVICE_UUID, CYCLINGPOWERMEASUREMENT_UUID, "Cycling Power Service"}, - {HEARTSERVICE_UUID, HEARTCHARACTERISTIC_UUID, "Heart Rate Service"}, - {FITNESSMACHINESERVICE_UUID, FITNESSMACHINEINDOORBIKEDATA_UUID, "Fitness Machine Service"}, - {HID_SERVICE_UUID, HID_REPORT_DATA_UUID, "HID Service"}, - {ECHELON_SERVICE_UUID, ECHELON_DATA_UUID, "Echelon Service"}, - {FLYWHEEL_UART_SERVICE_UUID, FLYWHEEL_UART_TX_UUID, "Flywheel UART Service"} -}; +namespace BLEServices { + const std::vector SUPPORTED_SERVICES = { + {CYCLINGPOWERSERVICE_UUID, CYCLINGPOWERMEASUREMENT_UUID, "Cycling Power Service"}, + {CSCSERVICE_UUID, CSCMEASUREMENT_UUID, "Cycling Speed And Cadence Service"}, + {HEARTSERVICE_UUID, HEARTCHARACTERISTIC_UUID, "Heart Rate Service"}, + {FITNESSMACHINESERVICE_UUID, FITNESSMACHINEINDOORBIKEDATA_UUID, "Fitness Machine Service"}, + {HID_SERVICE_UUID, HID_REPORT_DATA_UUID, "HID Service"}, + {ECHELON_SERVICE_UUID, ECHELON_DATA_UUID, "Echelon Service"}, + {FLYWHEEL_UART_SERVICE_UUID, FLYWHEEL_UART_TX_UUID, "Flywheel UART Service"} + }; +} + +using BLEServices::SUPPORTED_SERVICES; #define BLE_CLIENT_LOG_TAG "BLE_Client" #define BLE_COMMON_LOG_TAG "BLE_Common" @@ -54,6 +59,12 @@ void setupBLE(); extern TaskHandle_t BLEClientTask; // ***********************Common********************************** void BLECommunications(); + +// Check if a BLE device supports any of our supported services +bool isDeviceSupported(const NimBLEAdvertisedDevice* advertisedDevice, const String& deviceName = ""); + +// Get service info for a supported device +const BLEServiceInfo* getDeviceServiceInfo(const NimBLEAdvertisedDevice* advertisedDevice, const String& deviceName = ""); // *****************************Server**************************** class MyServerCallbacks : public NimBLEServerCallbacks { public: diff --git a/platformio.ini b/platformio.ini index 9a876eef..4ebdea8b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -26,10 +26,11 @@ build_flags = !python build_date_macro.py -D CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 -D CONFIG_MDNS_STRICT_MODE=1 - -D CORE_DEBUG_LEVEL=1 + -D CORE_DEBUG_LEVEL=5 -D ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=3500 + -std=gnu++17 lib_deps = - https://github.com/h2zero/NimBLE-Arduino#bugfix/adv-data-sequencing + https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.1.3.zip https://github.com/teemuatlut/TMCStepper/archive/refs/tags/v0.7.3.zip https://github.com/bblanchon/ArduinoJson/archive/refs/tags/v6.20.0.zip https://github.com/gin66/FastAccelStepper/archive/refs/tags/0.31.2.zip diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index f88ed247..eac8a9bf 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -46,9 +46,9 @@ void SpinBLEClient::start() { pBLEScan->setActiveScan(true); } -static void onNotify(BLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t *pData, size_t length, bool isNotify) { +static void notifyCB(NimBLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t *pData, size_t length, bool isNotify) { // Parse BLE shifter info. - if (pBLERemoteCharacteristic->getRemoteService()->getUUID().equals(HID_SERVICE_UUID)) { + if (pBLERemoteCharacteristic->getRemoteService()->getUUID() == HID_SERVICE_UUID) { Serial.print(pData[0], HEX); if (pData[0] == 0x04) { rtConfig->setShifterPosition(rtConfig->getShifterPosition() + 1); @@ -57,7 +57,8 @@ static void onNotify(BLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t rtConfig->setShifterPosition(rtConfig->getShifterPosition() - 1); } } - + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Notification received from %s - Service UUID: %s", pBLERemoteCharacteristic->getRemoteService()->getClient()->getPeerAddress().toString().c_str(), + pBLERemoteCharacteristic->getRemoteService()->getUUID().toString().c_str()); // enqueue sensor data for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { if (pBLERemoteCharacteristic->getClient()->getPeerAddress() == spinBLEClient.myBLEDevices[i].peerAddress) { @@ -66,6 +67,16 @@ static void onNotify(BLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t } } +void testnotifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify) { + std::string str = (isNotify == true) ? "Notification" : "Indication"; + str += " from "; + str += pRemoteCharacteristic->getClient()->getPeerAddress().toString(); + str += ": Service = " + pRemoteCharacteristic->getRemoteService()->getUUID().toString(); + str += ", Characteristic = " + pRemoteCharacteristic->getUUID().toString(); + str += ", Value = " + std::string((char*)pData, length); + Serial.printf("%s\n", str.c_str()); +} + // BLE Client loop task. // Manages device connections and scanning. void bleClientTask(void *pvParameters) { @@ -156,33 +167,16 @@ bool SpinBLEClient::connectToServer() { return false; } if (myDevice->getServiceUUIDCount() > 0) { - bool found = false; - for (const auto& service : SUPPORTED_SERVICES) { - // Special case for Flywheel which requires name check - if (service.serviceUUID.equals(FLYWHEEL_UART_SERVICE_UUID)) { - if (myDevice->isAdvertisingService(service.serviceUUID) && myDevice->getName() == FLYWHEEL_BLE_NAME) { - serviceUUID = service.serviceUUID; - charUUID = service.characteristicUUID; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "trying to connect to %s", service.name.c_str()); - found = true; - break; - } - } - // For all other services - else if (myDevice->isAdvertisingService(service.serviceUUID)) { - serviceUUID = service.serviceUUID; - charUUID = service.characteristicUUID; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "trying to connect to %s", service.name.c_str()); - found = true; - break; - } - } - - if (!found) { + const BLEServiceInfo *serviceInfo = getDeviceServiceInfo(myDevice, String(myDevice->getName().c_str())); + if (!serviceInfo) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "No supported service UUID found"); spinBLEClient.myBLEDevices[device_number].reset(); return false; } + + serviceUUID = serviceInfo->serviceUUID; + charUUID = serviceInfo->characteristicUUID; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "trying to connect to %s", serviceInfo->name.c_str()); } else { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Device has no Service UUID"); spinBLEClient.myBLEDevices[device_number].reset(); @@ -268,7 +262,7 @@ bool SpinBLEClient::connectToServer() { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Connected to: %s - %s RSSI %d", this->adevName2UniqueName(myDevice).c_str(), pClient->getPeerAddress().toString().c_str(), pClient->getRssi()); - if (serviceUUID.equals(HID_SERVICE_UUID)) { + if (serviceUUID == HID_SERVICE_UUID) { connectBLE_HID(pClient); this->reconnectTries = MAX_RECONNECT_TRIES; SS2K_LOG(BLE_CLIENT_LOG_TAG, "Successful remote subscription."); @@ -299,7 +293,8 @@ bool SpinBLEClient::connectToServer() { SS2K_LOG(BLE_COMMON_LOG_TAG, "%s", logBuf); } if (pChr->canNotify()) { - if (!pChr->subscribe(true, onNotify)) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Setting up notifications for service %s char %s, handle %d", serviceUUID.toString().c_str(), charUUID.toString().c_str(), pChr->getHandle()); + if (!pChr->subscribe(true, testnotifyCB)) { /** Disconnect if subscribe failed */ SS2K_LOG(BLE_CLIENT_LOG_TAG, "Notifications Failed for %s", pClient->getPeerAddress().toString().c_str()); spinBLEClient.myBLEDevices[device_number].reset(); @@ -308,10 +303,10 @@ bool SpinBLEClient::connectToServer() { NimBLEDevice::deleteClient(pClient); return false; } - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Notifications Subscribed for %s", pClient->getPeerAddress().toString().c_str()); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Notifications Subscribed for %s, UUID %s", pClient->getPeerAddress().toString().c_str(), pChr->getUUID().toString().c_str()); } else if (pChr->canIndicate()) { /** Send false as first argument to subscribe to indications instead of notifications */ - if (!pChr->subscribe(false, onNotify)) { + if (!pChr->subscribe(false, notifyCB)) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Indications Failed for %s", pClient->getPeerAddress().toString().c_str()); /** Disconnect if subscribe failed */ spinBLEClient.myBLEDevices[device_number].reset(); @@ -342,7 +337,7 @@ bool SpinBLEClient::connectToServer() { /** None of these are required as they will be handled by the library with defaults. ** ** Remove as you see fit for your needs */ -void MyClientCallback::onConnect(NimBLEClient *pClient) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Connected"); } +void MyClientCallback::onConnect(NimBLEClient *pClient) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Connected, %s", pClient->getPeerAddress().toString().c_str()); } void MyClientCallback::onDisconnect(NimBLEClient *pClient, int reason) { if (!pClient->isConnected()) { @@ -359,7 +354,7 @@ void MyClientCallback::onDisconnect(NimBLEClient *pClient, int reason) { } 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) || - (spinBLEClient.myBLEDevices[i].charUUID == CYCLINGPOWERSERVICE_UUID)) { + (spinBLEClient.myBLEDevices[i].charUUID == CYCLINGPOWERSERVICE_UUID) || (spinBLEClient.myBLEDevices[i].charUUID == CSCSERVICE_UUID)) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Deregistered PM on Disconnect"); rtConfig->pm_batt.setValue(0); } @@ -418,28 +413,11 @@ void ScanCallbacks::onResult(const NimBLEAdvertisedDevice *advertisedDevice) { String aDevName = spinBLEClient.adevName2UniqueName(advertisedDevice); const char *aDevAddr = advertisedDevice->getAddress().toString().c_str(); - if (advertisedDevice->haveServiceUUID()) { - bool isSupported = false; - for (const auto& service : SUPPORTED_SERVICES) { - // Special case for Flywheel which requires name check - if (service.serviceUUID.equals(FLYWHEEL_UART_SERVICE_UUID)) { - if (advertisedDevice->isAdvertisingService(service.serviceUUID.toString()) && aDevName == String(FLYWHEEL_BLE_NAME)) { - isSupported = true; - break; - } - } - // For all other services - else if (advertisedDevice->isAdvertisingService(service.serviceUUID.toString())) { - isSupported = true; - break; - } - } - - if (isSupported) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Trying to match found device name: %s", aDevName.c_str()); + if (advertisedDevice->haveServiceUUID() && isDeviceSupported(advertisedDevice, aDevName)) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Trying to match found device name: %s", aDevName.c_str()); // Handling for BLE connected remotes - if (advertisedDevice->getServiceUUID().equals(HID_SERVICE_UUID)) { + if (advertisedDevice->getServiceUUID() == HID_SERVICE_UUID) { if (strcmp(userConfig->getConnectedRemote(), "any") == 0) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s", REMOTE, STRING_MATCHED_ANY); } else { @@ -452,7 +430,7 @@ void ScanCallbacks::onResult(const NimBLEAdvertisedDevice *advertisedDevice) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s %s%s", REMOTE, NAME, MATCHED, aDevName); } } - } else if (advertisedDevice->getServiceUUID().equals(HEARTSERVICE_UUID)) { + } else if (advertisedDevice->getServiceUUID() == HEARTSERVICE_UUID) { if (strcmp(userConfig->getConnectedHeartMonitor(), "any") == 0) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s", HRM, STRING_MATCHED_ANY); } else { @@ -489,7 +467,6 @@ void ScanCallbacks::onResult(const NimBLEAdvertisedDevice *advertisedDevice) { } SS2K_LOG(BLE_CLIENT_LOG_TAG, "Checking Slot %d", i); } - } } } @@ -530,22 +507,7 @@ void ScanCallbacks::onScanEnd(const NimBLEScanResults &results, int reason) { } } - // Check if device advertises any of our supported services - bool isSupported = false; - for (const auto& service : SUPPORTED_SERVICES) { - if (service.serviceUUID.equals(FLYWHEEL_UART_SERVICE_UUID)) { - if (d->isAdvertisingService(service.serviceUUID) && spinBLEClient.adevName2UniqueName(d) == String(FLYWHEEL_BLE_NAME)) { - isSupported = true; - break; - } - } - else if (d->isAdvertisingService(service.serviceUUID.toString())) { - isSupported = true; - break; - } - } - - if (!isDuplicate && isSupported) { + if (!isDuplicate && d->haveServiceUUID() && isDeviceSupported(d, spinBLEClient.adevName2UniqueName(d))) { String device = "device " + String(devices.size()); // Use the current size to index the new device devices[device]["name"] = spinBLEClient.adevName2UniqueName(d); @@ -585,7 +547,7 @@ void SpinBLEClient::removeDuplicates(NimBLEClient *pClient) { for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { // Disconnect oldest PM to avoid two connected. oldBLEd = this->myBLEDevices[i]; if (oldBLEd.advertisedDevice) { - if ((tBLEd.serviceUUID.equals(oldBLEd.serviceUUID)) && (tBLEd.peerAddress != oldBLEd.peerAddress)) { + if ((tBLEd.serviceUUID == oldBLEd.serviceUUID) && (tBLEd.peerAddress != oldBLEd.peerAddress)) { if (BLEDevice::getClientByPeerAddress(oldBLEd.peerAddress)) { if (BLEDevice::getClientByPeerAddress(oldBLEd.peerAddress)->isConnected()) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s Matched another service. Disconnecting: %s", tBLEd.peerAddress.toString().c_str(), oldBLEd.peerAddress.toString().c_str()); @@ -618,7 +580,7 @@ void SpinBLEClient::FTMSControlPointWrite(const uint8_t *pData, int length) { modData[i] = pData[i]; } for (int i = 0; i < NUM_BLE_DEVICES; i++) { - if (myBLEDevices[i].getPostConnected() && (myBLEDevices[i].serviceUUID.equals(FITNESSMACHINESERVICE_UUID))) { + if (myBLEDevices[i].getPostConnected() && (myBLEDevices[i].serviceUUID == FITNESSMACHINESERVICE_UUID)) { if (NimBLEDevice::getClientByPeerAddress(myBLEDevices[i].peerAddress)->getService(FITNESSMACHINESERVICE_UUID)) { pClient = NimBLEDevice::getClientByPeerAddress(myBLEDevices[i].peerAddress); break; @@ -786,10 +748,10 @@ void SpinBLEClient::connectBLE_HID(NimBLEClient *pClient) { // in subscribing to only one. std::vector charVector = pSvc->getCharacteristics(true); for (auto &it : charVector) { - if (it->getUUID().equals(NimBLEUUID(HID_REPORT_DATA_UUID))) { + if (it->getUUID() == NimBLEUUID(HID_REPORT_DATA_UUID)) { Serial.println(it->toString().c_str()); if (it->canNotify()) { - if (!it->subscribe(true, onNotify)) { + if (!it->subscribe(true, notifyCB)) { /** Disconnect if subscribe failed */ Serial.println("subscribe notification failed"); NimBLEDevice::deleteClient(pClient); @@ -900,26 +862,38 @@ void SpinBLEAdvertisedDevice::set(const NimBLEAdvertisedDevice *device, int id, this->serviceUUID = BLEUUID(inServiceUUID); this->charUUID = BLEUUID(inCharUUID); this->dataBufferQueue = xQueueCreate(4, sizeof(NotifyData)); - if (inServiceUUID.equals(HEARTSERVICE_UUID)) { - this->isHRM = true; - spinBLEClient.connectedHRM = true; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered HRM on Connect"); - } else if (inServiceUUID.equals(CSCSERVICE_UUID)) { - this->isCSC = true; - spinBLEClient.connectedCD = true; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered CSC on Connect"); - } else if (inServiceUUID.equals(CYCLINGPOWERSERVICE_UUID) || inServiceUUID.equals(FITNESSMACHINESERVICE_UUID) || inServiceUUID.equals(FLYWHEEL_UART_SERVICE_UUID) || - inServiceUUID.equals(ECHELON_SERVICE_UUID) || inServiceUUID.equals(PELOTON_DATA_UUID)) { - this->isPM = true; - spinBLEClient.connectedPM = true; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered PM on Connect"); - } else if (inServiceUUID.equals(HID_SERVICE_UUID)) { - this->isRemote = true; - spinBLEClient.connectedRemote = true; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered Remote on Connect"); - } else { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to set service!"); + + // Only register services when we have a connected client + if (id != BLE_HS_CONN_HANDLE_NONE) { + NimBLEClient *pClient = NimBLEDevice::getClientByPeerAddress(device->getAddress()); + if (pClient) { + // Get all services + const std::vector &services = pClient->getServices(true); + for (auto &pService : services) { + BLEUUID serviceUUID = pService->getUUID(); + + if (serviceUUID == HEARTSERVICE_UUID) { + this->isHRM = true; + spinBLEClient.connectedHRM = true; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered HRM on Connect"); + } else if (serviceUUID == CSCSERVICE_UUID) { + this->isCSC = true; + spinBLEClient.connectedCD = true; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered CSC on Connect"); + } else if (serviceUUID == CYCLINGPOWERSERVICE_UUID || serviceUUID == FITNESSMACHINESERVICE_UUID || serviceUUID == FLYWHEEL_UART_SERVICE_UUID || + serviceUUID == ECHELON_SERVICE_UUID || serviceUUID == PELOTON_DATA_UUID) { + this->isPM = true; + spinBLEClient.connectedPM = true; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered PM on Connect"); + } else if (serviceUUID == HID_SERVICE_UUID) { + this->isRemote = true; + spinBLEClient.connectedRemote = true; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered Remote on Connect"); + } + } + } } + // During initial discovery, just store the device info without registering services } void SpinBLEAdvertisedDevice::reset() { diff --git a/src/BLE_Common.cpp b/src/BLE_Common.cpp index 1347d460..d24a2106 100644 --- a/src/BLE_Common.cpp +++ b/src/BLE_Common.cpp @@ -17,6 +17,32 @@ bool hr2p = false; +const BLEServiceInfo* getDeviceServiceInfo(const NimBLEAdvertisedDevice* advertisedDevice, const String& deviceName) { + if (!advertisedDevice->haveServiceUUID()) { + return nullptr; + } + + for (const auto& service : SUPPORTED_SERVICES) { + // Special case for Flywheel which requires name check + if (service.serviceUUID == FLYWHEEL_UART_SERVICE_UUID) { + if (advertisedDevice->isAdvertisingService(service.serviceUUID) && + deviceName == String(FLYWHEEL_BLE_NAME)) { + return &service; + } + } + // For all other services + else if (advertisedDevice->isAdvertisingService(service.serviceUUID)) { + return &service; + } + } + + return nullptr; +} + +bool isDeviceSupported(const NimBLEAdvertisedDevice* advertisedDevice, const String& deviceName) { + return getDeviceServiceInfo(advertisedDevice, deviceName) != nullptr; +} + void BLECommunications() { static unsigned long int bleCommTimer = millis(); if (((millis() - bleCommTimer) > BLE_NOTIFY_DELAY) && !ss2k->isUpdating) { @@ -24,10 +50,10 @@ void BLECommunications() { // **********************************Client*************************************** for (auto &_BLEd : spinBLEClient.myBLEDevices) { // loop through discovered devices if (_BLEd.connectedClientID != BLE_HS_CONN_HANDLE_NONE) { - SS2K_LOGW(BLE_COMMON_LOG_TAG, "Address: (%s) Client ID: (%d) SerUUID: (%s) CharUUID: (%s) HRM: (%s) PM: (%s) CSC: (%s) CT: (%s) doConnect: (%s) postConnect: (%s)", - _BLEd.peerAddress.toString().c_str(), _BLEd.connectedClientID, _BLEd.serviceUUID.toString().c_str(), _BLEd.charUUID.toString().c_str(), - _BLEd.isHRM ? "true" : "false", _BLEd.isPM ? "true" : "false", _BLEd.isCSC ? "true" : "false", _BLEd.isCT ? "true" : "false", _BLEd.doConnect ? "true" : "false", - _BLEd.getPostConnected() ? "true" : "false"); + // SS2K_LOGW(BLE_COMMON_LOG_TAG, "Address: (%s) Client ID: (%d) SerUUID: (%s) CharUUID: (%s) HRM: (%s) PM: (%s) CSC: (%s) CT: (%s) doConnect: (%s) postConnect: (%s)", + // _BLEd.peerAddress.toString().c_str(), _BLEd.connectedClientID, _BLEd.serviceUUID.toString().c_str(), _BLEd.charUUID.toString().c_str(), + // _BLEd.isHRM ? "true" : "false", _BLEd.isPM ? "true" : "false", _BLEd.isCSC ? "true" : "false", _BLEd.isCT ? "true" : "false", _BLEd.doConnect ? "true" : "false", + // _BLEd.getPostConnected() ? "true" : "false"); if (_BLEd.advertisedDevice) { // is device registered? if ((_BLEd.connectedClientID != BLE_HS_CONN_HANDLE_NONE) && (_BLEd.doConnect == false)) { // client must not be in connection process if (BLEDevice::getClientByPeerAddress(_BLEd.peerAddress)) { // nullptr check @@ -121,4 +147,4 @@ void BLECommunications() { digitalWrite(LED_PIN, HIGH); } } -} \ No newline at end of file +} From 66fd6eecae41915ea7d1177b542ae772688a6349 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Sun, 12 Jan 2025 15:59:24 -0600 Subject: [PATCH 010/451] implemented neighbor weighting for extrapFillTable() function. --- include/SmartSpin_parameters.h | 3 - src/BLE_Custom_Characteristic.cpp | 16 -- src/ERG_Mode.cpp | 254 ++++++++++++++++-------------- src/Main.cpp | 1 - 4 files changed, 136 insertions(+), 138 deletions(-) diff --git a/include/SmartSpin_parameters.h b/include/SmartSpin_parameters.h index 60c30975..befe8d77 100644 --- a/include/SmartSpin_parameters.h +++ b/include/SmartSpin_parameters.h @@ -196,9 +196,6 @@ class userParameters { void setShifterDir(bool shd) { shifterDir = shd; } bool getShifterDir() { return shifterDir; } - void setTotalTravel(int tT) { totalTravel = tT; } - bool getTotalTravel() { return totalTravel; } - void setUdpLogEnabled(bool enabled) { udpLogEnabled = enabled; } bool getUdpLogEnabled() { return udpLogEnabled; } diff --git a/src/BLE_Custom_Characteristic.cpp b/src/BLE_Custom_Characteristic.cpp index 131394aa..69f2a89f 100644 --- a/src/BLE_Custom_Characteristic.cpp +++ b/src/BLE_Custom_Characteristic.cpp @@ -739,22 +739,6 @@ void BLE_ss2kCustomCharacteristic::process(std::string rxValue) { ss2k->setTargetPosition(int32_t((uint8_t)(rxValue[2]) << 0 | (uint8_t)(rxValue[3]) << 8 | (uint8_t)(rxValue[4]) << 16 | (uint8_t)(rxValue[5]) << 24)); logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, " (%f)", userConfig->getHMax()); } - - case BLE_totalTravel: // 0x2C - logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "<-totalTravel"); - if (rxValue[0] == cc_read) { - returnValue[0] = cc_success; - returnValue[2] = (uint8_t)(userConfig->getTotalTravel() & 0xff); - returnValue[3] = (uint8_t)(userConfig->getTotalTravel() >> 8); - returnValue[4] = (uint8_t)(userConfig->getTotalTravel() >> 16); - returnValue[5] = (uint8_t)(userConfig->getTotalTravel() >> 24); - returnLength += 4; - } - if (rxValue[0] == cc_write) { - returnValue[0] = cc_success; - ss2k->setTargetPosition(int32_t((uint8_t)(rxValue[2]) << 0 | (uint8_t)(rxValue[3]) << 8 | (uint8_t)(rxValue[4]) << 16 | (uint8_t)(rxValue[5]) << 24)); - logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, " (%f)", userConfig->getTotalTravel()); - } break; case BLE_homingSensitivity: // 0x2C diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 51ea2ce9..79c90839 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -15,6 +15,7 @@ #include #include #include +#include PowerTable* powerTable = new PowerTable; @@ -108,9 +109,9 @@ int PowerBuffer::getReadings() { return ret; } -void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, Measurement watts) { +void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, Measurement watts) { //this basically checks the constaraints and if everything is good it adds it into the powerbuffer. no need to change if ((cadence >= (MINIMUM_TABLE_CAD - (POWERTABLE_CAD_INCREMENT / 2))) && - (cadence <= (MINIMUM_TABLE_CAD + (POWERTABLE_CAD_INCREMENT * POWERTABLE_CAD_SIZE) - (POWERTABLE_CAD_SIZE / 2))) && (watts.getValue() > 10) && + (cadence <= (MINIMUM_TABLE_CAD + (POWERTABLE_CAD_INCREMENT * POWERTABLE_CAD_SIZE) - (POWERTABLE_CAD_SIZE / 2))) && (watts.getValue() > 10) && //adding constraints (watts.getValue() < (POWERTABLE_WATT_SIZE * POWERTABLE_WATT_INCREMENT))) { if (powerBuffer.powerEntry[0].readings == 0) { // Take Initial reading @@ -402,48 +403,80 @@ void PowerTable::fillTable() { // Fill each empty cell by linear interpolation for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - // Interpolate horizontally - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest left and right non-empty cells - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + + //create two hash maps for row and col + std::unordered_map> rowMap; + std::unordered_map> colMap; - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear interpolation - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) * (j - left) / (right - left); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + //store non-empty values + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + rowMap[i][j] = this->tableRow[i].tableEntry[j].targetPosition; + colMap[j][i] = this->tableRow[i].tableEntry[j].targetPosition; + } + } } - } - } - } - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - // Interpolate vertically + //horizontal interpolation for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top and bottom non-empty cells - int top = i - 1; - while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; - int bottom = i + 1; - while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { - // Linear interpolation - tempValue = this->tableRow[top].tableEntry[j].targetPosition + - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) * (i - top) / (bottom - top); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + int left = j - 1; + while (left >= 0 && rowMap[i].find(left) == rowMap[i].end()) + left--; + + int right = j + 1; + while (right < POWERTABLE_WATT_SIZE && rowMap[i].find(right) == rowMap[i].end()) + right++; + + if (left >= 0 && right < POWERTABLE_WATT_SIZE) { + + int16_t tempValue = rowMap[i][left] + (rowMap[i][right] - rowMap[i][left]) * (j - left) / (right - left); + + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } } - } - } + + //vertical interpolation + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + + int top = i - 1; + while (top >= 0 && colMap[j].find(top) == colMap[j].end()) + top--; + + int bottom = i + 1; + while (bottom < POWERTABLE_CAD_SIZE && colMap[j].find(bottom) == colMap[j].end()) + bottom++; + + if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { + + int16_t tempValue = colMap[j][top] + (colMap[j][bottom] - colMap[j][top]) * (i - top) / (bottom - top); + + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } + } + } +} + +int weightedAverage(int leftValue, int rightValue, int leftWeight, int rightWeight){ + if (leftWeight + rightWeight == 0){ + return INT16_MIN; } + int weightedValue = (leftValue * leftWeight + rightValue * rightWeight) / (leftWeight + rightWeight); + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Value: %f", weightedValue); + return (leftValue * leftWeight + rightValue * rightWeight) / (leftWeight + rightWeight); } void PowerTable::extrapFillTable() { @@ -481,37 +514,34 @@ void PowerTable::extrapFillTable() { if (left >= 0 && right < POWERTABLE_WATT_SIZE) { // Linear extrapolation if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - if (j < left) { - // Extrapolate to the left - tempValue = this->tableRow[i].tableEntry[left].targetPosition - - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } else if (j > right) { - // Extrapolate to the right - tempValue = this->tableRow[i].tableEntry[right].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + + int leftWeight = (j - left); + int rightWeight = (right - j); + int tempValue = weightedAverage(this->tableRow[i].tableEntry[left].targetPosition, this->tableRow[i].tableEntry[right].targetPosition, leftWeight, rightWeight); + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) + + if(this->testNeighbors(i, j, tempValue).allNeighborsPassed){ + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } - } else if (left - 1 >= 0) { + } else if (left>= 0) { // Only left value available, extrapolate to the right - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN) { + int rigthWeight = 1; + int tempValue = this->tableRow[i].tableEntry[left].targetPosition + rigthWeight; + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } - } else if (right + 1 < POWERTABLE_WATT_SIZE) { + } else if (right < POWERTABLE_WATT_SIZE) { // Only right value available, extrapolate to the left - if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - tempValue = - this->tableRow[i].tableEntry[right].targetPosition - - (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); + if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + int leftWeight = 1; + int tempValue = this->tableRow[i].tableEntry[right].targetPosition - leftWeight; + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } @@ -541,43 +571,39 @@ void PowerTable::extrapFillTable() { // Find nearest right non-empty cell int right = j + 1; while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear extrapolation - if (j < left) { - // Extrapolate to the left - tempValue = this->tableRow[i].tableEntry[left].targetPosition - - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + + int leftWeight = (j - left); + int rightWeight = (right - j); + int tempValue = weightedAverage(this->tableRow[i].tableEntry[left].targetPosition, this->tableRow[i].tableEntry[right].targetPosition, leftWeight, rightWeight); + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) - } else if (j > right) { - // Extrapolate to the right - tempValue = this->tableRow[i].tableEntry[right].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } - } else if (left >= 1) { + } else if (left >= 0) { // Only left value available, extrapolate to the right - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN) { + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN){ + int tempValue = this->tableRow[i].tableEntry[left].targetPosition + 1; + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } + } } - } else if (right + 1 < POWERTABLE_WATT_SIZE) { + } else if (right < POWERTABLE_WATT_SIZE) { // Only right value available, extrapolate to the left - if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[right].targetPosition - - (right - j) * - (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); + if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + int tempValue = this->tableRow[i].tableEntry[right].targetPosition - 1; + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + } } } @@ -598,41 +624,33 @@ void PowerTable::extrapFillTable() { while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { - // Linear extrapolation - if (i < top) { - // Extrapolate upwards - tempValue = this->tableRow[top].tableEntry[j].targetPosition - - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } else if (i > bottom) { - // Extrapolate downwards - tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + + if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN) { + int topWeight = (i - top); + int bottomWeight = (bottom - i); + int tempValue = weightedAverage(this->tableRow[top].tableEntry[j].targetPosition, this->tableRow[bottom].tableEntry[j].targetPosition, topWeight, bottomWeight); + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } - } else if (top >= 1) { - // Only top value available, extrapolate downwards - if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { - tempValue = this->tableRow[top].tableEntry[j].targetPosition + - (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } else { - } + } + + } else if (top >= 0) { + if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN) { + int tempValue = this->tableRow[top].tableEntry[j].targetPosition + 1; + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } - } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { - // Only bottom value available, extrapolate upwards - if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { - tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - - (bottom - i) * - (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + } + + } else if (bottom < POWERTABLE_CAD_SIZE) { + if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN) { + int tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - 1; + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } } } } diff --git a/src/Main.cpp b/src/Main.cpp index a25de80b..b495a40b 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -647,7 +647,6 @@ void SS2K::goHome(bool bothDirections) { if (bothDirections) { userConfig->setHMin(rtConfig->getMinStep()); userConfig->setHMax(rtConfig->getMaxStep()); - userConfig->setTotalTravel(userConfig->getHMax() - userConfig->getHMin()); } // In case this was only one direction homing. rtConfig->setMaxStep(userConfig->getHMax()); From db82a4d7aa5fe609fd92d2ffb3ace652c4214b11 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Sun, 12 Jan 2025 22:04:06 +0000 Subject: [PATCH 011/451] Update changelog for version 24.12.17 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 080ec42d..e2f7a81e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Hardware +## [24.12.17] + +### Added + +### Changed + +### Hardware + + ## [24.12.7] ### Added From a0acc00b0ddfe6aff8863beb8e7ef5be40226335 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Sun, 12 Jan 2025 19:45:25 -0600 Subject: [PATCH 012/451] implemented neighbor testing on diag extrapolation --- src/ERG_Mode.cpp | 127 +++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 65 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 79c90839..9710ff6f 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -518,10 +518,10 @@ void PowerTable::extrapFillTable() { int leftWeight = (j - left); int rightWeight = (right - j); int tempValue = weightedAverage(this->tableRow[i].tableEntry[left].targetPosition, this->tableRow[i].tableEntry[right].targetPosition, leftWeight, rightWeight); - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) if(this->testNeighbors(i, j, tempValue).allNeighborsPassed){ this->tableRow[i].tableEntry[j].targetPosition = tempValue; + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue); } } } else if (left>= 0) { @@ -529,10 +529,10 @@ void PowerTable::extrapFillTable() { if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN) { int rigthWeight = 1; int tempValue = this->tableRow[i].tableEntry[left].targetPosition + rigthWeight; - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue); } } } else if (right < POWERTABLE_WATT_SIZE) { @@ -540,10 +540,10 @@ void PowerTable::extrapFillTable() { if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { int leftWeight = 1; int tempValue = this->tableRow[i].tableEntry[right].targetPosition - leftWeight; - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue); } } } @@ -578,32 +578,30 @@ void PowerTable::extrapFillTable() { int leftWeight = (j - left); int rightWeight = (right - j); int tempValue = weightedAverage(this->tableRow[i].tableEntry[left].targetPosition, this->tableRow[i].tableEntry[right].targetPosition, leftWeight, rightWeight); - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue); } } } else if (left >= 0) { - // Only left value available, extrapolate to the right if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN) { if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN){ int tempValue = this->tableRow[i].tableEntry[left].targetPosition + 1; - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue); } } } } else if (right < POWERTABLE_WATT_SIZE) { - // Only right value available, extrapolate to the left if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { int tempValue = this->tableRow[i].tableEntry[right].targetPosition - 1; - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; - + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue); } } } @@ -629,27 +627,30 @@ void PowerTable::extrapFillTable() { int topWeight = (i - top); int bottomWeight = (bottom - i); int tempValue = weightedAverage(this->tableRow[top].tableEntry[j].targetPosition, this->tableRow[bottom].tableEntry[j].targetPosition, topWeight, bottomWeight); - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue); } } } else if (top >= 0) { if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN) { int tempValue = this->tableRow[top].tableEntry[j].targetPosition + 1; - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue); } } } else if (bottom < POWERTABLE_CAD_SIZE) { if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN) { int tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - 1; - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue); } } } @@ -661,66 +662,62 @@ void PowerTable::extrapFillTable() { void PowerTable::extrapolateDiagonal() { int tempValue = INT16_MIN; - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top-left non-empty cell - int topLeftRow = i - 1, topLeftCol = j - 1; - while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { - topLeftRow--; - topLeftCol--; - } - - // Find nearest bottom-right non-empty cell - int bottomRightRow = i + 1, bottomRightCol = j + 1; - while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && - this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { - bottomRightRow++; - bottomRightCol++; - } - - // Perform diagonal extrapolation (top-left to bottom-right) - if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { - tempValue = - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + - ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / - (bottomRightCol - topLeftCol); + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + std::vector> isNeighbor; + std::vector weights; + int weightSum = 0; + + //looks at all surrounding cells + for (int row = -1; row <= 1; ++row) { //checks top and bottom + for (int col = -1; col <= 1; ++col) { // checks right and left + int rowPosition = i + row; + int colPosition = j + col; + + // make sure the vald neighbor is within the range + if (rowPosition >= 0 && rowPosition < POWERTABLE_CAD_SIZE && colPosition >= 0 && colPosition < POWERTABLE_WATT_SIZE && (row != 0 || col != 0) && this->tableRow[rowPosition].tableEntry[colPosition].targetPosition != INT16_MIN) { + + //calculate the weight or distance between the two valid neighbors + int dist = abs(row) + abs(col); + int weight; + if(dist > 0){ + weight = 1 / dist; // 1 / dist ratio, smaller the farther it is + SS2K_LOG(POWERTABLE_LOG_TAG, "Weight (distance): %f", weight) + } else { + weight = 1; + SS2K_LOG(POWERTABLE_LOG_TAG, "No distance.") + } - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } + // store the data + isNeighbor.push_back({rowPosition, colPosition}); + weights.push_back(weight); + weightSum += weight; + } + } + } - // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left - if (tempValue == INT16_MIN) { - // Find nearest top-right non-empty cell - int topRightRow = i - 1, topRightCol = j + 1; - while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { - topRightRow--; - topRightCol++; - } + // If we have neightbors we can calculate a weighted average + if (!isNeighbor.empty()) { + int weightedSum = 0; - // Find nearest bottom-left non-empty cell - int bottomLeftRow = i + 1, bottomLeftCol = j - 1; - while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { - bottomLeftRow++; - bottomLeftCol--; - } + for (size_t i = 0; i < isNeighbor.size(); ++i) { + int x = isNeighbor[i].first; + int y = isNeighbor[i].second; + int neighborValue = this->tableRow[x].tableEntry[y].targetPosition; + weightedSum += neighborValue * weights[i]; + } - // Perform diagonal extrapolation (top-right to bottom-left) - if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { - tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + - ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * - (j - bottomLeftCol)) / - (topRightCol - bottomLeftCol); + // get the value to store inside the cell + tempValue = weightedSum / weightSum; - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted avg: %f", tempValue) + } } - } } - } - } + } } } From 4f55587df9c8f7e74f9e4929c6baf75149419e2e Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Mon, 13 Jan 2025 12:54:05 -0600 Subject: [PATCH 013/451] up to date with doudar develop --- src/ERG_Mode.cpp | 249 ++++++++++++++++++++++------------------------- 1 file changed, 116 insertions(+), 133 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 79c90839..71aef15a 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -403,80 +403,48 @@ void PowerTable::fillTable() { // Fill each empty cell by linear interpolation for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - - //create two hash maps for row and col - std::unordered_map> rowMap; - std::unordered_map> colMap; + // Interpolate horizontally + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest left and right non-empty cells + int left = j - 1; + while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + int right = j + 1; + while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - //store non-empty values - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - rowMap[i][j] = this->tableRow[i].tableEntry[j].targetPosition; - colMap[j][i] = this->tableRow[i].tableEntry[j].targetPosition; - } - } + if (left >= 0 && right < POWERTABLE_WATT_SIZE) { + // Linear interpolation + tempValue = this->tableRow[i].tableEntry[left].targetPosition + + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) * (j - left) / (right - left); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } } + } + } + } - //horizontal interpolation + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + // Interpolate vertically for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - - int left = j - 1; - while (left >= 0 && rowMap[i].find(left) == rowMap[i].end()) - left--; - - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && rowMap[i].find(right) == rowMap[i].end()) - right++; - - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - - int16_t tempValue = rowMap[i][left] + (rowMap[i][right] - rowMap[i][left]) * (j - left) / (right - left); - - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } - } - - //vertical interpolation - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - - int top = i - 1; - while (top >= 0 && colMap[j].find(top) == colMap[j].end()) - top--; - - int bottom = i + 1; - while (bottom < POWERTABLE_CAD_SIZE && colMap[j].find(bottom) == colMap[j].end()) - bottom++; - - if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { - - int16_t tempValue = colMap[j][top] + (colMap[j][bottom] - colMap[j][top]) * (i - top) / (bottom - top); + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest top and bottom non-empty cells + int top = i - 1; + while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; + int bottom = i + 1; + while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } + if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { + // Linear interpolation + tempValue = this->tableRow[top].tableEntry[j].targetPosition + + (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) * (i - top) / (bottom - top); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } } - } -} - -int weightedAverage(int leftValue, int rightValue, int leftWeight, int rightWeight){ - if (leftWeight + rightWeight == 0){ - return INT16_MIN; + } + } } - int weightedValue = (leftValue * leftWeight + rightValue * rightWeight) / (leftWeight + rightWeight); - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Value: %f", weightedValue); - return (leftValue * leftWeight + rightValue * rightWeight) / (leftWeight + rightWeight); } void PowerTable::extrapFillTable() { @@ -514,34 +482,37 @@ void PowerTable::extrapFillTable() { if (left >= 0 && right < POWERTABLE_WATT_SIZE) { // Linear extrapolation if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - - int leftWeight = (j - left); - int rightWeight = (right - j); - int tempValue = weightedAverage(this->tableRow[i].tableEntry[left].targetPosition, this->tableRow[i].tableEntry[right].targetPosition, leftWeight, rightWeight); - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) - - if(this->testNeighbors(i, j, tempValue).allNeighborsPassed){ - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + if (j < left) { + // Extrapolate to the left + tempValue = this->tableRow[i].tableEntry[left].targetPosition - + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } else if (j > right) { + // Extrapolate to the right + tempValue = this->tableRow[i].tableEntry[right].targetPosition + + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } } } - } else if (left>= 0) { + } else if (left - 1 >= 0) { // Only left value available, extrapolate to the right - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN) { - int rigthWeight = 1; - int tempValue = this->tableRow[i].tableEntry[left].targetPosition + rigthWeight; - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) - + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { + tempValue = this->tableRow[i].tableEntry[left].targetPosition + + (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } - } else if (right < POWERTABLE_WATT_SIZE) { + } else if (right + 1 < POWERTABLE_WATT_SIZE) { // Only right value available, extrapolate to the left - if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - int leftWeight = 1; - int tempValue = this->tableRow[i].tableEntry[right].targetPosition - leftWeight; - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) - + if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + tempValue = + this->tableRow[i].tableEntry[right].targetPosition - + (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } @@ -571,39 +542,43 @@ void PowerTable::extrapFillTable() { // Find nearest right non-empty cell int right = j + 1; while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - - int leftWeight = (j - left); - int rightWeight = (right - j); - int tempValue = weightedAverage(this->tableRow[i].tableEntry[left].targetPosition, this->tableRow[i].tableEntry[right].targetPosition, leftWeight, rightWeight); - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) - + // Linear extrapolation + if (j < left) { + // Extrapolate to the left + tempValue = this->tableRow[i].tableEntry[left].targetPosition - + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } else if (j > right) { + // Extrapolate to the right + tempValue = this->tableRow[i].tableEntry[right].targetPosition + + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } - } else if (left >= 0) { + } else if (left >= 1) { // Only left value available, extrapolate to the right - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN) { - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN){ - int tempValue = this->tableRow[i].tableEntry[left].targetPosition + 1; - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { + tempValue = this->tableRow[i].tableEntry[left].targetPosition + + (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } - } } - } else if (right < POWERTABLE_WATT_SIZE) { + } else if (right + 1 < POWERTABLE_WATT_SIZE) { // Only right value available, extrapolate to the left - if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - int tempValue = this->tableRow[i].tableEntry[right].targetPosition - 1; - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) + if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { + tempValue = this->tableRow[i].tableEntry[right].targetPosition - + (right - j) * + (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; - + } } } } @@ -624,33 +599,41 @@ void PowerTable::extrapFillTable() { while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { - - if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN) { - int topWeight = (i - top); - int bottomWeight = (bottom - i); - int tempValue = weightedAverage(this->tableRow[top].tableEntry[j].targetPosition, this->tableRow[bottom].tableEntry[j].targetPosition, topWeight, bottomWeight); - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + // Linear extrapolation + if (i < top) { + // Extrapolate upwards + tempValue = this->tableRow[top].tableEntry[j].targetPosition - + (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } else if (i > bottom) { + // Extrapolate downwards + tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + + (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } } - } - - } else if (top >= 0) { - if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN) { - int tempValue = this->tableRow[top].tableEntry[j].targetPosition + 1; - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } else if (top >= 1) { + // Only top value available, extrapolate downwards + if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { + tempValue = this->tableRow[top].tableEntry[j].targetPosition + + (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } else { + } } - } - - } else if (bottom < POWERTABLE_CAD_SIZE) { - if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN) { - int tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - 1; - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue) - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { + // Only bottom value available, extrapolate upwards + if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { + tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - + (bottom - i) * + (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } } } } From 3e9fc978417d2964d04472c0f47207d3b35fd875 Mon Sep 17 00:00:00 2001 From: ddtomic Date: Tue, 14 Jan 2025 19:20:51 -0600 Subject: [PATCH 014/451] added comments for readability on insetpoint --- src/ERG_Mode.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 51ea2ce9..3e201904 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -1182,14 +1182,22 @@ void ErgMode::_setPointChangeState(int newCadence, Measurement& newWatts) { } void ErgMode::_inSetpointState(int newCadence, Measurement& newWatts) { + // retrieves the current Watt output int watts = newWatts.getValue(); - int wattChange = newWatts.getTarget() - watts; // setpoint_form_trainer - current_torque => Amount to increase or decrease incline + // setpoint_form_trainer - current_torque => Amount to increase or decrease incline + int wattChange = newWatts.getTarget() - watts; + + // Calculates how far current power is from the target power, measred as a percentage of target float deviation = ((float)wattChange * 100.0) / ((float)newWatts.getTarget()); - float factor = abs(deviation) > 10 ? userConfig->getERGSensitivity() : userConfig->getERGSensitivity() / 2; + // retrieves the sensitivity from adjustments from userConfig + float factor = abs(deviation) > 10 ? userConfig->getERGSensitivity() : userConfig->getERGSensitivity() / 2; + + // Adjusts the incline float newIncline = ss2k->getCurrentPosition() + (wattChange * factor); + // passes to apply new cadence, power measurement and incline settings _updateValues(newCadence, newWatts, newIncline); } From 44686b22d94a32fcf2a36e93cddb176c03b010e3 Mon Sep 17 00:00:00 2001 From: ddtomic Date: Wed, 15 Jan 2025 15:17:42 -0600 Subject: [PATCH 015/451] implementing PID, WIP --- src/ERG_Mode.cpp | 69 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 9 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 3e201904..c71389c7 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -1181,26 +1181,77 @@ void ErgMode::_setPointChangeState(int newCadence, Measurement& newWatts) { ergTimer += (ERG_MODE_DELAY * 2); // Wait for power meter to register new watts } +// INTRODUCING PID CONTROL LOOP +// Error: Difference between TW and Current W + +// Proportional term: Directly Proportional to error +// Integral term: accumulated sum of errors over time +// Derivative term: rate of change of error + +// PrevError void ErgMode::_inSetpointState(int newCadence, Measurement& newWatts) { + // Setting Gains For PID Loop + float Kp = 0.1; + float Ki = 0.1; + float Kd = 0.1; + + // Initialize PID, Neeed to move these to prevent them resetting every loop + float integral = 0.0; + float prevError = 0.0; + // retrieves the current Watt output int watts = newWatts.getValue(); + // retrieves target Watt output + int target = newWatts.getTarget(); + // subtracting target from current watts + float error = target - watts; + + // Defining proportional term + float proportional = Kp * error; + + // Defining integral term + integral += error; + float integralFinal = Ki * integral; + + // NEED TO GO BACK AND CLAMP DOWN INTEGRAL TO PREVENT IT FROM BEING TOO LARGE - // setpoint_form_trainer - current_torque => Amount to increase or decrease incline - int wattChange = newWatts.getTarget() - watts; + // Defining derivative term + float derivative = error - prevError; // Difference between current and previous errors + float derivativeTerm = Kd * derivative; - // Calculates how far current power is from the target power, measred as a percentage of target - float deviation = ((float)wattChange * 100.0) / ((float)newWatts.getTarget()); + // final PID output + float PID_output = proportional + integralFinal + derivativeTerm; - // retrieves the sensitivity from adjustments from userConfig - float factor = abs(deviation) > 10 ? userConfig->getERGSensitivity() : userConfig->getERGSensitivity() / 2; + // Calculate the new incline + float newIncline = ss2k->getCurrentPosition() + PID_output; - // Adjusts the incline - float newIncline = ss2k->getCurrentPosition() + (wattChange * factor); + prevError = error; - // passes to apply new cadence, power measurement and incline settings + // Apply the new values _updateValues(newCadence, newWatts, newIncline); } +// OLD PI FUNCTION +// void ErgMode::_inSetpointState(int newCadence, Measurement& newWatts) { +// // retrieves the current Watt output +// int watts = newWatts.getValue(); + +// // setpoint_form_trainer - current_torque => Amount to increase or decrease incline +// int wattChange = newWatts.getTarget() - watts; + +// // Calculates how far current power is from the target power, measred as a percentage of target +// float deviation = ((float)wattChange * 100.0) / ((float)newWatts.getTarget()); + +// // retrieves the sensitivity from adjustments from userConfig +// float factor = abs(deviation) > 10 ? userConfig->getERGSensitivity() : userConfig->getERGSensitivity() / 2; + +// // Adjusts the incline +// float newIncline = ss2k->getCurrentPosition() + (wattChange * factor); + +// // passes to apply new cadence, power measurement and incline settings +// _updateValues(newCadence, newWatts, newIncline); +// } + void ErgMode::_updateValues(int newCadence, Measurement& newWatts, float newIncline) { rtConfig->setTargetIncline(newIncline); _writeLog(ss2k->getCurrentPosition(), newIncline, this->setPoint, newWatts.getTarget(), this->watts.getValue(), newWatts.getValue(), this->cadence, newCadence); From 2d506ede37fca859cf5f9c7482bf936f38a2496d Mon Sep 17 00:00:00 2001 From: ddtomic Date: Wed, 15 Jan 2025 16:57:43 -0600 Subject: [PATCH 016/451] changing variable scope PID --- src/ERG_Mode.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index c71389c7..ea47e36e 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -1195,9 +1195,9 @@ void ErgMode::_inSetpointState(int newCadence, Measurement& newWatts) { float Ki = 0.1; float Kd = 0.1; - // Initialize PID, Neeed to move these to prevent them resetting every loop - float integral = 0.0; - float prevError = 0.0; + // initialize, may need to double check it's not resetting every time + static float integral = 0.0; + static float prevError = 0.0; // retrieves the current Watt output int watts = newWatts.getValue(); @@ -1222,7 +1222,7 @@ void ErgMode::_inSetpointState(int newCadence, Measurement& newWatts) { // final PID output float PID_output = proportional + integralFinal + derivativeTerm; - // Calculate the new incline + // Calculate new incline float newIncline = ss2k->getCurrentPosition() + PID_output; prevError = error; From a9aa97f788ce5af1bf6b2262ee1f15e7398f1525 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 15 Jan 2025 18:51:59 -0600 Subject: [PATCH 017/451] Added toggles for turning on/off ERG control methods --- CHANGELOG.md | 1 + include/settings.h | 9 +++++++++ src/ERG_Mode.cpp | 19 +++++++++++++++++-- src/Main.cpp | 2 ++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8eda3ead..7c0abe22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added ### Changed +-PID loop for ERG mode instead of P loop. ### Hardware diff --git a/include/settings.h b/include/settings.h index 51314d62..a0c55166 100644 --- a/include/settings.h +++ b/include/settings.h @@ -253,6 +253,15 @@ const char* const DEFAULT_PASSWORD = "password"; #define RUNTIMECONFIG_JSON_SIZE 1000 + DEBUG_LOG_BUFFER_SIZE +// Uncomment to use guardrails for ERG mode in the stepper loop. +// #define ERG_GUARDRAILS + +//Uncomment to enable the use of the power table for ERG mode. +//#define ERG_MODE_USE_POWER_TABLE + +// Uncomment to use the PID controller for ERG mode. +#define ERG_MODE_USE_PID + // PowerTable Version #define TABLE_VERSION 5 diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index ea47e36e..55ecf7e3 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -1134,14 +1134,22 @@ void ErgMode::computeErg() { return; } - // SetPoint changed +#ifdef ERG_MODE_USE_POWER_TABLE +// SetPoint changed +#ifdef ERG_MODE_USE_PID if (abs(this->setPoint - newWatts.getTarget()) > 20) { +#endif _setPointChangeState(newCadence, newWatts); return; +#ifdef ERG_MODE_USE_PID } +#endif +#endif +#ifdef ERG_MODE_USE_PID // Setpoint unchanged _inSetpointState(newCadence, newWatts); +#endif } void ErgMode::_setPointChangeState(int newCadence, Measurement& newWatts) { @@ -1191,7 +1199,7 @@ void ErgMode::_setPointChangeState(int newCadence, Measurement& newWatts) { // PrevError void ErgMode::_inSetpointState(int newCadence, Measurement& newWatts) { // Setting Gains For PID Loop - float Kp = 0.1; + float Kp = userConfig->getERGSensitivity(); float Ki = 0.1; float Kd = 0.1; @@ -1222,6 +1230,13 @@ void ErgMode::_inSetpointState(int newCadence, Measurement& newWatts) { // final PID output float PID_output = proportional + integralFinal + derivativeTerm; + // log proportional, integral, derivative every five seconds + static unsigned long lastTime = 0; + if (millis() - lastTime > 5000) { + lastTime = millis(); + SS2K_LOG(ERG_MODE_LOG_TAG, "Proportional: %f, Integral: %f, Derivative: %f", proportional, integralFinal, derivativeTerm); + } + // Calculate new incline float newIncline = ss2k->getCurrentPosition() + PID_output; diff --git a/src/Main.cpp b/src/Main.cpp index b495a40b..5b9cc449 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -405,6 +405,7 @@ void SS2K::moveStepper() { ss2k->currentPosition = stepper->getCurrentPosition(); if (!ss2k->externalControl) { if ((rtConfig->getFTMSMode() == FitnessMachineControlPointProcedure::SetTargetPower)) { + #ifdef ERG_GUARDRAILS // don't drive lower out of bounds. This is a final test that should never happen. if ((stepper->getCurrentPosition() > rtConfig->getTargetIncline()) && (rtConfig->watts.getValue() < rtConfig->watts.getTarget())) { rtConfig->setTargetIncline(stepper->getCurrentPosition() + 1); @@ -413,6 +414,7 @@ void SS2K::moveStepper() { if ((stepper->getCurrentPosition() < rtConfig->getTargetIncline()) && (rtConfig->watts.getValue() > rtConfig->watts.getTarget())) { rtConfig->setTargetIncline(stepper->getCurrentPosition() - 1); } + #endif ss2k->targetPosition = rtConfig->getTargetIncline(); } else if (rtConfig->getFTMSMode() == FitnessMachineControlPointProcedure::SetTargetResistanceLevel) { rtConfig->setTargetIncline(ss2k->currentPosition + ((rtConfig->resistance.getTarget() - rtConfig->resistance.getValue()) * 20)); From 64a8da11d30c891a5bfb3cf48e9cd888200a75c1 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Wed, 15 Jan 2025 20:47:17 -0600 Subject: [PATCH 018/451] added calculation when homed --- src/ERG_Mode.cpp | 126 ++++++++++++++++++++++++++--------------------- 1 file changed, 71 insertions(+), 55 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index a2ede3d8..1edbe1a0 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -110,17 +110,32 @@ int PowerBuffer::getReadings() { } void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, Measurement watts) { //this basically checks the constaraints and if everything is good it adds it into the powerbuffer. no need to change + static int calcStep; + if ((cadence >= (MINIMUM_TABLE_CAD - (POWERTABLE_CAD_INCREMENT / 2))) && (cadence <= (MINIMUM_TABLE_CAD + (POWERTABLE_CAD_INCREMENT * POWERTABLE_CAD_SIZE) - (POWERTABLE_CAD_SIZE / 2))) && (watts.getValue() > 10) && //adding constraints (watts.getValue() < (POWERTABLE_WATT_SIZE * POWERTABLE_WATT_INCREMENT))) { + + /*if(rtConfig->getMaxStep() == DEFAULT_STEPPER_TRAVEL && rtConfig->getMinStep() == -DEFAULT_STEPPER_TRAVEL){ + int totalStep = ((rtConfig->getMaxStep() - rtConfig->getMinStep()) / 10000); //this would get us 4000 if it was the default stepper distance. only if were using a resistance bike + SS2K_LOG(POWERTABLE_LOG_TAG, "totalStep: %d", totalStep); //so it would be 400 + calcStep = totalStep * 0.05; //if it is default stepper position it would be 20 + SS2K_LOG(POWERTABLE_LOG_TAG, "calcStep: %d", calcStep) // would be 20 + }*/ + if (rtConfig->getHomed()){ + int totalStep = (rtConfig->getMaxStep() / 100); //maxStep should be around 22000 / 100 gives us 200ish + calcStep = totalStep * 0.05; // 5% of that would give us around a 10 range + } + if (powerBuffer.powerEntry[0].readings == 0) { // Take Initial reading powerBuffer.set(0); - // Check that reading is within 1/2 of the initial reading - } else if ((abs(powerBuffer.powerEntry[0].watts - watts.getValue()) < (POWERTABLE_WATT_INCREMENT / 2)) && - (abs(powerBuffer.powerEntry[0].cad - cadence) < (POWERTABLE_CAD_INCREMENT))) { + // Check if the current stepper posistion is within a 5% range of the previous stepper position + } else if (((ss2k->getCurrentPosition()/100) >= (powerBuffer.powerEntry[0].targetPosition - calcStep)) && + ((ss2k->getCurrentPosition()/100) <= (powerBuffer.powerEntry[0].targetPosition + calcStep))) { for (int i = 1; i < POWER_SAMPLES; i++) { if (powerBuffer.powerEntry[i].readings == 0) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Success!"); powerBuffer.set(i); // Add additional readings to the buffer. break; } @@ -505,7 +520,6 @@ void PowerTable::extrapFillTable() { (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue); } } } else if (right + 1 < POWERTABLE_WATT_SIZE) { @@ -516,7 +530,6 @@ void PowerTable::extrapFillTable() { (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue); } } } @@ -570,7 +583,6 @@ void PowerTable::extrapFillTable() { (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted Avg: %f", tempValue); } } } else if (right + 1 < POWERTABLE_WATT_SIZE) { @@ -647,62 +659,66 @@ void PowerTable::extrapFillTable() { void PowerTable::extrapolateDiagonal() { int tempValue = INT16_MIN; -for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - std::vector> isNeighbor; - std::vector weights; - int weightSum = 0; - - //looks at all surrounding cells - for (int row = -1; row <= 1; ++row) { //checks top and bottom - for (int col = -1; col <= 1; ++col) { // checks right and left - int rowPosition = i + row; - int colPosition = j + col; - - // make sure the vald neighbor is within the range - if (rowPosition >= 0 && rowPosition < POWERTABLE_CAD_SIZE && colPosition >= 0 && colPosition < POWERTABLE_WATT_SIZE && (row != 0 || col != 0) && this->tableRow[rowPosition].tableEntry[colPosition].targetPosition != INT16_MIN) { - - //calculate the weight or distance between the two valid neighbors - int dist = abs(row) + abs(col); - int weight; - if(dist > 0){ - weight = 1 / dist; // 1 / dist ratio, smaller the farther it is - SS2K_LOG(POWERTABLE_LOG_TAG, "Weight (distance): %f", weight) - } else { - weight = 1; - SS2K_LOG(POWERTABLE_LOG_TAG, "No distance.") - } - - // store the data - isNeighbor.push_back({rowPosition, colPosition}); - weights.push_back(weight); - weightSum += weight; - } - } - } + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest top-left non-empty cell + int topLeftRow = i - 1, topLeftCol = j - 1; + while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { + topLeftRow--; + topLeftCol--; + } + + // Find nearest bottom-right non-empty cell + int bottomRightRow = i + 1, bottomRightCol = j + 1; + while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && + this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { + bottomRightRow++; + bottomRightCol++; + } + + // Perform diagonal extrapolation (top-left to bottom-right) + if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { + tempValue = + this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + + ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / + (bottomRightCol - topLeftCol); - // If we have neightbors we can calculate a weighted average - if (!isNeighbor.empty()) { - int weightedSum = 0; + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + + // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left + if (tempValue == INT16_MIN) { + // Find nearest top-right non-empty cell + int topRightRow = i - 1, topRightCol = j + 1; + while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { + topRightRow--; + topRightCol++; + } - for (size_t i = 0; i < isNeighbor.size(); ++i) { - int x = isNeighbor[i].first; - int y = isNeighbor[i].second; - int neighborValue = this->tableRow[x].tableEntry[y].targetPosition; - weightedSum += neighborValue * weights[i]; - } + // Find nearest bottom-left non-empty cell + int bottomLeftRow = i + 1, bottomLeftCol = j - 1; + while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { + bottomLeftRow++; + bottomLeftCol--; + } - // get the value to store inside the cell - tempValue = weightedSum / weightSum; + // Perform diagonal extrapolation (top-right to bottom-left) + if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { + tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + + ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * + (j - bottomLeftCol)) / + (topRightCol - bottomLeftCol); - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - SS2K_LOG(POWERTABLE_LOG_TAG, "Weighted avg: %f", tempValue) - } + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } + } } - } + } + } } } From 0bdb0926d9b8ed197bebf934ccf36e7909d26f0c Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Thu, 16 Jan 2025 13:44:19 -0600 Subject: [PATCH 019/451] brought the ERGSensitivity setting (Kp) so it fits better with the current defaults. --- src/ERG_Mode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 55ecf7e3..cecaf661 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -1199,7 +1199,7 @@ void ErgMode::_setPointChangeState(int newCadence, Measurement& newWatts) { // PrevError void ErgMode::_inSetpointState(int newCadence, Measurement& newWatts) { // Setting Gains For PID Loop - float Kp = userConfig->getERGSensitivity(); + float Kp = userConfig->getERGSensitivity()*2; float Ki = 0.1; float Kd = 0.1; From 5b0326d51514be21b7295b85c5451cff8a42ae29 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Sun, 19 Jan 2025 19:44:16 -0600 Subject: [PATCH 020/451] cleaned up code (still need to solve non-homing problem) --- src/ERG_Mode.cpp | 37 +++++++++++++++++-------------------- src/Main.cpp | 2 +- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 1edbe1a0..f5ebf66c 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -110,29 +110,26 @@ int PowerBuffer::getReadings() { } void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, Measurement watts) { //this basically checks the constaraints and if everything is good it adds it into the powerbuffer. no need to change - static int calcStep; - + static int calcStep; //calcStep is the percentage range of the stepper motor + if ((cadence >= (MINIMUM_TABLE_CAD - (POWERTABLE_CAD_INCREMENT / 2))) && (cadence <= (MINIMUM_TABLE_CAD + (POWERTABLE_CAD_INCREMENT * POWERTABLE_CAD_SIZE) - (POWERTABLE_CAD_SIZE / 2))) && (watts.getValue() > 10) && //adding constraints (watts.getValue() < (POWERTABLE_WATT_SIZE * POWERTABLE_WATT_INCREMENT))) { - /*if(rtConfig->getMaxStep() == DEFAULT_STEPPER_TRAVEL && rtConfig->getMinStep() == -DEFAULT_STEPPER_TRAVEL){ - int totalStep = ((rtConfig->getMaxStep() - rtConfig->getMinStep()) / 10000); //this would get us 4000 if it was the default stepper distance. only if were using a resistance bike - SS2K_LOG(POWERTABLE_LOG_TAG, "totalStep: %d", totalStep); //so it would be 400 - calcStep = totalStep * 0.05; //if it is default stepper position it would be 20 - SS2K_LOG(POWERTABLE_LOG_TAG, "calcStep: %d", calcStep) // would be 20 - }*/ - if (rtConfig->getHomed()){ + if(rtConfig->getMaxStep() == DEFAULT_STEPPER_TRAVEL && rtConfig->getMinStep() == 0){ + int totalStep = ((rtConfig->getMaxStep() / 1000000)); //stepper distance is 400,000,000 so dividing it by 2,000,000 gives us 200 + calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range + } else if (rtConfig->getHomed()){ int totalStep = (rtConfig->getMaxStep() / 100); //maxStep should be around 22000 / 100 gives us 200ish - calcStep = totalStep * 0.05; // 5% of that would give us around a 10 range + calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range } - if (powerBuffer.powerEntry[0].readings == 0) { + if (powerBuffer.powerEntry[0].readings == 0) { //we need to make sure stepper position is not negative so it only takes positive resistance values // Take Initial reading powerBuffer.set(0); - // Check if the current stepper posistion is within a 5% range of the previous stepper position - } else if (((ss2k->getCurrentPosition()/100) >= (powerBuffer.powerEntry[0].targetPosition - calcStep)) && - ((ss2k->getCurrentPosition()/100) <= (powerBuffer.powerEntry[0].targetPosition + calcStep))) { + // Check if the current stepper posistion is within a 5% range of the previous stepper position and that the current position is not negative + } if (((ss2k->getCurrentPosition()/100) >= ((powerBuffer.powerEntry[0].targetPosition) - calcStep)) && + ((ss2k->getCurrentPosition()/100) <= ((powerBuffer.powerEntry[0].targetPosition) + calcStep))) { for (int i = 1; i < POWER_SAMPLES; i++) { if (powerBuffer.powerEntry[i].readings == 0) { SS2K_LOG(POWERTABLE_LOG_TAG, "Success!"); @@ -145,8 +142,8 @@ void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, Measur this->toLog(); this->_manageSaveState(); powerBuffer.reset(); - } - } else { // Reading was outside the range - clear the buffer and start over. + } + } else { // Reading was outside the range - clear the buffer and start over. powerBuffer.reset(); } } @@ -464,7 +461,7 @@ void PowerTable::fillTable() { void PowerTable::extrapFillTable() { // Find the center of the known data - int sumRow = 0, sumCol = 0, count = 0; + /*int sumRow = 0, sumCol = 0, count = 0; for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { @@ -653,11 +650,11 @@ void PowerTable::extrapFillTable() { } } } - } + }*/ } void PowerTable::extrapolateDiagonal() { - int tempValue = INT16_MIN; + /*int tempValue = INT16_MIN; for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { @@ -719,7 +716,7 @@ void PowerTable::extrapolateDiagonal() { } } } - } + }*/ } int PowerTable::getNumEntries() { diff --git a/src/Main.cpp b/src/Main.cpp index b495a40b..b26dc163 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -678,7 +678,7 @@ void SS2K::updateStepperSpeed(int speed) { if (speed == 0) { speed = userConfig->getStepperSpeed(); } - SS2K_LOG(MAIN_LOG_TAG, "StepperSpeed is now %d", speed); + //SS2K_LOG(MAIN_LOG_TAG, "StepperSpeed is now %d", speed); stepper->setSpeedInHz(speed); } From 0f0f24098e48a3daba8fe8f624fcb6a99a2cdc8c Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Mon, 20 Jan 2025 19:21:48 -0600 Subject: [PATCH 021/451] testing for setstepperMinMax --- lib/SS2K/src/sensors/PelotonData.cpp | 4 ++-- src/ERG_Mode.cpp | 4 ++-- src/Main.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/SS2K/src/sensors/PelotonData.cpp b/lib/SS2K/src/sensors/PelotonData.cpp index 57c6099e..fdb73f3e 100644 --- a/lib/SS2K/src/sensors/PelotonData.cpp +++ b/lib/SS2K/src/sensors/PelotonData.cpp @@ -61,8 +61,8 @@ void PelotonData::decode(uint8_t *data, size_t length) { break; case PELOTON_RES_ID: - resistance = value; - receivedResistance = true; + //resistance = value; + //receivedResistance = true; break; case PELOTON_RES_ID2: diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index f5ebf66c..8fabbb64 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -116,8 +116,8 @@ void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, Measur (cadence <= (MINIMUM_TABLE_CAD + (POWERTABLE_CAD_INCREMENT * POWERTABLE_CAD_SIZE) - (POWERTABLE_CAD_SIZE / 2))) && (watts.getValue() > 10) && //adding constraints (watts.getValue() < (POWERTABLE_WATT_SIZE * POWERTABLE_WATT_INCREMENT))) { - if(rtConfig->getMaxStep() == DEFAULT_STEPPER_TRAVEL && rtConfig->getMinStep() == 0){ - int totalStep = ((rtConfig->getMaxStep() / 1000000)); //stepper distance is 400,000,000 so dividing it by 2,000,000 gives us 200 + if(rtConfig->getMaxStep() == DEFAULT_STEPPER_TRAVEL && rtConfig->getMinStep() == -DEFAULT_STEPPER_TRAVEL){ + int totalStep = ((rtConfig->getMaxStep() - rtConfig->getMaxStep() / 2000000)); //stepper distance is 400,000,000 so dividing it by 2,000,000 gives us 200 calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range } else if (rtConfig->getHomed()){ int totalStep = (rtConfig->getMaxStep() / 100); //maxStep should be around 22000 / 100 gives us 200ish diff --git a/src/Main.cpp b/src/Main.cpp index b26dc163..91e9dede 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -744,14 +744,14 @@ void SS2K::txSerial() { // Serial.printf(" Before TX "); } void SS2K::pelotonConnected() { - txCheck = TX_CHECK_INTERVAL; + /*txCheck = TX_CHECK_INTERVAL; if (rtConfig->resistance.getValue() > 0) { rtConfig->setMinResistance(MIN_PELOTON_RESISTANCE); rtConfig->setMaxResistance(MAX_PELOTON_RESISTANCE); } else { rtConfig->setMinResistance(-DEFAULT_RESISTANCE_RANGE); rtConfig->setMaxResistance(DEFAULT_RESISTANCE_RANGE); - } + }*/ } void SS2K::rxSerial(void) { From 1127f219c63b3db7465235ef690c6a23539e5d92 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Mon, 20 Jan 2025 20:16:35 -0600 Subject: [PATCH 022/451] uncommented out situations where peleton was detected --- lib/SS2K/src/sensors/PelotonData.cpp | 4 ++-- src/Main.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/SS2K/src/sensors/PelotonData.cpp b/lib/SS2K/src/sensors/PelotonData.cpp index fdb73f3e..57c6099e 100644 --- a/lib/SS2K/src/sensors/PelotonData.cpp +++ b/lib/SS2K/src/sensors/PelotonData.cpp @@ -61,8 +61,8 @@ void PelotonData::decode(uint8_t *data, size_t length) { break; case PELOTON_RES_ID: - //resistance = value; - //receivedResistance = true; + resistance = value; + receivedResistance = true; break; case PELOTON_RES_ID2: diff --git a/src/Main.cpp b/src/Main.cpp index 91e9dede..b26dc163 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -744,14 +744,14 @@ void SS2K::txSerial() { // Serial.printf(" Before TX "); } void SS2K::pelotonConnected() { - /*txCheck = TX_CHECK_INTERVAL; + txCheck = TX_CHECK_INTERVAL; if (rtConfig->resistance.getValue() > 0) { rtConfig->setMinResistance(MIN_PELOTON_RESISTANCE); rtConfig->setMaxResistance(MAX_PELOTON_RESISTANCE); } else { rtConfig->setMinResistance(-DEFAULT_RESISTANCE_RANGE); rtConfig->setMaxResistance(DEFAULT_RESISTANCE_RANGE); - }*/ + } } void SS2K::rxSerial(void) { From d3f8b3cdc3f12571bed32bdf291969365d8c758d Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Mon, 20 Jan 2025 22:25:36 -0600 Subject: [PATCH 023/451] forgot to uncomment out fill functions for powertable --- src/ERG_Mode.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 8fabbb64..6ee5cd9c 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -461,7 +461,7 @@ void PowerTable::fillTable() { void PowerTable::extrapFillTable() { // Find the center of the known data - /*int sumRow = 0, sumCol = 0, count = 0; + int sumRow = 0, sumCol = 0, count = 0; for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { @@ -650,11 +650,11 @@ void PowerTable::extrapFillTable() { } } } - }*/ + } } void PowerTable::extrapolateDiagonal() { - /*int tempValue = INT16_MIN; + int tempValue = INT16_MIN; for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { @@ -716,7 +716,7 @@ void PowerTable::extrapolateDiagonal() { } } } - }*/ + } } int PowerTable::getNumEntries() { From be7eeaa76ee7d2287f6dfb8f21c560ca6bd32dc2 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 21 Jan 2025 18:50:27 -0600 Subject: [PATCH 024/451] latest --- src/BLE_Client.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index eac8a9bf..6d5f65fa 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -46,7 +46,7 @@ void SpinBLEClient::start() { pBLEScan->setActiveScan(true); } -static void notifyCB(NimBLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t *pData, size_t length, bool isNotify) { +void notifyCB(NimBLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t *pData, size_t length, bool isNotify) { // Parse BLE shifter info. if (pBLERemoteCharacteristic->getRemoteService()->getUUID() == HID_SERVICE_UUID) { Serial.print(pData[0], HEX); From 2c8508f6ce172700d75a6eec2cf8d30e16224183 Mon Sep 17 00:00:00 2001 From: ddtomic Date: Tue, 21 Jan 2025 19:18:53 -0600 Subject: [PATCH 025/451] clamping down integral term --- src/ERG_Mode.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index ea47e36e..95ce3c4d 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -1191,11 +1191,10 @@ void ErgMode::_setPointChangeState(int newCadence, Measurement& newWatts) { // PrevError void ErgMode::_inSetpointState(int newCadence, Measurement& newWatts) { // Setting Gains For PID Loop - float Kp = 0.1; + float Kp = userConfig->getERGSensitivity(); float Ki = 0.1; float Kd = 0.1; - // initialize, may need to double check it's not resetting every time static float integral = 0.0; static float prevError = 0.0; @@ -1213,7 +1212,15 @@ void ErgMode::_inSetpointState(int newCadence, Measurement& newWatts) { integral += error; float integralFinal = Ki * integral; - // NEED TO GO BACK AND CLAMP DOWN INTEGRAL TO PREVENT IT FROM BEING TOO LARGE + // Clamping down integral term + float integralMax = 60; + float integralMin = -60; + + if (integral > integralMax) { + integral = integralMax; + } else if (integral < integralMin) { + integral = integralMin; + } // Defining derivative term float derivative = error - prevError; // Difference between current and previous errors From d7073faa30c61027cdd60fae291e9a5685d27659 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 21 Jan 2025 20:42:34 -0600 Subject: [PATCH 026/451] getting closer --- platformio.ini | 4 ++-- src/BLE_Client.cpp | 59 +++++++++++++++++++++++++++++++--------------- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/platformio.ini b/platformio.ini index 4ebdea8b..37bbb775 100644 --- a/platformio.ini +++ b/platformio.ini @@ -26,11 +26,11 @@ build_flags = !python build_date_macro.py -D CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 -D CONFIG_MDNS_STRICT_MODE=1 - -D CORE_DEBUG_LEVEL=5 + -D CORE_DEBUG_LEVEL=1 -D ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=3500 -std=gnu++17 lib_deps = - https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.1.3.zip + https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.2.0.zip https://github.com/teemuatlut/TMCStepper/archive/refs/tags/v0.7.3.zip https://github.com/bblanchon/ArduinoJson/archive/refs/tags/v6.20.0.zip https://github.com/gin66/FastAccelStepper/archive/refs/tags/0.31.2.zip diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index 66d84405..a123d1e5 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -67,14 +67,32 @@ void notifyCB(NimBLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t *pDa } } -void testnotifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify) { - std::string str = (isNotify == true) ? "Notification" : "Indication"; - str += " from "; - str += pRemoteCharacteristic->getClient()->getPeerAddress().toString(); - str += ": Service = " + pRemoteCharacteristic->getRemoteService()->getUUID().toString(); - str += ", Characteristic = " + pRemoteCharacteristic->getUUID().toString(); - str += ", Value = " + std::string((char*)pData, length); - Serial.printf("%s\n", str.c_str()); +void subscribeToAllNotifications(NimBLEClient* pClient) { + if(!pClient || !pClient->isConnected()) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Client not connected for notifications"); + return; + } + + for(const auto& service : BLEServices::SUPPORTED_SERVICES) { + NimBLERemoteService* pSvc = pClient->getService(service.serviceUUID); + if(pSvc) { + for(const auto& pChr : pSvc->getCharacteristics()) { + if(pChr) { + if(pChr->canNotify() || pChr->canIndicate()) { + if(pChr->subscribe(true, notifyCB)) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Subscribed to %s %s", + service.name.c_str(), + pChr->getUUID().toString().c_str()); + } else { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to subscribe to %s %s", + service.name.c_str(), + pChr->getUUID().toString().c_str()); + } + } + } + } + } + } } // BLE Client loop task. @@ -284,7 +302,7 @@ bool SpinBLEClient::connectToServer() { pChr = pSvc->getCharacteristic(charUUID); if (pChr) { /** make sure it's not null */ - if (pChr->canRead()) { +/* if (pChr->canRead()) { NimBLEAttValue value = pChr->readValue(); const int kLogBufMaxLength = 250; char logBuf[kLogBufMaxLength]; @@ -293,9 +311,9 @@ bool SpinBLEClient::connectToServer() { SS2K_LOG(BLE_COMMON_LOG_TAG, "%s", logBuf); } if (pChr->canNotify()) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Setting up notifications for service %s char %s, handle %d", serviceUUID.toString().c_str(), charUUID.toString().c_str(), pChr->getHandle()); - if (!pChr->subscribe(true, testnotifyCB)) { - /** Disconnect if subscribe failed */ + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Setting up notifications for service %s char %s, handle %d", serviceUUID.toString().c_str(), pChr->getUUID().toString().c_str(), pChr->getHandle()); + if (!pChr->subscribe(true, notifyCB)) { + /** Disconnect if subscribe failed *//* SS2K_LOG(BLE_CLIENT_LOG_TAG, "Notifications Failed for %s", pClient->getPeerAddress().toString().c_str()); spinBLEClient.myBLEDevices[device_number].reset(); pClient->deleteServices(); @@ -305,10 +323,10 @@ bool SpinBLEClient::connectToServer() { } SS2K_LOG(BLE_CLIENT_LOG_TAG, "Notifications Subscribed for %s, UUID %s", pClient->getPeerAddress().toString().c_str(), pChr->getUUID().toString().c_str()); } else if (pChr->canIndicate()) { - /** Send false as first argument to subscribe to indications instead of notifications */ + /** Send false as first argument to subscribe to indications instead of notifications if (!pChr->subscribe(false, notifyCB)) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Indications Failed for %s", pClient->getPeerAddress().toString().c_str()); - /** Disconnect if subscribe failed */ + /** Disconnect if subscribe failed spinBLEClient.myBLEDevices[device_number].reset(); pClient->deleteServices(); NimBLEDevice::getScan()->erase(pClient->getPeerAddress()); @@ -316,7 +334,8 @@ bool SpinBLEClient::connectToServer() { return false; } SS2K_LOG(BLE_CLIENT_LOG_TAG, "Indications Subscribed for %s", pClient->getPeerAddress().toString().c_str()); - } + } */ + subscribeToAllNotifications(pClient); this->reconnectTries = MAX_RECONNECT_TRIES; SS2K_LOG(BLE_CLIENT_LOG_TAG, "Successful %s subscription.", pChr->getUUID().toString().c_str()); spinBLEClient.myBLEDevices[device_number].doConnect = false; @@ -615,7 +634,9 @@ void SpinBLEClient::postConnect() { for (auto &_BLEd : spinBLEClient.myBLEDevices) { // Check that the device has been assigned and it hasn't been post connected. if ((_BLEd.connectedClientID != BLE_HS_CONN_HANDLE_NONE) && !_BLEd.getPostConnected()) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Post connecting: %s , ConnID %d", _BLEd.peerAddress.toString().c_str(), _BLEd.connectedClientID); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Post connecting: %s , ConnID %d, PrimaryChar %s", _BLEd.peerAddress.toString().c_str(), _BLEd.connectedClientID, _BLEd.charUUID.toString().c_str()); + //auto testCharactreristic = NimBLEDevice::getClientByPeerAddress(_BLEd.peerAddress)->getService(CYCLINGPOWERSERVICE_UUID)->getCharacteristic(CYCLINGPOWERMEASUREMENT_UUID); + //testCharactreristic->subscribe(true, notifyCB); if (NimBLEDevice::getClientByPeerAddress(_BLEd.peerAddress)) { _BLEd.setPostConnected(true); NimBLEClient *pClient = NimBLEDevice::getClientByPeerAddress(_BLEd.peerAddress); @@ -636,7 +657,7 @@ void SpinBLEClient::postConnect() { if ((_BLEd.charUUID == FITNESSMACHINEINDOORBIKEDATA_UUID)) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Updating Connection Params for: %s", _BLEd.peerAddress.toString().c_str()); - BLEDevice::getServer()->updateConnParams(pClient->getConnId(), 100, 100, 2, 1000); + BLEDevice::getServer()->updateConnParams(pClient->getConnHandle(), 100, 100, 2, 1000); spinBLEClient.handleBattInfo(pClient, true); auto featuresCharacteristic = pClient->getService(FITNESSMACHINESERVICE_UUID)->getCharacteristic(FITNESSMACHINEFEATURE_UUID); @@ -775,11 +796,11 @@ void SpinBLEClient::connectBLE_HID(NimBLEClient *pClient) { if (it->canNotify()) { if (!it->subscribe(true, notifyCB)) { /** Disconnect if subscribe failed */ - Serial.println("subscribe notification failed"); + Serial.println("HID subscribe notification failed"); NimBLEDevice::deleteClient(pClient); return; // false; } else { - Serial.println("subscribed"); + Serial.println("subscribed to HID"); } } } From 51facd21e3172de9df2c351acfd3dd31ba6f75ad Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 21 Jan 2025 21:59:45 -0600 Subject: [PATCH 027/451] Incoming Cadence is working --- include/BLE_Common.h | 64 +++++++++++------------ src/BLE_Client.cpp | 122 ++++++++++++++----------------------------- src/BLE_Common.cpp | 56 ++++++++++---------- 3 files changed, 97 insertions(+), 145 deletions(-) diff --git a/include/BLE_Common.h b/include/BLE_Common.h index c0fbb3d5..80aa62e7 100644 --- a/include/BLE_Common.h +++ b/include/BLE_Common.h @@ -21,21 +21,19 @@ // Vector of supported BLE services and their corresponding characteristic UUIDs struct BLEServiceInfo { - BLEUUID serviceUUID; - BLEUUID characteristicUUID; - String name; + BLEUUID serviceUUID; + BLEUUID characteristicUUID; + String name; }; namespace BLEServices { - const std::vector SUPPORTED_SERVICES = { - {CYCLINGPOWERSERVICE_UUID, CYCLINGPOWERMEASUREMENT_UUID, "Cycling Power Service"}, - {CSCSERVICE_UUID, CSCMEASUREMENT_UUID, "Cycling Speed And Cadence Service"}, - {HEARTSERVICE_UUID, HEARTCHARACTERISTIC_UUID, "Heart Rate Service"}, - {FITNESSMACHINESERVICE_UUID, FITNESSMACHINEINDOORBIKEDATA_UUID, "Fitness Machine Service"}, - {HID_SERVICE_UUID, HID_REPORT_DATA_UUID, "HID Service"}, - {ECHELON_SERVICE_UUID, ECHELON_DATA_UUID, "Echelon Service"}, - {FLYWHEEL_UART_SERVICE_UUID, FLYWHEEL_UART_TX_UUID, "Flywheel UART Service"} - }; +const std::vector SUPPORTED_SERVICES = {{CYCLINGPOWERSERVICE_UUID, CYCLINGPOWERMEASUREMENT_UUID, "Cycling Power Service"}, + {CSCSERVICE_UUID, CSCMEASUREMENT_UUID, "Cycling Speed And Cadence Service"}, + {HEARTSERVICE_UUID, HEARTCHARACTERISTIC_UUID, "Heart Rate Service"}, + {FITNESSMACHINESERVICE_UUID, FITNESSMACHINEINDOORBIKEDATA_UUID, "Fitness Machine Service"}, + {HID_SERVICE_UUID, HID_REPORT_DATA_UUID, "HID Service"}, + {ECHELON_SERVICE_UUID, ECHELON_DATA_UUID, "Echelon Service"}, + {FLYWHEEL_UART_SERVICE_UUID, FLYWHEEL_UART_TX_UUID, "Flywheel UART Service"}}; } using BLEServices::SUPPORTED_SERVICES; @@ -88,8 +86,8 @@ class SpinBLEServer { bool IndoorBikeData : 1; bool CyclingSpeedCadence : 1; } clientSubscribed; - int spinDownFlag = 0; - NimBLEServer *pServer = nullptr; + int spinDownFlag = 0; + NimBLEServer* pServer = nullptr; void setClientSubscribed(NimBLEUUID pUUID, bool subscribe); void notifyShift(); double calculateSpeed(); @@ -111,8 +109,8 @@ extern SpinBLEServer spinBLEServer; extern BLE_Wattbike_Service wattbikeService; void startBLEServer(); -void logCharacteristic(char *buffer, const size_t bufferCapacity, const byte *data, const size_t dataLength, const NimBLEUUID serviceUUID, const NimBLEUUID charUUID, - const char *format, ...); +void logCharacteristic(char* buffer, const size_t bufferCapacity, const byte* data, const size_t dataLength, const NimBLEUUID serviceUUID, const NimBLEUUID charUUID, + const char* format, ...); void calculateInstPwrFromHR(); int connectedClientCount(); @@ -123,7 +121,7 @@ void BLEFirmwareSetup(); // Keeping the task outside the class so we don't need a mask. // We're only going to run one anyway. -void bleClientTask(void *pvParameters); +void bleClientTask(void* pvParameters); // UUID's the client has methods for // BLEUUID serviceUUIDs[4] = {FITNESSMACHINESERVICE_UUID, @@ -133,6 +131,7 @@ void bleClientTask(void *pvParameters); // FLYWHEEL_UART_TX_UUID}; typedef struct NotifyData { + NimBLEUUID serviceUUID; NimBLEUUID charUUID; uint8_t data[25]; size_t length; @@ -155,7 +154,7 @@ class SpinBLEAdvertisedDevice { // } // } - const NimBLEAdvertisedDevice *advertisedDevice = nullptr; + const NimBLEAdvertisedDevice* advertisedDevice = nullptr; NimBLEAddress peerAddress; int connectedClientID = BLE_HS_CONN_HANDLE_NONE; @@ -169,10 +168,10 @@ class SpinBLEAdvertisedDevice { bool doConnect = false; void setPostConnected(bool pc) { isPostConnected = pc; } bool getPostConnected() { return isPostConnected; } - void set(const NimBLEAdvertisedDevice *device, int id = BLE_HS_CONN_HANDLE_NONE, BLEUUID inServiceUUID = (uint16_t)0x0000, BLEUUID inCharUUID = (uint16_t)0x0000); + void set(const NimBLEAdvertisedDevice* device, int id = BLE_HS_CONN_HANDLE_NONE, BLEUUID inServiceUUID = (uint16_t)0x0000, BLEUUID inCharUUID = (uint16_t)0x0000); void reset(); void print(); - bool enqueueData(uint8_t data[25], size_t length, NimBLEUUID charUUID); + bool enqueueData(uint8_t data[25], size_t length, NimBLEUUID serviceUUID, NimBLEUUID charUUID); NotifyData dequeueData(); }; @@ -196,7 +195,7 @@ class SpinBLEClient { double cscLastWheelEvtTime = 0.0; int reconnectTries = MAX_RECONNECT_TRIES; - BLERemoteCharacteristic *pRemoteCharacteristic = nullptr; + BLERemoteCharacteristic* pRemoteCharacteristic = nullptr; // BLEDevices myBLEDevices; SpinBLEAdvertisedDevice myBLEDevices[NUM_BLE_DEVICES]; @@ -206,27 +205,28 @@ class SpinBLEClient { bool connectToServer(); // Check for duplicate services of BLEClient and remove the previously // connected one. - void removeDuplicates(NimBLEClient *pClient); - void resetDevices(NimBLEClient *pClient); + void removeDuplicates(NimBLEClient* pClient); + void resetDevices(NimBLEClient* pClient); void postConnect(); - void FTMSControlPointWrite(const uint8_t *pData, int length); - void connectBLE_HID(NimBLEClient *pClient); - void keepAliveBLE_HID(NimBLEClient *pClient); - void handleBattInfo(NimBLEClient *pClient, bool updateNow); + void FTMSControlPointWrite(const uint8_t* pData, int length); + void connectBLE_HID(NimBLEClient* pClient); + void keepAliveBLE_HID(NimBLEClient* pClient); + void handleBattInfo(NimBLEClient* pClient, bool updateNow); // Instead of using this directly, set the .doScan flag to start a scan. void scanProcess(int duration = DEFAULT_SCAN_DURATION); void checkBLEReconnect(); // Disconnects all devices. They will then be reconnected if scanned and preferred again. void reconnectAllDevices(); - String adevName2UniqueName(const NimBLEAdvertisedDevice *inDev); + String adevName2UniqueName(const NimBLEAdvertisedDevice* inDev); }; class ScanCallbacks : public NimBLEScanCallbacks { -public: - void onResult(const NimBLEAdvertisedDevice* advertisedDevice) override; - void onScanEnd(const NimBLEScanResults& results, int reason) override; -private: + public: + void onResult(const NimBLEAdvertisedDevice* advertisedDevice) override; + void onScanEnd(const NimBLEScanResults& results, int reason) override; + + private: }; class MyClientCallback : public NimBLEClientCallbacks { diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index a123d1e5..d1659111 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -57,42 +57,37 @@ void notifyCB(NimBLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t *pDa rtConfig->setShifterPosition(rtConfig->getShifterPosition() - 1); } } - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Notification received from %s - Service UUID: %s", pBLERemoteCharacteristic->getRemoteService()->getClient()->getPeerAddress().toString().c_str(), - pBLERemoteCharacteristic->getRemoteService()->getUUID().toString().c_str()); // enqueue sensor data for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { if (pBLERemoteCharacteristic->getClient()->getPeerAddress() == spinBLEClient.myBLEDevices[i].peerAddress) { - spinBLEClient.myBLEDevices[i].enqueueData(pData, length, pBLERemoteCharacteristic->getUUID()); + spinBLEClient.myBLEDevices[i].enqueueData(pData, length, pBLERemoteCharacteristic->getRemoteService()->getUUID(), pBLERemoteCharacteristic->getUUID()); } } } -void subscribeToAllNotifications(NimBLEClient* pClient) { - if(!pClient || !pClient->isConnected()) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Client not connected for notifications"); - return; - } - - for(const auto& service : BLEServices::SUPPORTED_SERVICES) { - NimBLERemoteService* pSvc = pClient->getService(service.serviceUUID); - if(pSvc) { - for(const auto& pChr : pSvc->getCharacteristics()) { - if(pChr) { - if(pChr->canNotify() || pChr->canIndicate()) { - if(pChr->subscribe(true, notifyCB)) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Subscribed to %s %s", - service.name.c_str(), - pChr->getUUID().toString().c_str()); - } else { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to subscribe to %s %s", - service.name.c_str(), - pChr->getUUID().toString().c_str()); - } - } - } +void subscribeToAllNotifications(NimBLEClient *pClient) { + if (!pClient || !pClient->isConnected()) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Client not connected for notifications"); + return; + } + for (const auto &service : BLEServices::SUPPORTED_SERVICES) { + NimBLERemoteService *pSvc = pClient->getService(service.serviceUUID); + if (pSvc) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Found %s", service.name.c_str()); + for (const auto &pChr : pSvc->getCharacteristics(true)) { + if (pChr) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Found %s, %s", service.serviceUUID.toString().c_str(), pChr->getUUID().toString().c_str()); + if (pChr->canNotify() || pChr->canIndicate()) { + if (pChr->subscribe(true, notifyCB)) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Subscribed to %s %s", service.name.c_str(), pChr->getUUID().toString().c_str()); + } else { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to subscribe to %s %s", service.name.c_str(), pChr->getUUID().toString().c_str()); } + } } + } } + } } // BLE Client loop task. @@ -293,62 +288,20 @@ bool SpinBLEClient::connectToServer() { } /** Now we can read/write/subscribe the characteristics of the services we are interested in */ - NimBLERemoteService *pSvc = nullptr; - NimBLERemoteCharacteristic *pChr = nullptr; - NimBLERemoteDescriptor *pDsc = nullptr; + NimBLERemoteService *pSvc = nullptr; pSvc = pClient->getService(serviceUUID); if (pSvc) { /** make sure it's not null */ - pChr = pSvc->getCharacteristic(charUUID); - - if (pChr) { /** make sure it's not null */ -/* if (pChr->canRead()) { - NimBLEAttValue value = pChr->readValue(); - const int kLogBufMaxLength = 250; - char logBuf[kLogBufMaxLength]; - int logBufLength = ss2k_log_hex_to_buffer(value.data(), value.length(), logBuf, 0, kLogBufMaxLength); - logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " <-initial Value"); - SS2K_LOG(BLE_COMMON_LOG_TAG, "%s", logBuf); - } - if (pChr->canNotify()) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Setting up notifications for service %s char %s, handle %d", serviceUUID.toString().c_str(), pChr->getUUID().toString().c_str(), pChr->getHandle()); - if (!pChr->subscribe(true, notifyCB)) { - /** Disconnect if subscribe failed *//* - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Notifications Failed for %s", pClient->getPeerAddress().toString().c_str()); - spinBLEClient.myBLEDevices[device_number].reset(); - pClient->deleteServices(); - NimBLEDevice::getScan()->erase(pClient->getPeerAddress()); - NimBLEDevice::deleteClient(pClient); - return false; - } - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Notifications Subscribed for %s, UUID %s", pClient->getPeerAddress().toString().c_str(), pChr->getUUID().toString().c_str()); - } else if (pChr->canIndicate()) { - /** Send false as first argument to subscribe to indications instead of notifications - if (!pChr->subscribe(false, notifyCB)) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Indications Failed for %s", pClient->getPeerAddress().toString().c_str()); - /** Disconnect if subscribe failed - spinBLEClient.myBLEDevices[device_number].reset(); - pClient->deleteServices(); - NimBLEDevice::getScan()->erase(pClient->getPeerAddress()); - NimBLEDevice::deleteClient(pClient); - return false; - } - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Indications Subscribed for %s", pClient->getPeerAddress().toString().c_str()); - } */ - subscribeToAllNotifications(pClient); - this->reconnectTries = MAX_RECONNECT_TRIES; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Successful %s subscription.", pChr->getUUID().toString().c_str()); - spinBLEClient.myBLEDevices[device_number].doConnect = false; - this->reconnectTries = MAX_RECONNECT_TRIES; - spinBLEClient.myBLEDevices[device_number].set(myDevice, pClient->getConnHandle(), serviceUUID, charUUID); - spinBLEClient.myBLEDevices[device_number].peerAddress = pClient->getPeerAddress(); - removeDuplicates(pClient); - } - + this->reconnectTries = MAX_RECONNECT_TRIES; + // SS2K_LOG(BLE_CLIENT_LOG_TAG, "Successful %s subscription.", pChr->getUUID().toString().c_str()); + spinBLEClient.myBLEDevices[device_number].doConnect = false; + this->reconnectTries = MAX_RECONNECT_TRIES; + spinBLEClient.myBLEDevices[device_number].set(myDevice, pClient->getConnHandle(), serviceUUID, charUUID); + spinBLEClient.myBLEDevices[device_number].peerAddress = pClient->getPeerAddress(); + removeDuplicates(pClient); } else { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to find service: %s", serviceUUID.toString().c_str()); } - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Device Connected"); return true; } @@ -634,12 +587,12 @@ void SpinBLEClient::postConnect() { for (auto &_BLEd : spinBLEClient.myBLEDevices) { // Check that the device has been assigned and it hasn't been post connected. if ((_BLEd.connectedClientID != BLE_HS_CONN_HANDLE_NONE) && !_BLEd.getPostConnected()) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Post connecting: %s , ConnID %d, PrimaryChar %s", _BLEd.peerAddress.toString().c_str(), _BLEd.connectedClientID, _BLEd.charUUID.toString().c_str()); - //auto testCharactreristic = NimBLEDevice::getClientByPeerAddress(_BLEd.peerAddress)->getService(CYCLINGPOWERSERVICE_UUID)->getCharacteristic(CYCLINGPOWERMEASUREMENT_UUID); - //testCharactreristic->subscribe(true, notifyCB); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Post connecting: %s , ConnID %d, PrimaryChar %s", _BLEd.peerAddress.toString().c_str(), _BLEd.connectedClientID, + _BLEd.charUUID.toString().c_str()); if (NimBLEDevice::getClientByPeerAddress(_BLEd.peerAddress)) { _BLEd.setPostConnected(true); NimBLEClient *pClient = NimBLEDevice::getClientByPeerAddress(_BLEd.peerAddress); + subscribeToAllNotifications(pClient); if (_BLEd.charUUID == ECHELON_DATA_UUID) { NimBLERemoteCharacteristic *writeCharacteristic = pClient->getService(ECHELON_SERVICE_UUID)->getCharacteristic(ECHELON_WRITE_UUID); if (writeCharacteristic == nullptr) { @@ -659,7 +612,7 @@ void SpinBLEClient::postConnect() { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Updating Connection Params for: %s", _BLEd.peerAddress.toString().c_str()); BLEDevice::getServer()->updateConnParams(pClient->getConnHandle(), 100, 100, 2, 1000); spinBLEClient.handleBattInfo(pClient, true); - + auto featuresCharacteristic = pClient->getService(FITNESSMACHINESERVICE_UUID)->getCharacteristic(FITNESSMACHINEFEATURE_UUID); if (featuresCharacteristic == nullptr) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to find FTMS features characteristic UUID: %s", FITNESSMACHINEFEATURE_UUID.toString().c_str()); @@ -680,7 +633,7 @@ void SpinBLEClient::postConnect() { return; } } - + NimBLERemoteCharacteristic *writeCharacteristic = pClient->getService(FITNESSMACHINESERVICE_UUID)->getCharacteristic(FITNESSMACHINECONTROLPOINT_UUID); if (writeCharacteristic == nullptr) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to find FTMS control characteristic UUID: %s", FITNESSMACHINECONTROLPOINT_UUID.toString().c_str()); @@ -701,7 +654,7 @@ void SpinBLEClient::postConnect() { } } -bool SpinBLEAdvertisedDevice::enqueueData(uint8_t *data, size_t length, NimBLEUUID charUUID) { +bool SpinBLEAdvertisedDevice::enqueueData(uint8_t *data, size_t length, NimBLEUUID serviceUUID, NimBLEUUID charUUID) { NotifyData notifyData; if (!uxQueueSpacesAvailable(this->dataBufferQueue)) { @@ -709,8 +662,9 @@ bool SpinBLEAdvertisedDevice::enqueueData(uint8_t *data, size_t length, NimBLEUU return pdFALSE; } - notifyData.length = length; - notifyData.charUUID = charUUID; + notifyData.length = length; + notifyData.charUUID = charUUID; + notifyData.serviceUUID = serviceUUID; for (size_t i = 0; i < length; i++) { notifyData.data[i] = data[i]; // Serial.printf("%02x ", notifyData.data[i]); diff --git a/src/BLE_Common.cpp b/src/BLE_Common.cpp index d24a2106..1ac54683 100644 --- a/src/BLE_Common.cpp +++ b/src/BLE_Common.cpp @@ -18,49 +18,46 @@ bool hr2p = false; const BLEServiceInfo* getDeviceServiceInfo(const NimBLEAdvertisedDevice* advertisedDevice, const String& deviceName) { - if (!advertisedDevice->haveServiceUUID()) { - return nullptr; - } + if (!advertisedDevice->haveServiceUUID()) { + return nullptr; + } - for (const auto& service : SUPPORTED_SERVICES) { - // Special case for Flywheel which requires name check - if (service.serviceUUID == FLYWHEEL_UART_SERVICE_UUID) { - if (advertisedDevice->isAdvertisingService(service.serviceUUID) && - deviceName == String(FLYWHEEL_BLE_NAME)) { - return &service; - } - } - // For all other services - else if (advertisedDevice->isAdvertisingService(service.serviceUUID)) { - return &service; - } + for (const auto& service : SUPPORTED_SERVICES) { + // Special case for Flywheel which requires name check + if (service.serviceUUID == FLYWHEEL_UART_SERVICE_UUID) { + if (advertisedDevice->isAdvertisingService(service.serviceUUID) && deviceName == String(FLYWHEEL_BLE_NAME)) { + return &service; + } } - - return nullptr; -} + // For all other services + else if (advertisedDevice->isAdvertisingService(service.serviceUUID)) { + return &service; + } + } -bool isDeviceSupported(const NimBLEAdvertisedDevice* advertisedDevice, const String& deviceName) { - return getDeviceServiceInfo(advertisedDevice, deviceName) != nullptr; + return nullptr; } +bool isDeviceSupported(const NimBLEAdvertisedDevice* advertisedDevice, const String& deviceName) { return getDeviceServiceInfo(advertisedDevice, deviceName) != nullptr; } + void BLECommunications() { static unsigned long int bleCommTimer = millis(); if (((millis() - bleCommTimer) > BLE_NOTIFY_DELAY) && !ss2k->isUpdating) { bleCommTimer = millis(); // **********************************Client*************************************** - for (auto &_BLEd : spinBLEClient.myBLEDevices) { // loop through discovered devices + for (auto& _BLEd : spinBLEClient.myBLEDevices) { // loop through discovered devices if (_BLEd.connectedClientID != BLE_HS_CONN_HANDLE_NONE) { - // SS2K_LOGW(BLE_COMMON_LOG_TAG, "Address: (%s) Client ID: (%d) SerUUID: (%s) CharUUID: (%s) HRM: (%s) PM: (%s) CSC: (%s) CT: (%s) doConnect: (%s) postConnect: (%s)", - // _BLEd.peerAddress.toString().c_str(), _BLEd.connectedClientID, _BLEd.serviceUUID.toString().c_str(), _BLEd.charUUID.toString().c_str(), - // _BLEd.isHRM ? "true" : "false", _BLEd.isPM ? "true" : "false", _BLEd.isCSC ? "true" : "false", _BLEd.isCT ? "true" : "false", _BLEd.doConnect ? "true" : "false", - // _BLEd.getPostConnected() ? "true" : "false"); + // SS2K_LOGW(BLE_COMMON_LOG_TAG, "Address: (%s) Client ID: (%d) SerUUID: (%s) CharUUID: (%s) HRM: (%s) PM: (%s) CSC: (%s) CT: (%s) doConnect: (%s) postConnect: (%s)", + // _BLEd.peerAddress.toString().c_str(), _BLEd.connectedClientID, _BLEd.serviceUUID.toString().c_str(), _BLEd.charUUID.toString().c_str(), + // _BLEd.isHRM ? "true" : "false", _BLEd.isPM ? "true" : "false", _BLEd.isCSC ? "true" : "false", _BLEd.isCT ? "true" : "false", _BLEd.doConnect ? "true" : + // "false", _BLEd.getPostConnected() ? "true" : "false"); if (_BLEd.advertisedDevice) { // is device registered? if ((_BLEd.connectedClientID != BLE_HS_CONN_HANDLE_NONE) && (_BLEd.doConnect == false)) { // client must not be in connection process if (BLEDevice::getClientByPeerAddress(_BLEd.peerAddress)) { // nullptr check - BLEClient *pClient = NimBLEDevice::getClientByPeerAddress(_BLEd.peerAddress); + BLEClient* pClient = NimBLEDevice::getClientByPeerAddress(_BLEd.peerAddress); // Client connected with a valid UUID registered if ((_BLEd.serviceUUID != BLEUUID((uint16_t)0x0000)) && (pClient->isConnected())) { - BLERemoteCharacteristic *pRemoteBLECharacteristic = pClient->getService(_BLEd.serviceUUID)->getCharacteristic(_BLEd.charUUID); + BLERemoteCharacteristic* pRemoteBLECharacteristic = pClient->getService(_BLEd.serviceUUID)->getCharacteristic(_BLEd.charUUID); // Handle BLE HID Remotes if (_BLEd.serviceUUID == HID_SERVICE_UUID) { @@ -80,13 +77,14 @@ void BLECommunications() { for (size_t i = 0; i < length; i++) { pData[i] = incomingNotifyData.data[i]; } - collectAndSet(pRemoteBLECharacteristic->getUUID(), _BLEd.serviceUUID, pRemoteBLECharacteristic->getRemoteService()->getClient()->getPeerAddress(), pData, length); + collectAndSet(incomingNotifyData.charUUID, incomingNotifyData.serviceUUID, pRemoteBLECharacteristic->getRemoteService()->getClient()->getPeerAddress(), pData, + length); } spinBLEClient.handleBattInfo(pClient, false); } else if (!pClient->isConnected()) { // This shouldn't ever be - // called... + // called... SS2K_LOG(BLE_COMMON_LOG_TAG, "Workaround connect"); _BLEd.doConnect = true; //} From defad9a19c597cb407f495de7eea710fd06f9d84 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Wed, 22 Jan 2025 04:04:17 +0000 Subject: [PATCH 028/451] Update changelog for version 25.1.10 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b5563ae..5abda86f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +### Changed + +### Hardware + + +## [25.1.10] + +### Added + ### Changed - Added checks for IC SE Bike Connection. From cfb76a184b8e0d837c45e89c1efd6a88cb483914 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 21 Jan 2025 22:28:59 -0600 Subject: [PATCH 029/451] Cadence zeros now --- lib/SS2K/include/sensors/CscSensorData.h | 1 + lib/SS2K/src/sensors/CscSensorData.cpp | 23 ++++++++++++++++++++--- src/BLE_Client.cpp | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/SS2K/include/sensors/CscSensorData.h b/lib/SS2K/include/sensors/CscSensorData.h index 86fe3245..20c72af1 100644 --- a/lib/SS2K/include/sensors/CscSensorData.h +++ b/lib/SS2K/include/sensors/CscSensorData.h @@ -32,4 +32,5 @@ class CscSensorData : public SensorData { uint32_t lastCrankEventTime = 0; uint32_t lastWheelRevolutions = 0; uint32_t lastCrankRevolutions = 0; + uint8_t missedReadingCount = 0; }; \ No newline at end of file diff --git a/lib/SS2K/src/sensors/CscSensorData.cpp b/lib/SS2K/src/sensors/CscSensorData.cpp index 1623c071..aaa1363b 100644 --- a/lib/SS2K/src/sensors/CscSensorData.cpp +++ b/lib/SS2K/src/sensors/CscSensorData.cpp @@ -72,15 +72,32 @@ void CscSensorData::decode(uint8_t *data, size_t length) { // Calculate cadence if we have previous measurements if (lastCrankEventTime > 0) { // Handle timer wraparound (16-bit timer) - uint16_t timeDiff = (crankEventTime >= lastCrankEventTime) ? - (crankEventTime - lastCrankEventTime) : + uint16_t timeDiff = (crankEventTime >= lastCrankEventTime) ? + (crankEventTime - lastCrankEventTime) : (65535 - lastCrankEventTime + crankEventTime); if (timeDiff > 0) { // Time is in 1/1024th of a second float revolutions = crankRevolutions - lastCrankRevolutions; float timeMinutes = (timeDiff / 1024.0f) / 60.0f; - this->cadence = revolutions / timeMinutes; + float cadence = revolutions / timeMinutes; + + if (cadence > 1) { + if (cadence > 200) { // Human is unlikely producing 200+ cadence + // Cadence Error: Could happen if cadence measurements were missed + // Leave cadence unchanged + cadence = this->cadence; + } + this->cadence = cadence; + this->missedReadingCount = 0; + } else { + this->missedReadingCount++; + } + } else { // the crank rev probably didn't update + if (this->missedReadingCount > 2) { // Require three consecutive readings before setting 0 cadence + this->cadence = 0; + } + this->missedReadingCount++; } } diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index d1659111..ae6a3125 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -858,7 +858,7 @@ void SpinBLEAdvertisedDevice::set(const NimBLEAdvertisedDevice *device, int id, this->connectedClientID = id; this->serviceUUID = BLEUUID(inServiceUUID); this->charUUID = BLEUUID(inCharUUID); - this->dataBufferQueue = xQueueCreate(4, sizeof(NotifyData)); + this->dataBufferQueue = xQueueCreate(6, sizeof(NotifyData)); // Only register services when we have a connected client if (id != BLE_HS_CONN_HANDLE_NONE) { From 6143072f310a67af4d9bc145c0fed5e20536e857 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Fri, 24 Jan 2025 15:50:13 -0600 Subject: [PATCH 030/451] Ready for testing --- include/BLE_Common.h | 10 ++++++++-- platformio.ini | 2 +- src/BLE_Client.cpp | 18 +++++------------- src/BLE_Common.cpp | 8 +------- src/BLE_Fitness_Machine_Service.cpp | 5 ++--- 5 files changed, 17 insertions(+), 26 deletions(-) diff --git a/include/BLE_Common.h b/include/BLE_Common.h index 80aa62e7..0e781a65 100644 --- a/include/BLE_Common.h +++ b/include/BLE_Common.h @@ -19,6 +19,10 @@ #include "BLE_Wattbike_Service.h" #include "Constants.h" +//Client size allocated to the queue for receiving characteristic data +#define NOTIFY_DATA_QUEUE_SIZE 25 +#define NOTIFY_DATA_QUEUE_LENGTH 10 + // Vector of supported BLE services and their corresponding characteristic UUIDs struct BLEServiceInfo { BLEUUID serviceUUID; @@ -130,10 +134,12 @@ void bleClientTask(void* pvParameters); // CYCLINGPOWERMEASUREMENT_UUID, HEARTCHARACTERISTIC_UUID, // FLYWHEEL_UART_TX_UUID}; + + typedef struct NotifyData { NimBLEUUID serviceUUID; NimBLEUUID charUUID; - uint8_t data[25]; + uint8_t data[NOTIFY_DATA_QUEUE_SIZE]; size_t length; } NotifyData; @@ -171,7 +177,7 @@ class SpinBLEAdvertisedDevice { void set(const NimBLEAdvertisedDevice* device, int id = BLE_HS_CONN_HANDLE_NONE, BLEUUID inServiceUUID = (uint16_t)0x0000, BLEUUID inCharUUID = (uint16_t)0x0000); void reset(); void print(); - bool enqueueData(uint8_t data[25], size_t length, NimBLEUUID serviceUUID, NimBLEUUID charUUID); + bool enqueueData(uint8_t data[NOTIFY_DATA_QUEUE_SIZE], size_t length, NimBLEUUID serviceUUID, NimBLEUUID charUUID); NotifyData dequeueData(); }; diff --git a/platformio.ini b/platformio.ini index 37bbb775..e1033275 100644 --- a/platformio.ini +++ b/platformio.ini @@ -30,7 +30,7 @@ build_flags = -D ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=3500 -std=gnu++17 lib_deps = - https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.2.0.zip + https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.1.3.zip https://github.com/teemuatlut/TMCStepper/archive/refs/tags/v0.7.3.zip https://github.com/bblanchon/ArduinoJson/archive/refs/tags/v6.20.0.zip https://github.com/gin66/FastAccelStepper/archive/refs/tags/0.31.2.zip diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index ae6a3125..fa74612c 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -46,7 +46,7 @@ void SpinBLEClient::start() { pBLEScan->setActiveScan(true); } -void notifyCB(NimBLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t *pData, size_t length, bool isNotify) { +static void notifyCB(NimBLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t *pData, size_t length, bool isNotify) { // Parse BLE shifter info. if (pBLERemoteCharacteristic->getRemoteService()->getUUID() == HID_SERVICE_UUID) { Serial.print(pData[0], HEX); @@ -78,8 +78,8 @@ void subscribeToAllNotifications(NimBLEClient *pClient) { if (pChr) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Found %s, %s", service.serviceUUID.toString().c_str(), pChr->getUUID().toString().c_str()); if (pChr->canNotify() || pChr->canIndicate()) { - if (pChr->subscribe(true, notifyCB)) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Subscribed to %s %s", service.name.c_str(), pChr->getUUID().toString().c_str()); + if (pChr->canNotify() ? pChr->subscribe(true, notifyCB) : pChr->subscribe(false, notifyCB)) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Subscribed to %s %s handle: %d", service.name.c_str(), pChr->getUUID().toString().c_str(), pChr->getHandle()); } else { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to subscribe to %s %s", service.name.c_str(), pChr->getUUID().toString().c_str()); } @@ -209,7 +209,7 @@ bool SpinBLEClient::connectToServer() { */ pClient = NimBLEDevice::getClientByPeerAddress(myDevice->getAddress()); if (pClient) { - pClient->setConnectTimeout(2); + pClient->setConnectTimeout(500); SS2K_LOG(BLE_CLIENT_LOG_TAG, "Reusing Client"); if (!pClient->connect(myDevice, false)) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Reconnect failed "); @@ -251,7 +251,7 @@ bool SpinBLEClient::connectToServer() { * connections. Timeout should be a multiple of the interval, minimum is 100ms. * Min interval: 12 * 1.25ms = 15, Max interval: 12 * 1.25ms = 15, 0 latency, 51 * 10ms = 510ms timeout */ - pClient->setConnectionParams(6, 6, 0, 200); + pClient->setConnectionParams(6, 12, 0, 500); /** Set how long we are willing to wait for the connection to complete (seconds), default is 30. */ pClient->setConnectTimeout(5 * 1000); // 5 seconds @@ -266,13 +266,6 @@ bool SpinBLEClient::connectToServer() { } } - if (!pClient->isConnected()) { - if (!pClient->connect(myDevice)) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to connect"); - return false; - } - } - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Connected to: %s - %s RSSI %d", this->adevName2UniqueName(myDevice).c_str(), pClient->getPeerAddress().toString().c_str(), pClient->getRssi()); if (serviceUUID == HID_SERVICE_UUID) { @@ -293,7 +286,6 @@ bool SpinBLEClient::connectToServer() { pSvc = pClient->getService(serviceUUID); if (pSvc) { /** make sure it's not null */ this->reconnectTries = MAX_RECONNECT_TRIES; - // SS2K_LOG(BLE_CLIENT_LOG_TAG, "Successful %s subscription.", pChr->getUUID().toString().c_str()); spinBLEClient.myBLEDevices[device_number].doConnect = false; this->reconnectTries = MAX_RECONNECT_TRIES; spinBLEClient.myBLEDevices[device_number].set(myDevice, pClient->getConnHandle(), serviceUUID, charUUID); diff --git a/src/BLE_Common.cpp b/src/BLE_Common.cpp index 1ac54683..58fbcd54 100644 --- a/src/BLE_Common.cpp +++ b/src/BLE_Common.cpp @@ -47,24 +47,18 @@ void BLECommunications() { // **********************************Client*************************************** for (auto& _BLEd : spinBLEClient.myBLEDevices) { // loop through discovered devices if (_BLEd.connectedClientID != BLE_HS_CONN_HANDLE_NONE) { - // SS2K_LOGW(BLE_COMMON_LOG_TAG, "Address: (%s) Client ID: (%d) SerUUID: (%s) CharUUID: (%s) HRM: (%s) PM: (%s) CSC: (%s) CT: (%s) doConnect: (%s) postConnect: (%s)", - // _BLEd.peerAddress.toString().c_str(), _BLEd.connectedClientID, _BLEd.serviceUUID.toString().c_str(), _BLEd.charUUID.toString().c_str(), - // _BLEd.isHRM ? "true" : "false", _BLEd.isPM ? "true" : "false", _BLEd.isCSC ? "true" : "false", _BLEd.isCT ? "true" : "false", _BLEd.doConnect ? "true" : - // "false", _BLEd.getPostConnected() ? "true" : "false"); if (_BLEd.advertisedDevice) { // is device registered? if ((_BLEd.connectedClientID != BLE_HS_CONN_HANDLE_NONE) && (_BLEd.doConnect == false)) { // client must not be in connection process if (BLEDevice::getClientByPeerAddress(_BLEd.peerAddress)) { // nullptr check BLEClient* pClient = NimBLEDevice::getClientByPeerAddress(_BLEd.peerAddress); // Client connected with a valid UUID registered if ((_BLEd.serviceUUID != BLEUUID((uint16_t)0x0000)) && (pClient->isConnected())) { - BLERemoteCharacteristic* pRemoteBLECharacteristic = pClient->getService(_BLEd.serviceUUID)->getCharacteristic(_BLEd.charUUID); // Handle BLE HID Remotes if (_BLEd.serviceUUID == HID_SERVICE_UUID) { spinBLEClient.keepAliveBLE_HID(pClient); // keep alive doesn't seem to help :( continue; // There is not data that needs to be dequeued for the remote, so got to the next device. } - // Dequeue sensor data we stored during notifications while (pdTRUE) { NotifyData incomingNotifyData = _BLEd.dequeueData(); @@ -77,7 +71,7 @@ void BLECommunications() { for (size_t i = 0; i < length; i++) { pData[i] = incomingNotifyData.data[i]; } - collectAndSet(incomingNotifyData.charUUID, incomingNotifyData.serviceUUID, pRemoteBLECharacteristic->getRemoteService()->getClient()->getPeerAddress(), pData, + collectAndSet(incomingNotifyData.charUUID, incomingNotifyData.serviceUUID, _BLEd.peerAddress, pData, length); } diff --git a/src/BLE_Fitness_Machine_Service.cpp b/src/BLE_Fitness_Machine_Service.cpp index 0e7e3d02..423450aa 100644 --- a/src/BLE_Fitness_Machine_Service.cpp +++ b/src/BLE_Fitness_Machine_Service.cpp @@ -309,12 +309,11 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { ftmsStatus = {FitnessMachineStatus::StartedOrResumedByUser}; ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x00; fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); - fitnessMachineTrainingStatus->notify(false); } fitnessMachineStatusCharacteristic->setValue(ftmsStatus.data(), ftmsStatus.size()); pCharacteristic->indicate(); - fitnessMachineTrainingStatus->notify(false); - fitnessMachineStatusCharacteristic->notify(false); + fitnessMachineTrainingStatus->notify(); + fitnessMachineStatusCharacteristic->notify(); } } From 1ce8abfc69228aac87395f87907ea077ea3dd26d Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Fri, 24 Jan 2025 19:34:57 -0600 Subject: [PATCH 031/451] added provisions to use powertable and cadence for power --- data/bluetoothscanner.html | 2 +- data/settings.html | 10 +++ include/BLE_Custom_Characteristic.h | 1 + include/ERG_Mode.h | 4 + include/SmartSpin_parameters.h | 4 + src/BLE_Client.cpp | 71 ++++++++++++++++- src/BLE_Common.cpp | 9 +-- src/BLE_Custom_Characteristic.cpp | 22 +++++- src/ERG_Mode.cpp | 114 +++++++++++++++++++++++++++- src/HTTP_Server_Basic.cpp | 5 ++ src/SensorCollector.cpp | 2 +- src/SmartSpin_parameters.cpp | 6 ++ 12 files changed, 236 insertions(+), 14 deletions(-) diff --git a/data/bluetoothscanner.html b/data/bluetoothscanner.html index 575663f3..c0d8a0c3 100644 --- a/data/bluetoothscanner.html +++ b/data/bluetoothscanner.html @@ -138,7 +138,7 @@

var t_obj = JSON.parse(data.foundDevices) { for (var key in t_obj) { - if (t_obj[key].UUID == '0x1818' || t_obj[key].UUID == '0x1826' || t_obj[key].UUID == '6e400001-b5a3-f393-e0a9-e50e24dcca9e' || t_obj[key].UUID == '0bf669f0-45f2-11e7-9598-0800200c9a66') { + if (t_obj[key].UUID == '0x1816' || t_obj[key].UUID == '0x1818' || t_obj[key].UUID == '0x1826' || t_obj[key].UUID == '6e400001-b5a3-f393-e0a9-e50e24dcca9e' || t_obj[key].UUID == '0bf669f0-45f2-11e7-9598-0800200c9a66') { optionPM = document.createElement('option'); if (t_obj[key].name) { optionPM.text = t_obj[key].name; diff --git a/data/settings.html b/data/settings.html index bfdb371a..ce88ace5 100644 --- a/data/settings.html +++ b/data/settings.html @@ -254,6 +254,15 @@

class="slider"> + + +

PowerTable For PowerUse the PowerTable for Power instead of PM

+ + + + + @@ -324,6 +333,7 @@

document.getElementById("stepperDir").checked = obj.stepperDir; document.getElementById("shifterDir").checked = obj.shifterDir; document.getElementById("udpLogEnabled").checked = !!obj.udpLogEnabled; + document.getElementById("pTab4Pwr").checked = !!obj.pTab4Pwr; updateSlider(document.getElementById("shiftStep").value, document.getElementById("shiftStepValue")); updateSlider(document.getElementById("inclineMultiplier").value, document.getElementById("inclineMultiplierValue")); updateSlider(document.getElementById("ERGSensitivity").value, document.getElementById("ERGSensitivityValue")); diff --git a/include/BLE_Custom_Characteristic.h b/include/BLE_Custom_Characteristic.h index 2ccc3326..76b8899d 100644 --- a/include/BLE_Custom_Characteristic.h +++ b/include/BLE_Custom_Characteristic.h @@ -61,6 +61,7 @@ const uint8_t BLE_simulateTargetWatts = 0x29; // are we sending target watts const uint8_t BLE_hMin = 0x2A; // Minimum homing value const uint8_t BLE_hMax = 0x2B; // Maximum homing value const uint8_t BLE_homingSensitivity = 0x2C; // Homing sensitivity value +const uint8_t BLE_pTab4Pwr = 0x2D; // Use power values for power table class BLE_ss2kCustomCharacteristic { public: diff --git a/include/ERG_Mode.h b/include/ERG_Mode.h index afdba436..292b05ec 100644 --- a/include/ERG_Mode.h +++ b/include/ERG_Mode.h @@ -89,6 +89,7 @@ class TestResults { class PowerTable { public: + bool saveFlag = false; TableRow tableRow[POWERTABLE_CAD_SIZE]; // What used to be in the ERGTaskLoop(). This is the main control function for ERG Mode and the powertable operations. @@ -106,6 +107,9 @@ class PowerTable { // returns incline for wattTarget. Null if not found. int32_t lookup(int watts, int cad); + // returns watts for given cadence and target position. Returns RETURN_ERROR if not found. + int32_t lookupWatts(int cad, int32_t targetPosition); + // automatically load or save the Power Table bool _manageSaveState(); diff --git a/include/SmartSpin_parameters.h b/include/SmartSpin_parameters.h index befe8d77..9cb12d50 100644 --- a/include/SmartSpin_parameters.h +++ b/include/SmartSpin_parameters.h @@ -123,6 +123,7 @@ class userParameters { int stepperSpeed; bool stepperDir; bool shifterDir; + bool pTab4Pwr = false; bool udpLogEnabled = false; int32_t hMin = INT32_MIN; int32_t hMax = INT32_MIN; @@ -199,6 +200,9 @@ class userParameters { void setUdpLogEnabled(bool enabled) { udpLogEnabled = enabled; } bool getUdpLogEnabled() { return udpLogEnabled; } + void setPTab4Pwr(bool pTab) { pTab4Pwr = pTab; } + bool getPTab4Pwr() { return pTab4Pwr; } + void setFoundDevices(String fdv) { foundDevices = fdv; } const char* getFoundDevices() { return foundDevices.c_str(); } diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index fa74612c..70b81262 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -46,6 +46,17 @@ void SpinBLEClient::start() { pBLEScan->setActiveScan(true); } +/** + * @brief Callback function for BLE notifications. + * + * This function is called whenever a notification is received from a BLE characteristic. + * It handles specific notifications for the HID service and enqueues sensor data for further processing. + * + * @param pBLERemoteCharacteristic Pointer to the remote characteristic that generated the notification. + * @param pData Pointer to the data received in the notification. + * @param length Length of the data received. + * @param isNotify Boolean indicating if the notification is a notify or indicate. + */ static void notifyCB(NimBLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t *pData, size_t length, bool isNotify) { // Parse BLE shifter info. if (pBLERemoteCharacteristic->getRemoteService()->getUUID() == HID_SERVICE_UUID) { @@ -57,7 +68,7 @@ static void notifyCB(NimBLERemoteCharacteristic *pBLERemoteCharacteristic, uint8 rtConfig->setShifterPosition(rtConfig->getShifterPosition() - 1); } } - // enqueue sensor data + // Enqueue sensor data for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { if (pBLERemoteCharacteristic->getClient()->getPeerAddress() == spinBLEClient.myBLEDevices[i].peerAddress) { spinBLEClient.myBLEDevices[i].enqueueData(pData, length, pBLERemoteCharacteristic->getRemoteService()->getUUID(), pBLERemoteCharacteristic->getUUID()); @@ -65,6 +76,15 @@ static void notifyCB(NimBLERemoteCharacteristic *pBLERemoteCharacteristic, uint8 } } +/** + * @brief Subscribes to all notifications for supported BLE services on the given client. + * + * This function iterates through all supported BLE services and subscribes to notifications + * for each characteristic that supports notifications or indications. + * + * @param pClient Pointer to the NimBLEClient object representing the BLE client. + * The client must be connected for the function to proceed. + */ void subscribeToAllNotifications(NimBLEClient *pClient) { if (!pClient || !pClient->isConnected()) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Client not connected for notifications"); @@ -92,6 +112,31 @@ void subscribeToAllNotifications(NimBLEClient *pClient) { // BLE Client loop task. // Manages device connections and scanning. +/** + * @brief Task function to manage BLE client operations. + * + * This function handles the BLE client operations including scanning for BLE devices, + * connecting to BLE servers, and managing BLE connections. It runs in an infinite loop + * with a delay between iterations. + * + * @param pvParameters Pointer to the parameters passed to the task (unused). + * + * The function performs the following operations: + * - Checks and manages BLE reconnections. + * - Disconnects all connected servers if an update is in progress. + * - Scans for BLE devices to connect to the client. + * - Connects BLE servers to the client. + * - Manages the spin down process for the server. + * + * The function uses the following global variables and objects: + * - spinBLEClient: Manages BLE client operations. + * - ss2k: Represents the main application state and configuration. + * - rtConfig: Runtime configuration for the application. + * - spinBLEServer: Manages BLE server operations. + * + * The function also includes debug logging and stack high water mark monitoring + * when the DEBUG_STACK macro is defined. + */ void bleClientTask(void *pvParameters) { long int scanDelay = millis(); spinBLEClient.checkBLEReconnect(); @@ -285,7 +330,7 @@ bool SpinBLEClient::connectToServer() { pSvc = pClient->getService(serviceUUID); if (pSvc) { /** make sure it's not null */ - this->reconnectTries = MAX_RECONNECT_TRIES; + this->reconnectTries = MAX_RECONNECT_TRIES; spinBLEClient.myBLEDevices[device_number].doConnect = false; this->reconnectTries = MAX_RECONNECT_TRIES; spinBLEClient.myBLEDevices[device_number].set(myDevice, pClient->getConnHandle(), serviceUUID, charUUID); @@ -359,9 +404,21 @@ void MyClientCallback::onAuthenticationComplete(NimBLEConnInfo &connInfo) { } /** - * Scan for BLE servers and find the first one that advertises the service we are looking for. + * @brief Callback function that is called when a BLE device is found during scanning. + * + * This function processes the advertised BLE device, checks if it matches the supported devices, + * and attempts to connect to it if it matches the user configuration. + * + * @param advertisedDevice Pointer to the NimBLEAdvertisedDevice object representing the found device. + * + * The function performs the following steps: + * - Logs the found device. + * - Checks if the device has a service UUID and if it is supported. + * - Depending on the service UUID, it checks if the device matches the user configuration for + * connected remote, heart monitor, or power meter. + * - If the device matches the user configuration, it attempts to connect to the device and logs the result. + * - If the device does not match the user configuration, it ignores the device. */ - void ScanCallbacks::onResult(const NimBLEAdvertisedDevice *advertisedDevice) { Serial.printf("Advertised Device found: %s\n", advertisedDevice->toString().c_str()); // Define granular constants for maximal reuse during logging @@ -808,6 +865,12 @@ void SpinBLEClient::handleBattInfo(NimBLEClient *pClient, bool updateNow = false static unsigned long last_battery_update = 0; if ((millis() - last_battery_update >= BATTERY_UPDATE_INTERVAL_MILLIS) || (last_battery_update == 0) || updateNow) { last_battery_update = millis(); + if (pClient->getService(BATTERYSERVICE_UUID) == nullptr) { + return; + } + if (pClient->getService(BATTERYSERVICE_UUID)->getCharacteristic(BATTERYCHARACTERISTIC_UUID) == nullptr) { + return; + } if (pClient->getService(HEARTSERVICE_UUID) && pClient->getService(BATTERYSERVICE_UUID)) { // get battery level at first connect BLERemoteCharacteristic *battCharacteristic = pClient->getService(BATTERYSERVICE_UUID)->getCharacteristic(BATTERYCHARACTERISTIC_UUID); if (battCharacteristic != nullptr) { diff --git a/src/BLE_Common.cpp b/src/BLE_Common.cpp index 58fbcd54..2458c5be 100644 --- a/src/BLE_Common.cpp +++ b/src/BLE_Common.cpp @@ -53,7 +53,6 @@ void BLECommunications() { BLEClient* pClient = NimBLEDevice::getClientByPeerAddress(_BLEd.peerAddress); // Client connected with a valid UUID registered if ((_BLEd.serviceUUID != BLEUUID((uint16_t)0x0000)) && (pClient->isConnected())) { - // Handle BLE HID Remotes if (_BLEd.serviceUUID == HID_SERVICE_UUID) { spinBLEClient.keepAliveBLE_HID(pClient); // keep alive doesn't seem to help :( @@ -71,11 +70,11 @@ void BLECommunications() { for (size_t i = 0; i < length; i++) { pData[i] = incomingNotifyData.data[i]; } - collectAndSet(incomingNotifyData.charUUID, incomingNotifyData.serviceUUID, _BLEd.peerAddress, pData, - length); + collectAndSet(incomingNotifyData.charUUID, incomingNotifyData.serviceUUID, _BLEd.peerAddress, pData, length); + } + if (_BLEd.getPostConnected()) { + spinBLEClient.handleBattInfo(pClient, false); } - - spinBLEClient.handleBattInfo(pClient, false); } else if (!pClient->isConnected()) { // This shouldn't ever be // called... diff --git a/src/BLE_Custom_Characteristic.cpp b/src/BLE_Custom_Characteristic.cpp index ac8a90d4..07c8a389 100644 --- a/src/BLE_Custom_Characteristic.cpp +++ b/src/BLE_Custom_Characteristic.cpp @@ -102,7 +102,7 @@ void BLE_ss2kCustomCharacteristic::update() {} void ss2kCustomCharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) { std::string rxValue = pCharacteristic->getValue(); - SS2K_LOG(CUSTOM_CHAR_LOG_TAG, "Write from %s", connInfo.getAddress().toString().c_str()); + //SS2K_LOG(CUSTOM_CHAR_LOG_TAG, "Write from %s", connInfo.getAddress().toString().c_str()); BLE_ss2kCustomCharacteristic::process(rxValue); } @@ -679,6 +679,7 @@ void BLE_ss2kCustomCharacteristic::process(std::string rxValue) { for (int i = 0; i < POWERTABLE_WATT_SIZE; i++) { powerTable->tableRow[rxValue[2]].tableEntry[i].targetPosition = (int16_t((uint8_t)(rxValue[i*2 + 3]) << 0 | (uint8_t)(rxValue[i*2 + 4]) << 8)); } + powerTable->saveFlag = true; } else { //SS2K_LOG(CUSTOM_CHAR_LOG_TAG, "Table row invalid"); // Logging causes crashes in ISR @@ -761,6 +762,20 @@ void BLE_ss2kCustomCharacteristic::process(std::string rxValue) { } break; + case BLE_pTab4Pwr: // 0x2D + logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "<-pTab4Pwr"); + if (rxValue[0] == cc_read) { + returnValue[0] = cc_success; + returnValue[2] = (uint8_t)(userConfig->getPTab4Pwr()); + returnLength += 1; + } + if (rxValue[0] == cc_write) { + returnValue[0] = cc_success; + userConfig->setPTab4Pwr(rxValue[2]); + logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "(%s)", userConfig->getPTab4Pwr() ? "true" : "false"); + } + break; + default: logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "<-Unknown Characteristic"); returnValue[0] = cc_error; @@ -930,4 +945,9 @@ void BLE_ss2kCustomCharacteristic::parseNemit() { BLE_ss2kCustomCharacteristic::notify(BLE_homingSensitivity); return; } + if (userConfig->getPTab4Pwr() != _oldParams.getPTab4Pwr()) { + _oldParams.setPTab4Pwr(userConfig->getPTab4Pwr()); + BLE_ss2kCustomCharacteristic::notify(BLE_pTab4Pwr); + return; + } } diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 51ea2ce9..a73553b3 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -29,6 +29,7 @@ void PowerTable::runERG() { static bool hasConnectedPowerMeter = false; static bool simulationRunning = false; static int loopCounter = 0; + static bool pTabUsed4Pwr = false; if ((millis() - ergTimer) > ERG_MODE_DELAY) { // reset the timer. @@ -41,6 +42,42 @@ void PowerTable::runERG() { return; } + static unsigned long int saveFlagCooldown = 0; + // save powertable if saveFlag has been set for 10 seconds using a saveFlagCooldown timer + // this is to provide enough time to transmit a new powerTable using BLE. + if (this->saveFlag) { + if (saveFlagCooldown == 0) { + saveFlagCooldown = millis(); + } + if ((millis() - saveFlagCooldown) > 10000) { + this->_save(); + saveFlagCooldown = 0; + saveFlag = false; + } + } + + // values hard set for testing: + // userConfig->setPTab4Pwr(true); + // rtConfig->setHomed(true); + + if ((!spinBLEClient.connectedPM || userConfig->getPTab4Pwr()) && rtConfig->cad.getValue() && rtConfig->getHomed()) { + // Lookup watts using the Power Table. + pTabUsed4Pwr = true; + if (this->_hasBeenLoadedThisSession) { + rtConfig->watts.setValue(lookupWatts(rtConfig->cad.getValue(), ss2k->getCurrentPosition())); + // rtConfig->watts.setSimulate(true); + } else { + // only run _manageSaveState every 5 seconds + static unsigned long int saveStateTimer = millis(); + if ((millis() - saveStateTimer) > 5000) { + this->_manageSaveState(); + saveStateTimer = millis(); + } + } + } else { + pTabUsed4Pwr = false; + } + if (rtConfig->cad.getValue() > 0 && rtConfig->watts.getValue() > 0) { hasConnectedPowerMeter = spinBLEClient.connectedPM; simulationRunning = rtConfig->watts.getTarget(); @@ -48,8 +85,10 @@ void PowerTable::runERG() { simulationRunning = rtConfig->watts.getSimulate(); } - // add values to torque table - powerTable->processPowerValue(powerBuffer, rtConfig->cad.getValue(), rtConfig->watts); + if (!pTabUsed4Pwr) { + // add values to Power table + powerTable->processPowerValue(powerBuffer, rtConfig->cad.getValue(), rtConfig->watts); + } // compute ERG if ((rtConfig->getFTMSMode() == FitnessMachineControlPointProcedure::SetTargetPower) && (hasConnectedPowerMeter || simulationRunning)) { @@ -1019,6 +1058,77 @@ bool PowerTable::_save() { return true; // return successful } +int32_t PowerTable::lookupWatts(int cad, int32_t targetPosition) { + // Convert targetPosition from external format (x100) to internal format + int16_t internalPosition = targetPosition / 100; + + // Calculate cadence index + int cadIndex = round(((float)cad - (float)MINIMUM_TABLE_CAD) / (float)POWERTABLE_CAD_INCREMENT); + + // Clamp cadence index to table limits + if (cadIndex < 0) { + cadIndex = 0; + } else if (cadIndex >= POWERTABLE_CAD_SIZE) { + cadIndex = POWERTABLE_CAD_SIZE - 1; + } + + // Find closest positions and corresponding watts in the row + int leftWattIndex = -1; + int rightWattIndex = -1; + + // Search for closest positions + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + if (this->tableRow[cadIndex].tableEntry[j].targetPosition != INT16_MIN) { + if (this->tableRow[cadIndex].tableEntry[j].targetPosition <= internalPosition) { + leftWattIndex = j; + } else { + rightWattIndex = j; + break; + } + } + } + + // If we found valid positions on both sides, interpolate + if (leftWattIndex != -1 && rightWattIndex != -1) { + int leftPos = this->tableRow[cadIndex].tableEntry[leftWattIndex].targetPosition; + int rightPos = this->tableRow[cadIndex].tableEntry[rightWattIndex].targetPosition; + int leftWatts = leftWattIndex * POWERTABLE_WATT_INCREMENT; + int rightWatts = rightWattIndex * POWERTABLE_WATT_INCREMENT; + + // Linear interpolation + int watts = leftWatts + (rightWatts - leftWatts) * (internalPosition - leftPos) / (rightPos - leftPos); + SS2K_LOG(ERG_MODE_LOG_TAG, "LookupWatts interpolated %dw from pos %d, cad %d", watts, targetPosition, cad); + return watts; + } + + // If we only found positions on one side, extrapolate + if (leftWattIndex != -1 && leftWattIndex > 0) { + // Extrapolate using two leftmost points + int pos1 = this->tableRow[cadIndex].tableEntry[leftWattIndex - 1].targetPosition; + int pos2 = this->tableRow[cadIndex].tableEntry[leftWattIndex].targetPosition; + int watts1 = (leftWattIndex - 1) * POWERTABLE_WATT_INCREMENT; + int watts2 = leftWattIndex * POWERTABLE_WATT_INCREMENT; + + int watts = watts2 + (watts2 - watts1) * (internalPosition - pos2) / (pos2 - pos1); + SS2K_LOG(ERG_MODE_LOG_TAG, "LookupWatts extrapolated high %dw from pos %d, cad %d", watts, targetPosition, cad); + return watts; + } + + if (rightWattIndex != -1 && rightWattIndex < POWERTABLE_WATT_SIZE - 1) { + // Extrapolate using two rightmost points + int pos1 = this->tableRow[cadIndex].tableEntry[rightWattIndex].targetPosition; + int pos2 = this->tableRow[cadIndex].tableEntry[rightWattIndex + 1].targetPosition; + int watts1 = rightWattIndex * POWERTABLE_WATT_INCREMENT; + int watts2 = (rightWattIndex + 1) * POWERTABLE_WATT_INCREMENT; + + int watts = watts1 + (watts1 - watts2) * (pos1 - internalPosition) / (pos1 - pos2); + SS2K_LOG(ERG_MODE_LOG_TAG, "LookupWatts extrapolated low %dw from pos %d, cad %d", watts, targetPosition, cad); + return watts; + } + SS2K_LOG(ERG_MODE_LOG_TAG, "LookupWatts failed to find a value for pos %d, cad %d", targetPosition, cad); + return RETURN_ERROR; +} + // Reset the PowerTable to 0; bool PowerTable::reset() { ss2k->resetPowerTableFlag = false; diff --git a/src/HTTP_Server_Basic.cpp b/src/HTTP_Server_Basic.cpp index c09a5c15..2324e500 100644 --- a/src/HTTP_Server_Basic.cpp +++ b/src/HTTP_Server_Basic.cpp @@ -543,6 +543,11 @@ void HTTP_Server::settingsProcessor() { } else if (wasSettingsUpdate) { userConfig->setUdpLogEnabled(false); } + if (!server.arg("pTab4Pwr").isEmpty()) { + userConfig->setPTab4Pwr(true); + } else if (wasSettingsUpdate) { + userConfig->setPTab4Pwr(false); + } if (!server.arg("stealthChop").isEmpty()) { userConfig->setStealthChop(true); ss2k->updateStealthChop(); diff --git a/src/SensorCollector.cpp b/src/SensorCollector.cpp index d587b40d..79c206cb 100644 --- a/src/SensorCollector.cpp +++ b/src/SensorCollector.cpp @@ -43,7 +43,7 @@ void collectAndSet(NimBLEUUID charUUID, NimBLEUUID serviceUUID, NimBLEAddress ad } } - if (sensorData->hasPower() && !rtConfig->watts.getSimulate()) { + if (sensorData->hasPower() && !rtConfig->watts.getSimulate() && !userConfig->getPTab4Pwr()) { if ((charUUID == PELOTON_DATA_UUID) && !((String(userConfig->getConnectedPowerMeter()) == "none") || (String(userConfig->getConnectedPowerMeter()) == "any"))) { // Peloton connected but using BLE Power Meter. So skip power for Peloton UUID. } else { diff --git a/src/SmartSpin_parameters.cpp b/src/SmartSpin_parameters.cpp index d44ed0f5..3638df96 100644 --- a/src/SmartSpin_parameters.cpp +++ b/src/SmartSpin_parameters.cpp @@ -67,6 +67,7 @@ void userParameters::setDefaults() { stepperDir = true; shifterDir = true; udpLogEnabled = false; + pTab4Pwr = false; hMin = INT32_MIN; hMax = INT32_MIN; homingSensitivity = DEFAULT_HOMING_SENSITIVITY; @@ -103,6 +104,7 @@ String userParameters::returnJSON() { doc["shifterDir"] = shifterDir; doc["stepperDir"] = stepperDir; doc["udpLogEnabled"] = udpLogEnabled; + doc["pTab4Pwr"] = pTab4Pwr; doc["hMin"] = hMin; doc["hMax"] = hMax; doc["homingSensitivity"] = homingSensitivity; @@ -154,6 +156,7 @@ void userParameters::saveToLittleFS() { doc["shifterDir"] = shifterDir; doc["stepperDir"] = stepperDir; doc["udpLogEnabled"] = udpLogEnabled; + doc["pTab4Pwr"] = pTab4Pwr; doc["hMin"] = hMin; doc["hMax"] = hMax; doc["homingSensitivity"] = homingSensitivity; @@ -226,6 +229,9 @@ void userParameters::loadFromLittleFS() { if (!doc["udpLogEnabled"].isNull()) { setUdpLogEnabled(doc["udpLogEnabled"]); } + if (!doc["pTab4Pwr"].isNull()) { + setPTab4Pwr(doc["pTab4Pwr"]); + } if (doc["powerCorrectionFactor"]) { setPowerCorrectionFactor(doc["powerCorrectionFactor"]); if ((getPowerCorrectionFactor() < MIN_PCF) || (getPowerCorrectionFactor() > MAX_PCF)) { From 7ccc5494d444c3d5c476f1a489f20a7a5a08e7d9 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sat, 25 Jan 2025 18:36:09 -0600 Subject: [PATCH 032/451] table should now load with csc only --- include/ERG_Mode.h | 2 +- src/ERG_Mode.cpp | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/ERG_Mode.h b/include/ERG_Mode.h index 292b05ec..80ecd8a2 100644 --- a/include/ERG_Mode.h +++ b/include/ERG_Mode.h @@ -111,7 +111,7 @@ class PowerTable { int32_t lookupWatts(int cad, int32_t targetPosition); // automatically load or save the Power Table - bool _manageSaveState(); + bool _manageSaveState(bool canSkipReliabilityChecks = false); // save powertable from littlefs bool _save(); diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index a73553b3..e2858a80 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -65,12 +65,12 @@ void PowerTable::runERG() { pTabUsed4Pwr = true; if (this->_hasBeenLoadedThisSession) { rtConfig->watts.setValue(lookupWatts(rtConfig->cad.getValue(), ss2k->getCurrentPosition())); - // rtConfig->watts.setSimulate(true); } else { // only run _manageSaveState every 5 seconds static unsigned long int saveStateTimer = millis(); if ((millis() - saveStateTimer) > 5000) { - this->_manageSaveState(); + //load the power table, true to skip checks. + this->_manageSaveState(true); saveStateTimer = millis(); } } @@ -875,7 +875,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { BLE_ss2kCustomCharacteristic::notify(0x27, k); } -bool PowerTable::_manageSaveState() { +bool PowerTable::_manageSaveState(bool canSkipReliabilityChecks) { // Check if the table has been loaded in this session if (!this->_hasBeenLoadedThisSession) { SS2K_LOG(POWERTABLE_LOG_TAG, "Loading Power Table...."); @@ -895,6 +895,11 @@ bool PowerTable::_manageSaveState() { bool savedHomed; file.read((uint8_t*)&savedHomed, sizeof(savedHomed)); + // If both current and saved tables were created with homing, we can skip position reliability checks + if (!canSkipReliabilityChecks) { + canSkipReliabilityChecks = savedHomed && rtConfig->getHomed(); + } + if (version != TABLE_VERSION) { SS2K_LOG(POWERTABLE_LOG_TAG, "Expected power table version %d, found version %d", TABLE_VERSION, version); file.close(); @@ -912,9 +917,6 @@ bool PowerTable::_manageSaveState() { SS2K_LOG(POWERTABLE_LOG_TAG, "Loading power table version %d, Size %d, Homed %d", version, savedQuality, savedHomed); - // If both current and saved tables were created with homing, we can skip position reliability checks - bool canSkipReliabilityChecks = savedHomed && rtConfig->getHomed(); - if (!canSkipReliabilityChecks) { // Initialize a counter for reliable positions int reliablePositions = 0; From c2076ef6d838c3c17a6bd5f04365446c55deb18c Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sat, 25 Jan 2025 19:52:01 -0600 Subject: [PATCH 033/451] cad with no pm --- src/BLE_Common.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BLE_Common.cpp b/src/BLE_Common.cpp index 2458c5be..e3c25369 100644 --- a/src/BLE_Common.cpp +++ b/src/BLE_Common.cpp @@ -101,7 +101,7 @@ void BLECommunications() { #endif // DEBUG_HR_TO_PWR // Set outputs to zero if we're not simulating or have connected devices. - if (!spinBLEClient.connectedPM && !hr2p && !rtConfig->watts.getSimulate() && !rtConfig->cad.getSimulate()) { + if (!spinBLEClient.connectedPM && !hr2p && !rtConfig->watts.getSimulate() && !rtConfig->cad.getSimulate() && !userConfig->getPTab4Pwr()) { rtConfig->cad.setValue(0); rtConfig->watts.setValue(0); } From da6754a40a3babed52576fb10d3cd5e2f3130a61 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sat, 25 Jan 2025 20:18:21 -0600 Subject: [PATCH 034/451] indications fixed. Working with Zwift --- src/BLE_Client.cpp | 2 +- src/BLE_Fitness_Machine_Service.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index 70b81262..dceb78ea 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -838,7 +838,7 @@ void SpinBLEClient::checkBLEReconnect() { this->doScan = true; SS2K_LOG(BLE_CLIENT_LOG_TAG, "No HRM Connected"); } - if ((String(userConfig->getConnectedPowerMeter()) != "none") && !(spinBLEClient.connectedPM)) { + if ((String(userConfig->getConnectedPowerMeter()) != "none") && !(spinBLEClient.connectedPM || spinBLEClient.connectedCD)) { this->doScan = true; SS2K_LOG(BLE_CLIENT_LOG_TAG, "No PM Connected"); } diff --git a/src/BLE_Fitness_Machine_Service.cpp b/src/BLE_Fitness_Machine_Service.cpp index 423450aa..6729f8c2 100644 --- a/src/BLE_Fitness_Machine_Service.cpp +++ b/src/BLE_Fitness_Machine_Service.cpp @@ -43,12 +43,12 @@ void BLE_Fitness_Machine_Service::setupService(NimBLEServer *pServer, MyCharacte pFitnessMachineService = spinBLEServer.pServer->createService(FITNESSMACHINESERVICE_UUID); fitnessMachineFeature = pFitnessMachineService->createCharacteristic(FITNESSMACHINEFEATURE_UUID, NIMBLE_PROPERTY::READ); fitnessMachineControlPoint = pFitnessMachineService->createCharacteristic(FITNESSMACHINECONTROLPOINT_UUID, NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::INDICATE); - fitnessMachineStatusCharacteristic = pFitnessMachineService->createCharacteristic(FITNESSMACHINESTATUS_UUID, NIMBLE_PROPERTY::NOTIFY); + fitnessMachineStatusCharacteristic = pFitnessMachineService->createCharacteristic(FITNESSMACHINESTATUS_UUID, NIMBLE_PROPERTY::INDICATE); fitnessMachineIndoorBikeData = pFitnessMachineService->createCharacteristic(FITNESSMACHINEINDOORBIKEDATA_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); fitnessMachineResistanceLevelRange = pFitnessMachineService->createCharacteristic(FITNESSMACHINERESISTANCELEVELRANGE_UUID, NIMBLE_PROPERTY::READ); fitnessMachinePowerRange = pFitnessMachineService->createCharacteristic(FITNESSMACHINEPOWERRANGE_UUID, NIMBLE_PROPERTY::READ); fitnessMachineInclinationRange = pFitnessMachineService->createCharacteristic(FITNESSMACHINEINCLINATIONRANGE_UUID, NIMBLE_PROPERTY::READ); - fitnessMachineTrainingStatus = pFitnessMachineService->createCharacteristic(FITNESSMACHINETRAININGSTATUS_UUID, NIMBLE_PROPERTY::NOTIFY); + fitnessMachineTrainingStatus = pFitnessMachineService->createCharacteristic(FITNESSMACHINETRAININGSTATUS_UUID, NIMBLE_PROPERTY::INDICATE); fitnessMachineFeature->setValue(ftmsFeature.bytes, sizeof(ftmsFeature)); ftmsIndoorBikeData[0] = static_cast(ftmsIBDFlags & 0xFF); // LSB, mask with 0xFF to get the lower 8 bits @@ -193,7 +193,7 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { case FitnessMachineControlPointProcedure::SetTargetPower: { rtConfig->setFTMSMode((uint8_t)rxValue[0]); - if (spinBLEClient.connectedPM || rtConfig->watts.getSimulate()) { + if (spinBLEClient.connectedPM || rtConfig->watts.getSimulate() || spinBLEClient.connectedCD) { returnValue[2] = FitnessMachineControlPointResultCode::Success; // 0x01; rtConfig->watts.setTarget(bytes_to_u16(rxValue[2], rxValue[1])); @@ -312,8 +312,8 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { } fitnessMachineStatusCharacteristic->setValue(ftmsStatus.data(), ftmsStatus.size()); pCharacteristic->indicate(); - fitnessMachineTrainingStatus->notify(); - fitnessMachineStatusCharacteristic->notify(); + fitnessMachineTrainingStatus->indicate(); + fitnessMachineStatusCharacteristic->indicate(); } } From 3feb3dc9d54a6a41bdeeb53f019faf659b61b4ce Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sun, 26 Jan 2025 15:46:47 -0600 Subject: [PATCH 035/451] testing to fix notifications in Zwift --- src/BLE_Fitness_Machine_Service.cpp | 30 ++++++++++++++++++++--------- src/BLE_Server.cpp | 9 +++++++-- src/Main.cpp | 2 +- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/BLE_Fitness_Machine_Service.cpp b/src/BLE_Fitness_Machine_Service.cpp index 6729f8c2..03a264d6 100644 --- a/src/BLE_Fitness_Machine_Service.cpp +++ b/src/BLE_Fitness_Machine_Service.cpp @@ -43,12 +43,12 @@ void BLE_Fitness_Machine_Service::setupService(NimBLEServer *pServer, MyCharacte pFitnessMachineService = spinBLEServer.pServer->createService(FITNESSMACHINESERVICE_UUID); fitnessMachineFeature = pFitnessMachineService->createCharacteristic(FITNESSMACHINEFEATURE_UUID, NIMBLE_PROPERTY::READ); fitnessMachineControlPoint = pFitnessMachineService->createCharacteristic(FITNESSMACHINECONTROLPOINT_UUID, NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::INDICATE); - fitnessMachineStatusCharacteristic = pFitnessMachineService->createCharacteristic(FITNESSMACHINESTATUS_UUID, NIMBLE_PROPERTY::INDICATE); - fitnessMachineIndoorBikeData = pFitnessMachineService->createCharacteristic(FITNESSMACHINEINDOORBIKEDATA_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); + fitnessMachineStatusCharacteristic = pFitnessMachineService->createCharacteristic(FITNESSMACHINESTATUS_UUID, NIMBLE_PROPERTY::NOTIFY); + fitnessMachineIndoorBikeData = pFitnessMachineService->createCharacteristic(FITNESSMACHINEINDOORBIKEDATA_UUID, NIMBLE_PROPERTY::NOTIFY); fitnessMachineResistanceLevelRange = pFitnessMachineService->createCharacteristic(FITNESSMACHINERESISTANCELEVELRANGE_UUID, NIMBLE_PROPERTY::READ); fitnessMachinePowerRange = pFitnessMachineService->createCharacteristic(FITNESSMACHINEPOWERRANGE_UUID, NIMBLE_PROPERTY::READ); fitnessMachineInclinationRange = pFitnessMachineService->createCharacteristic(FITNESSMACHINEINCLINATIONRANGE_UUID, NIMBLE_PROPERTY::READ); - fitnessMachineTrainingStatus = pFitnessMachineService->createCharacteristic(FITNESSMACHINETRAININGSTATUS_UUID, NIMBLE_PROPERTY::INDICATE); + fitnessMachineTrainingStatus = pFitnessMachineService->createCharacteristic(FITNESSMACHINETRAININGSTATUS_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); fitnessMachineFeature->setValue(ftmsFeature.bytes, sizeof(ftmsFeature)); ftmsIndoorBikeData[0] = static_cast(ftmsIBDFlags & 0xFF); // LSB, mask with 0xFF to get the lower 8 bits @@ -130,21 +130,23 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { switch ((uint8_t)rxValue[0]) { case FitnessMachineControlPointProcedure::RequestControl: - returnValue[2] = FitnessMachineControlPointResultCode::Success; // 0x01; + static bool firstRequest = true; + returnValue[2] = firstRequest ? FitnessMachineControlPointResultCode::Success : FitnessMachineControlPointResultCode::OpCodeNotSupported; + firstRequest = !firstRequest; rtConfig->watts.setTarget(0); rtConfig->setSimTargetWatts(false); logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> Control Request"); - ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Idle; // 0x01; + ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x01; fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); ftmsStatus = {FitnessMachineStatus::StartedOrResumedByUser}; pCharacteristic->setValue(returnValue, 3); break; case FitnessMachineControlPointProcedure::Reset: { - returnValue[2] = FitnessMachineControlPointResultCode::Success; // 0x01; + returnValue[2] = FitnessMachineControlPointResultCode::InvalidParameter; // 0x01; logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> Reset"); - ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Idle; // 0x01; + ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x01; ftmsStatus = {FitnessMachineStatus::Reset}; fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); pCharacteristic->setValue(returnValue, 3); @@ -309,11 +311,21 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { ftmsStatus = {FitnessMachineStatus::StartedOrResumedByUser}; ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x00; fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); + fitnessMachineTrainingStatus->notify(); } fitnessMachineStatusCharacteristic->setValue(ftmsStatus.data(), ftmsStatus.size()); + SS2K_LOG(FMTS_SERVER_LOG_TAG, "FTMS Status: %02x %02x", ftmsStatus[0], ftmsStatus[1]); pCharacteristic->indicate(); - fitnessMachineTrainingStatus->indicate(); - fitnessMachineStatusCharacteristic->indicate(); + std::string characteristicValue = pCharacteristic->getValue(); + std::string logValue; + for (size_t i = 0; i < characteristicValue.length(); ++i) { + char buf[4]; + snprintf(buf, sizeof(buf), "%02x ", (unsigned char)characteristicValue[i]); + logValue += buf; + } + SS2K_LOG(FMTS_SERVER_LOG_TAG, "FTMS CP Value: %s", logValue.c_str()); + fitnessMachineTrainingStatus->notify(); + fitnessMachineStatusCharacteristic->notify(); } } diff --git a/src/BLE_Server.cpp b/src/BLE_Server.cpp index 64912eb7..bf7a72da 100644 --- a/src/BLE_Server.cpp +++ b/src/BLE_Server.cpp @@ -184,8 +184,13 @@ void MyCharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, N } void MyCharacteristicCallbacks::onStatus(NimBLECharacteristic* pCharacteristic, int code) { - //SS2K_LOG(BLE_SERVER_LOG_TAG, "Notification/Indication status code: %d for characteristic: %s", - // code, pCharacteristic->getUUID().toString().c_str()); + //loop through and print out the characteristic data + for(int i = 0; i < pCharacteristic->getValue().size(); i++) { + SS2K_LOG(BLE_SERVER_LOG_TAG, "Characteristic Data: %d", pCharacteristic->getValue()[i]); + } + + SS2K_LOG(BLE_SERVER_LOG_TAG, "Notification/Indication status code: %d for characteristic: %s", + code, pCharacteristic->getUUID().toString().c_str()); } void MyCharacteristicCallbacks::onSubscribe(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) { diff --git a/src/Main.cpp b/src/Main.cpp index 0eefdce5..dfb7f825 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -224,7 +224,7 @@ void SS2K::maintenanceLoop(void *pvParameters) { speed = userConfig->getStepperSpeed(); } } - + ss2k->updateStepperSpeed(speed); } From ffe57adee2120871479ddb849dbb88bd4ddac1c7 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sun, 26 Jan 2025 19:11:17 -0600 Subject: [PATCH 036/451] more testing --- platformio.ini | 5 +- src/BLE_Fitness_Machine_Service.cpp | 93 ++++++++--------------------- src/BLE_Server.cpp | 16 +++-- 3 files changed, 39 insertions(+), 75 deletions(-) diff --git a/platformio.ini b/platformio.ini index e1033275..3860dee8 100644 --- a/platformio.ini +++ b/platformio.ini @@ -30,7 +30,10 @@ build_flags = -D ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=3500 -std=gnu++17 lib_deps = - https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.1.3.zip + #use a PR version of the library to fix a bug. Remove this line when the PR is merged + #NimBLE-Arduino PR #878 + https://github.com/h2zero/NimBLE-Arduino.git#refactor + #https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.1.3.zip https://github.com/teemuatlut/TMCStepper/archive/refs/tags/v0.7.3.zip https://github.com/bblanchon/ArduinoJson/archive/refs/tags/v6.20.0.zip https://github.com/gin66/FastAccelStepper/archive/refs/tags/0.31.2.zip diff --git a/src/BLE_Fitness_Machine_Service.cpp b/src/BLE_Fitness_Machine_Service.cpp index 03a264d6..4a570236 100644 --- a/src/BLE_Fitness_Machine_Service.cpp +++ b/src/BLE_Fitness_Machine_Service.cpp @@ -94,7 +94,7 @@ void BLE_Fitness_Machine_Service::update() { ftmsIndoorBikeData[10] = (uint8_t)hr; - fitnessMachineIndoorBikeData->setValue(ftmsIndoorBikeData, 11); + fitnessMachineIndoorBikeData->setValue(ftmsIndoorBikeData, sizeof(ftmsIndoorBikeData)); fitnessMachineIndoorBikeData->notify(); const int kLogBufCapacity = 200; // Data(30), Sep(data/2), Arrow(3), CharId(37), Sep(3), CharId(37), Sep(3), Name(10), Prefix(2), HR(7), SEP(1), CD(10), SEP(1), PW(8), @@ -113,71 +113,54 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { if (rxValue == "") { return; } + uint8_t returnValue[3] = {FitnessMachineControlPointProcedure::ResponseCode, (uint8_t)rxValue[0], FitnessMachineControlPointResultCode::OpCodeNotSupported}; BLECharacteristic *pCharacteristic = NimBLEDevice::getServer()->getServiceByUUID(FITNESSMACHINESERVICE_UUID)->getCharacteristic(FITNESSMACHINECONTROLPOINT_UUID); + std::vector ftmsStatus = {FitnessMachineStatus::ReservedForFutureUse}; - std::vector ftmsStatus; if (rxValue.length() >= 1) { - uint8_t *pData = reinterpret_cast(&rxValue[0]); - int length = rxValue.length(); - + uint8_t *pData = reinterpret_cast(&rxValue[0]); + int length = rxValue.length(); const int kLogBufCapacity = (rxValue.length() * 2) + 60; // largest comment is 48 VV char logBuf[kLogBufCapacity]; - int logBufLength = ss2k_log_hex_to_buffer(pData, length, logBuf, 0, kLogBufCapacity); - int port = 0; - uint8_t returnValue[3] = {FitnessMachineControlPointProcedure::ResponseCode, (uint8_t)rxValue[0], FitnessMachineControlPointResultCode::OpCodeNotSupported}; - - ftmsStatus = {FitnessMachineStatus::ReservedForFutureUse}; + int logBufLength = ss2k_log_hex_to_buffer(pData, length, logBuf, 0, kLogBufCapacity); + int port = 0; switch ((uint8_t)rxValue[0]) { case FitnessMachineControlPointProcedure::RequestControl: - static bool firstRequest = true; - returnValue[2] = firstRequest ? FitnessMachineControlPointResultCode::Success : FitnessMachineControlPointResultCode::OpCodeNotSupported; - firstRequest = !firstRequest; + returnValue[2] = FitnessMachineControlPointResultCode::Success; rtConfig->watts.setTarget(0); rtConfig->setSimTargetWatts(false); logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> Control Request"); ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x01; - fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); - ftmsStatus = {FitnessMachineStatus::StartedOrResumedByUser}; - pCharacteristic->setValue(returnValue, 3); + ftmsStatus = {FitnessMachineStatus::StartedOrResumedByUser}; break; case FitnessMachineControlPointProcedure::Reset: { - returnValue[2] = FitnessMachineControlPointResultCode::InvalidParameter; // 0x01; - + returnValue[2] = FitnessMachineControlPointResultCode::Success; // 0x01; logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> Reset"); ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x01; ftmsStatus = {FitnessMachineStatus::Reset}; - fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); - pCharacteristic->setValue(returnValue, 3); + } break; case FitnessMachineControlPointProcedure::SetTargetInclination: { rtConfig->setFTMSMode((uint8_t)rxValue[0]); returnValue[2] = FitnessMachineControlPointResultCode::Success; // 0x01; - - port = (rxValue[2] << 8) + rxValue[1]; + port = (rxValue[2] << 8) + rxValue[1]; port *= 10; - rtConfig->setTargetIncline(port); - logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> Incline Mode: %2f", rtConfig->getTargetIncline() / 100); - ftmsStatus = {FitnessMachineStatus::TargetInclineChanged, (uint8_t)rxValue[1], (uint8_t)rxValue[2]}; ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x00; - fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); - pCharacteristic->setValue(returnValue, 3); } break; case FitnessMachineControlPointProcedure::SetTargetResistanceLevel: { rtConfig->setFTMSMode((uint8_t)rxValue[0]); returnValue[2] = FitnessMachineControlPointResultCode::Success; // 0x01; ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x00; - fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); if ((int)rxValue[1] >= rtConfig->getMinResistance() && (int)rxValue[1] <= rtConfig->getMaxResistance()) { rtConfig->resistance.setTarget((int)rxValue[1]); returnValue[2] = FitnessMachineControlPointResultCode::Success; - logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> Resistance Mode: %d", rtConfig->resistance.getTarget()); } else if ((int)rxValue[1] > rtConfig->getMinResistance()) { rtConfig->resistance.setTarget(rtConfig->getMaxResistance()); @@ -190,21 +173,17 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { } ftmsStatus = {FitnessMachineStatus::TargetResistanceLevelChanged, (uint8_t)(rtConfig->resistance.getTarget() % 256)}; rtConfig->resistance.setTarget(rtConfig->resistance.getTarget()); - pCharacteristic->setValue(returnValue, 3); } break; case FitnessMachineControlPointProcedure::SetTargetPower: { rtConfig->setFTMSMode((uint8_t)rxValue[0]); if (spinBLEClient.connectedPM || rtConfig->watts.getSimulate() || spinBLEClient.connectedCD) { returnValue[2] = FitnessMachineControlPointResultCode::Success; // 0x01; - rtConfig->watts.setTarget(bytes_to_u16(rxValue[2], rxValue[1])); logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> ERG Mode Target: %d Current: %d Incline: %2f", rtConfig->watts.getTarget(), rtConfig->watts.getValue(), rtConfig->getTargetIncline() / 100); - ftmsStatus = {FitnessMachineStatus::TargetPowerChanged, (uint8_t)rxValue[1], (uint8_t)rxValue[2]}; ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::WattControl; // 0x0C; - fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); // Adjust set point for powerCorrectionFactor and send to FTMS server (if connected) int adjustedTarget = rtConfig->watts.getTarget() / userConfig->getPowerCorrectionFactor(); const uint8_t translated[] = {FitnessMachineControlPointProcedure::SetTargetPower, (uint8_t)(adjustedTarget % 256), (uint8_t)(adjustedTarget / 256)}; @@ -213,36 +192,28 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { returnValue[2] = FitnessMachineControlPointResultCode::OpCodeNotSupported; // 0x02; no power meter connected, so no ERG logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> ERG Mode: No Power Meter Connected"); } - pCharacteristic->setValue(returnValue, 3); } break; case FitnessMachineControlPointProcedure::StartOrResume: { returnValue[2] = FitnessMachineControlPointResultCode::Success; // 0x01; - pCharacteristic->setValue(returnValue, 3); - logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> Start Training"); ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x00; - fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); - ftmsStatus = {FitnessMachineStatus::StartedOrResumedByUser}; + ftmsStatus = {FitnessMachineStatus::StartedOrResumedByUser}; } break; case FitnessMachineControlPointProcedure::StopOrPause: { returnValue[2] = FitnessMachineControlPointResultCode::Success; // 0x01; - pCharacteristic->setValue(returnValue, 3); // rxValue[1] == 1 -> Stop, 2 -> Pause // TODO: Move stepper to Min Position logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> Stop Training"); - ftmsStatus = {FitnessMachineStatus::StoppedOrPausedByUser}; ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x00; - fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); } break; case FitnessMachineControlPointProcedure::SetIndoorBikeSimulationParameters: { // sim mode 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) @@ -252,7 +223,6 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { port = bytes_to_u16(buf[1], buf[0]); rtConfig->setTargetIncline(port); logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> Sim Mode Incline %2f", rtConfig->getTargetIncline() / 100); - ftmsStatus = {FitnessMachineStatus::IndoorBikeSimulationParametersChanged, (uint8_t)rxValue[1], (uint8_t)rxValue[2], @@ -262,7 +232,6 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { (uint8_t)rxValue[6]}; ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x00; - fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); spinBLEClient.FTMSControlPointWrite(pData, length); } break; @@ -272,50 +241,35 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { returnValue[2] = FitnessMachineControlPointResultCode::Success; pCharacteristic->setValue(controlPoint, 6); logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> Spin Down Requested"); - - ftmsStatus = {FitnessMachineStatus::SpinDownStatus, 0x01}; // send low and high speed targets - - ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x00; - pCharacteristic->setValue(returnValue, 3); - pCharacteristic->indicate(); + ftmsStatus = {FitnessMachineStatus::SpinDownStatus, 0x01}; // send low and high speed targets + ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x00; spinBLEServer.spinDownFlag = 2; } break; case FitnessMachineControlPointProcedure::SetTargetedCadence: { rtConfig->setFTMSMode((uint8_t)rxValue[0]); - returnValue[2] = FitnessMachineControlPointResultCode::Success; // 0x01; - pCharacteristic->setValue(returnValue, 3); - + returnValue[2] = FitnessMachineControlPointResultCode::Success; // 0x01; int targetCadence = bytes_to_u16(rxValue[2], rxValue[1]); // rtConfig->setTargetCadence(targetCadence); logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> Target Cadence: %d ", targetCadence); - - ftmsStatus = {FitnessMachineStatus::TargetedCadenceChanged, (uint8_t)rxValue[1], (uint8_t)rxValue[2]}; - + ftmsStatus = {FitnessMachineStatus::TargetedCadenceChanged, (uint8_t)rxValue[1], (uint8_t)rxValue[2]}; ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x00; - fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); } break; default: { logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> Unsupported FTMS Request"); - pCharacteristic->setValue(returnValue, 3); } } SS2K_LOG(FMTS_SERVER_LOG_TAG, "%s", logBuf); } else { SS2K_LOG(FMTS_SERVER_LOG_TAG, "App wrote nothing "); SS2K_LOG(FMTS_SERVER_LOG_TAG, "assuming it's a Control request"); - - uint8_t controlPoint[3] = {FitnessMachineControlPointProcedure::ResponseCode, 0x00, FitnessMachineControlPointResultCode::Success}; - pCharacteristic->setValue(controlPoint, 3); + returnValue[2] = FitnessMachineControlPointResultCode::Success; ftmsStatus = {FitnessMachineStatus::StartedOrResumedByUser}; ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x00; - fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); - fitnessMachineTrainingStatus->notify(); } fitnessMachineStatusCharacteristic->setValue(ftmsStatus.data(), ftmsStatus.size()); - SS2K_LOG(FMTS_SERVER_LOG_TAG, "FTMS Status: %02x %02x", ftmsStatus[0], ftmsStatus[1]); - pCharacteristic->indicate(); + SS2K_LOG(FMTS_SERVER_LOG_TAG, "Calling notify %s -> %02x %02x", fitnessMachineStatusCharacteristic->getUUID().toString().c_str(), ftmsStatus[0], ftmsStatus[1]); std::string characteristicValue = pCharacteristic->getValue(); std::string logValue; for (size_t i = 0; i < characteristicValue.length(); ++i) { @@ -323,9 +277,12 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { snprintf(buf, sizeof(buf), "%02x ", (unsigned char)characteristicValue[i]); logValue += buf; } - SS2K_LOG(FMTS_SERVER_LOG_TAG, "FTMS CP Value: %s", logValue.c_str()); - fitnessMachineTrainingStatus->notify(); - fitnessMachineStatusCharacteristic->notify(); + SS2K_LOG(FMTS_SERVER_LOG_TAG, "Caling notify %s -> %s", pCharacteristic->getUUID().toString().c_str(), logValue.c_str()); + fitnessMachineControlPoint->setValue(returnValue, 3); + fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); + fitnessMachineControlPoint->notify(); + //fitnessMachineTrainingStatus->notify(); + //fitnessMachineStatusCharacteristic->notify(); } } diff --git a/src/BLE_Server.cpp b/src/BLE_Server.cpp index bf7a72da..6b19c68c 100644 --- a/src/BLE_Server.cpp +++ b/src/BLE_Server.cpp @@ -184,13 +184,17 @@ void MyCharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, N } void MyCharacteristicCallbacks::onStatus(NimBLECharacteristic* pCharacteristic, int code) { - //loop through and print out the characteristic data - for(int i = 0; i < pCharacteristic->getValue().size(); i++) { - SS2K_LOG(BLE_SERVER_LOG_TAG, "Characteristic Data: %d", pCharacteristic->getValue()[i]); - } + //loop through and accumulate the data into a C++ string + std::string characteristicValue = pCharacteristic->getValue(); + std::string logValue; + for (size_t i = 0; i < characteristicValue.length(); ++i) { + char buf[4]; + snprintf(buf, sizeof(buf), "%02x ", (unsigned char)characteristicValue[i]); + logValue += buf; + } - SS2K_LOG(BLE_SERVER_LOG_TAG, "Notification/Indication status code: %d for characteristic: %s", - code, pCharacteristic->getUUID().toString().c_str()); + SS2K_LOG(BLE_SERVER_LOG_TAG, "Notification/Indication status code: %d for char: %s Data: %s", + code, pCharacteristic->getUUID().toString().c_str(), logValue.c_str()); } void MyCharacteristicCallbacks::onSubscribe(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) { From ee82c8a9e5c07a6eec90b9f608b2c076baf31f26 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 29 Jan 2025 18:28:17 -0600 Subject: [PATCH 037/451] bumped Power table version to version 6 --- include/settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/settings.h b/include/settings.h index 51314d62..e85c009d 100644 --- a/include/settings.h +++ b/include/settings.h @@ -254,7 +254,7 @@ const char* const DEFAULT_PASSWORD = "password"; #define RUNTIMECONFIG_JSON_SIZE 1000 + DEBUG_LOG_BUFFER_SIZE // PowerTable Version -#define TABLE_VERSION 5 +#define TABLE_VERSION 6 /* Number of entries in the ERG Power Lookup Table This is currently maintained as to keep memory usage lower and reduce the print output of the table. From 99200ae81200308671c89f1cc85712d0c21f29ab Mon Sep 17 00:00:00 2001 From: ddtomic Date: Thu, 30 Jan 2025 20:16:40 -0600 Subject: [PATCH 038/451] initial commit --- .../BLE_Client-checkpoint.cpp | 942 ++++++++++++++++++ 1 file changed, 942 insertions(+) create mode 100644 src/.ipynb_checkpoints/BLE_Client-checkpoint.cpp diff --git a/src/.ipynb_checkpoints/BLE_Client-checkpoint.cpp b/src/.ipynb_checkpoints/BLE_Client-checkpoint.cpp new file mode 100644 index 00000000..74f53167 --- /dev/null +++ b/src/.ipynb_checkpoints/BLE_Client-checkpoint.cpp @@ -0,0 +1,942 @@ +/* + * Copyright (C) 2020 Anthony Doud & Joel Baranick + * All rights reserved + * + * SPDX-License-Identifier: GPL-2.0-only + */ + +/* Assioma Pedal Information for later +BLE Advertised Device found: Name: ASSIOMA17287L, Address: e8:fe:6e:91:9f:16, +appearance: 1156, manufacturer data: 640302018743, serviceUUID: +00001818-0000-1000-8000-00805f9b34fb +*/ + +#include "Main.h" +#include "BLE_Common.h" +#include "BLE_Fitness_Machine_Service.h" +#include "SS2KLog.h" + +#include +#include +#include +#include + +TaskHandle_t BLEClientTask; + +SpinBLEClient spinBLEClient; + +static MyClientCallback myClientCallback; +static MyAdvertisedDeviceCallback myAdvertisedDeviceCallbacks; + +void SpinBLEClient::start() { + // Create the task for the BLE Client loop + xTaskCreatePinnedToCore(bleClientTask, /* Task function. */ + "BLEClientTask", /* name of task. */ + BLE_CLIENT_STACK, /* Stack size of task */ + NULL, /* parameter of the task */ + 1, /* priority of the task */ + &BLEClientTask, /* Task handle to keep track of created task */ + 1); /* pin task to core */ +} + +static void onNotify(BLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t *pData, size_t length, bool isNotify) { + // Parse BLE shifter info. + if (pBLERemoteCharacteristic->getRemoteService()->getUUID() == HID_SERVICE_UUID) { + Serial.print(pData[0], HEX); + if (pData[0] == 0x04) { + rtConfig->setShifterPosition(rtConfig->getShifterPosition() + 1); + } + if (pData[0] == 0x08) { + rtConfig->setShifterPosition(rtConfig->getShifterPosition() - 1); + } + } + + // enqueue sensor data + for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { + if (pBLERemoteCharacteristic->getUUID() == spinBLEClient.myBLEDevices[i].charUUID) { + spinBLEClient.myBLEDevices[i].enqueueData(pData, length); + } + } +} + +// BLE Client loop task. +// Manages device connections and scanning. +void bleClientTask(void *pvParameters) { + long int scanDelay = millis(); + for (;;) { + vTaskDelay(BLE_CLIENT_DELAY / portTICK_PERIOD_MS); // Delay between loops. + + // disconnect all connected servers if we're updating via BLE + if (ss2k->isUpdating) { + for (auto &_BLEd : spinBLEClient.myBLEDevices) { // loop through discovered devices + if (_BLEd.connectedClientID != BLE_HS_CONN_HANDLE_NONE) { + if (_BLEd.advertisedDevice) { // is device registered? + if ((_BLEd.connectedClientID != BLE_HS_CONN_HANDLE_NONE) && (_BLEd.doConnect == false)) { // client must not be in connection process + if (BLEDevice::getClientByPeerAddress(_BLEd.peerAddress)) { // nullptr check + NimBLEClient *pClient = NimBLEDevice::getClientByPeerAddress(_BLEd.peerAddress); + pClient->disconnect(); + } + } + } + } + } + } + + // Scan for BLE devices that we should connect to this client + if ((millis() - scanDelay) > ((BLE_RECONNECT_SCAN_DURATION * 1000) * 2)) { + spinBLEClient.checkBLEReconnect(); + scanDelay = millis(); +#ifdef DEBUG_STACK + Serial.printf("BLEClient: %d \n", uxTaskGetStackHighWaterMark(BLEClientTask)); +#endif // DEBUG_STACK + } + + if (spinBLEClient.doScan && (!ss2k->isUpdating)) { + spinBLEClient.scanProcess(); + } + + // Connect BLE Servers to this client + for (int x = 0; x < NUM_BLE_DEVICES; x++) { + if (spinBLEClient.myBLEDevices[x].doConnect == true && !ss2k->isUpdating) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Connecting device on slot %d ...", x); + if (spinBLEClient.connectToServer()) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "We are now connected to the BLE Server."); + } else { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "slot %d connection failed", x); + } + } + } + // Spin Down process for the Server. It's here because it needs to be non-blocking for the maintenance loop. + // Checking for cadence also so that we don't home when nobody is around. + if (spinBLEServer.spinDownFlag && rtConfig->cad.getValue()) { + if (spinBLEServer.spinDownFlag >= 2) { // Home Both Directions + ss2k->goHome(true); + } else { // Startup Homing + ss2k->goHome(false); + } + spinBLEServer.spinDownFlag = 0; + } + } +} + +bool SpinBLEClient::connectToServer() { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Initiating Server Connection"); + NimBLEUUID serviceUUID; + NimBLEUUID charUUID; + + int successful = 0; + BLEAdvertisedDevice *myDevice = nullptr; + int device_number = -1; + + for (int i = 0; i < NUM_BLE_DEVICES; i++) { + if (spinBLEClient.myBLEDevices[i].doConnect == true) { // Client wants to be connected + if (spinBLEClient.myBLEDevices[i].advertisedDevice) { // Client is assigned + // If this device is advertising HR service AND not advertising FTMS service AND there is no connected PM AND the next slot is set to connect, connect that one first + // and connect the HRM last. if (spinBLEClient.myBLEDevices[i].advertisedDevice->isAdvertisingService(HEARTSERVICE_UUID) && + // (!spinBLEClient.myBLEDevices[i].advertisedDevice->isAdvertisingService(FITNESSMACHINESERVICE_UUID)) && (!connectedPM) && + // (spinBLEClient.myBLEDevices[i + 1].doConnect == true)) { + // myDevice = spinBLEClient.myBLEDevices[i + 1].advertisedDevice; + // device_number = i + 1; + // SS2K_LOG(BLE_CLIENT_LOG_TAG, "Connecting HRM last."); + // } else { + myDevice = spinBLEClient.myBLEDevices[i].advertisedDevice; + device_number = i; + // } + break; + } else { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "doConnect and client out of alignment. Resetting device slot."); + spinBLEClient.myBLEDevices[i].reset(); + return false; + } + } else { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "doConnect on slot %d not set", i); + } + } + if (myDevice == nullptr) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "No Device Found to Connect"); + return false; + } + // FUTURE - Iterate through an array of UUID's we support instead of all the if checks. + if (myDevice->getServiceUUIDCount() > 0) { + if (myDevice->isAdvertisingService(FLYWHEEL_UART_SERVICE_UUID) && (myDevice->getName() == FLYWHEEL_BLE_NAME)) { + serviceUUID = FLYWHEEL_UART_SERVICE_UUID; + charUUID = FLYWHEEL_UART_TX_UUID; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "trying to connect to Flywheel Bike"); + } else if (myDevice->isAdvertisingService(FITNESSMACHINESERVICE_UUID)) { + serviceUUID = FITNESSMACHINESERVICE_UUID; + charUUID = FITNESSMACHINEINDOORBIKEDATA_UUID; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "trying to connect to Fitness Machine Service"); + } else if (myDevice->isAdvertisingService(CYCLINGPOWERSERVICE_UUID)) { + serviceUUID = CYCLINGPOWERSERVICE_UUID; + charUUID = CYCLINGPOWERMEASUREMENT_UUID; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "trying to connect to Cycling Power Service"); + } else if (myDevice->isAdvertisingService(ECHELON_DEVICE_UUID)) { + serviceUUID = ECHELON_SERVICE_UUID; + charUUID = ECHELON_DATA_UUID; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Trying to connect to Echelon Bike"); + } else if (myDevice->isAdvertisingService(HEARTSERVICE_UUID)) { + serviceUUID = HEARTSERVICE_UUID; + charUUID = HEARTCHARACTERISTIC_UUID; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Trying to connect to HRM"); + } else if (myDevice->isAdvertisingService(HID_SERVICE_UUID)) { + serviceUUID = HID_SERVICE_UUID; + charUUID = HID_REPORT_DATA_UUID; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Trying to connect to BLE HID remote"); + } else { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "No advertised UUID found"); + spinBLEClient.myBLEDevices[device_number].reset(); + return false; + } + } else { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Device has no Service UUID"); + spinBLEClient.myBLEDevices[device_number].reset(); + // spinBLEClient.serverScan(true); + return false; + } + + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Forming a connection to: %s", this->adevName2UniqueName(myDevice).c_str()); + + NimBLEClient *pClient = nullptr; + + /** Check if we have a client we should reuse first **/ + if (NimBLEDevice::getClientListSize()) { + /** Special case when we already know this device, we send false as the + * second argument in connect() to prevent refreshing the service database. + * This saves considerable time and power. + */ + pClient = NimBLEDevice::getClientByPeerAddress(myDevice->getAddress()); + if (pClient) { + pClient->setConnectTimeout(2); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Reusing Client"); + if (!pClient->connect(myDevice, false)) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Reconnect failed "); + this->reconnectTries--; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "%d left.", reconnectTries); + if (reconnectTries < 1) { + spinBLEClient.myBLEDevices[device_number].reset(); + spinBLEClient.resetDevices(pClient); + pClient->deleteServices(); + NimBLEDevice::getScan()->erase(pClient->getPeerAddress()); + NimBLEDevice::deleteClient(pClient); + } + return false; + } + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Reconnected client"); + } + /** We don't already have a client that knows this device, + * we will check for a client that is disconnected that we can use. + */ + else { + pClient = NimBLEDevice::getDisconnectedClient(); + } + } + + /** No client to reuse? Create a new one. */ + if (!pClient) { + if (NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS) { + Serial.println("Max clients reached - no more connections available"); + return false; + } + + pClient = NimBLEDevice::createClient(); + + SS2K_LOG(BLE_CLIENT_LOG_TAG, " - Created client"); + + pClient->setClientCallbacks(&myClientCallback, false); + /** Set initial connection parameters: These settings are 15ms interval, 0 latency, 120ms timout. + * These settings are safe for 3 clients to connect reliably, can go faster if you have less + * connections. Timeout should be a multiple of the interval, minimum is 100ms. + * Min interval: 12 * 1.25ms = 15, Max interval: 12 * 1.25ms = 15, 0 latency, 51 * 10ms = 510ms timeout + */ + pClient->setConnectionParams(6, 6, 0, 200); + /** Set how long we are willing to wait for the connection to complete (seconds), default is 30. */ + pClient->setConnectTimeout(5); // 5 + + if (!pClient->connect(myDevice->getAddress())) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, " - Failed to connect client"); + /** Created a client but failed to connect, don't need to keep it as it has no data */ + spinBLEClient.myBLEDevices[device_number].reset(); + pClient->deleteServices(); + NimBLEDevice::getScan()->erase(pClient->getPeerAddress()); + NimBLEDevice::deleteClient(pClient); + return false; + } + } + + if (!pClient->isConnected()) { + if (!pClient->connect(myDevice)) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to connect"); + return false; + } + } + + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Connected to: %s - %s RSSI %d", this->adevName2UniqueName(myDevice).c_str(), pClient->getPeerAddress().toString().c_str(), pClient->getRssi()); + + if (serviceUUID == HID_SERVICE_UUID) { + connectBLE_HID(pClient); + this->reconnectTries = MAX_RECONNECT_TRIES; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Successful remote subscription."); + spinBLEClient.myBLEDevices[device_number].doConnect = false; + this->reconnectTries = MAX_RECONNECT_TRIES; + spinBLEClient.myBLEDevices[device_number].set(myDevice, pClient->getConnId(), serviceUUID, charUUID); + spinBLEClient.myBLEDevices[device_number].peerAddress = pClient->getPeerAddress(); + removeDuplicates(pClient); + return true; + } + + /** Now we can read/write/subscribe the characteristics of the services we are interested in */ + NimBLERemoteService *pSvc = nullptr; + NimBLERemoteCharacteristic *pChr = nullptr; + NimBLERemoteDescriptor *pDsc = nullptr; + + pSvc = pClient->getService(serviceUUID); + if (pSvc) { /** make sure it's not null */ + pChr = pSvc->getCharacteristic(charUUID); + + if (pChr) { /** make sure it's not null */ + if (pChr->canRead()) { + NimBLEAttValue value = pChr->readValue(); + const int kLogBufMaxLength = 250; + char logBuf[kLogBufMaxLength]; + int logBufLength = ss2k_log_hex_to_buffer(value.data(), value.length(), logBuf, 0, kLogBufMaxLength); + logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " <-initial Value"); + SS2K_LOG(BLE_COMMON_LOG_TAG, "%s", logBuf); + } + if (pChr->canNotify()) { + if (!pChr->subscribe(true, onNotify)) { + /** Disconnect if subscribe failed */ + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Notifications Failed for %s", pClient->getPeerAddress().toString().c_str()); + spinBLEClient.myBLEDevices[device_number].reset(); + pClient->deleteServices(); + NimBLEDevice::getScan()->erase(pClient->getPeerAddress()); + NimBLEDevice::deleteClient(pClient); + return false; + } + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Notifications Subscribed for %s", pClient->getPeerAddress().toString().c_str()); + } else if (pChr->canIndicate()) { + /** Send false as first argument to subscribe to indications instead of notifications */ + if (!pChr->subscribe(false, onNotify)) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Indications Failed for %s", pClient->getPeerAddress().toString().c_str()); + /** Disconnect if subscribe failed */ + spinBLEClient.myBLEDevices[device_number].reset(); + pClient->deleteServices(); + NimBLEDevice::getScan()->erase(pClient->getPeerAddress()); + NimBLEDevice::deleteClient(pClient); + return false; + } + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Indications Subscribed for %s", pClient->getPeerAddress().toString().c_str()); + } + this->reconnectTries = MAX_RECONNECT_TRIES; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Successful %s subscription.", pChr->getUUID().toString().c_str()); + spinBLEClient.myBLEDevices[device_number].doConnect = false; + this->reconnectTries = MAX_RECONNECT_TRIES; + spinBLEClient.myBLEDevices[device_number].set(myDevice, pClient->getConnId(), serviceUUID, charUUID); + spinBLEClient.myBLEDevices[device_number].peerAddress = pClient->getPeerAddress(); + removeDuplicates(pClient); + } + + } else { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to find service: %s", serviceUUID.toString().c_str()); + } + + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Device Connected"); + return true; +} + +/** None of these are required as they will be handled by the library with defaults. ** + ** Remove as you see fit for your needs */ + +void MyClientCallback::onConnect(NimBLEClient *pClient) { + // additional characteristic subscriptions. +} + +void MyClientCallback::onDisconnect(NimBLEClient *pClient) { + if (!pClient->isConnected()) { + NimBLEAddress addr = pClient->getPeerAddress(); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "This disconnected client Address %s", addr.toString().c_str()); + for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { + if (addr == spinBLEClient.myBLEDevices[i].peerAddress) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Detected %s Disconnect", spinBLEClient.myBLEDevices[i].serviceUUID.toString().c_str()); + // did another task disconnect this device? + if (!spinBLEClient.intentionalDisconnect) { + spinBLEClient.myBLEDevices[i].doConnect = true; + } else { + spinBLEClient.intentionalDisconnect--; + } + 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) || + (spinBLEClient.myBLEDevices[i].charUUID == CYCLINGPOWERSERVICE_UUID)) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Deregistered PM on Disconnect"); + rtConfig->pm_batt.setValue(0); + } + if ((spinBLEClient.myBLEDevices[i].charUUID == HEARTCHARACTERISTIC_UUID)) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Deregistered HR on Disconnect"); + rtConfig->hr_batt.setValue(0); + } + if ((spinBLEClient.myBLEDevices[i].charUUID == HID_REPORT_DATA_UUID)) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Deregistered Remote on Disconnect"); + } + spinBLEClient.myBLEDevices[i].reset(); + } + } + return; + } +} + +/***************** New - Security handled here ******************** +****** Note: these are the same return values as defaults ********/ +uint32_t MyClientCallback::onPassKeyRequest() { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Client PassKeyRequest"); + return 123456; +} +bool MyClientCallback::onConfirmPIN(uint32_t pass_key) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "The passkey YES/NO number: %ud", pass_key); + return true; +} + +void MyClientCallback::onAuthenticationComplete(ble_gap_conn_desc desc) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Starting BLE work!"); } +/*******************************************************************/ + +/** + * Scan for BLE servers and find the first one that advertises the service we are looking for. + */ + +void MyAdvertisedDeviceCallback::onResult(BLEAdvertisedDevice *advertisedDevice) { + // Define granular constants for maximal reuse during logging + const char *const MATCHED = "Matched "; + const char *const DIDNT_MATCH_THE_SAVED = " didn't match the saved: "; + const char *const STRING_MATCHED_ANY = " String Matched Any"; + const char *const THIS = "This "; + const char *const NAME = "Name "; + const char *const ADDRESS = "Address "; + const char *const REMOTE = "Remote"; + const char *const HRM = "HRM"; + const char *const PM = "PM"; + String aDevName = spinBLEClient.adevName2UniqueName(advertisedDevice); + const char *aDevAddr = advertisedDevice->getAddress().toString().c_str(); + + if ((advertisedDevice->haveServiceUUID()) && (advertisedDevice->isAdvertisingService(CYCLINGPOWERSERVICE_UUID) || + (advertisedDevice->isAdvertisingService(FLYWHEEL_UART_SERVICE_UUID) && aDevName == String(FLYWHEEL_BLE_NAME)) || + advertisedDevice->isAdvertisingService(FITNESSMACHINESERVICE_UUID) || advertisedDevice->isAdvertisingService(HEARTSERVICE_UUID) || + advertisedDevice->isAdvertisingService(ECHELON_DEVICE_UUID) || advertisedDevice->isAdvertisingService(HID_SERVICE_UUID))) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Trying to match found device name: %s", aDevName.c_str()); + + // Handling for BLE connected remotes + if (advertisedDevice->getServiceUUID() == HID_SERVICE_UUID) { + if (strcmp(userConfig->getConnectedRemote(), "any") == 0) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s", REMOTE, STRING_MATCHED_ANY); + } else { + bool nameMatched = (aDevName = userConfig->getConnectedRemote()) ? true : false; + bool addrMatched = strcmp(aDevAddr, userConfig->getConnectedRemote()) == 0; + if (!nameMatched && !addrMatched || strcmp(userConfig->getConnectedRemote(), "none") == 0) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s%s%s", THIS, REMOTE, DIDNT_MATCH_THE_SAVED, userConfig->getConnectedRemote()); + return; // Ignore this device; + } else { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s %s%s", REMOTE, NAME, MATCHED, aDevName); + } + } + } else if (advertisedDevice->getServiceUUID() == HEARTSERVICE_UUID) { + if (strcmp(userConfig->getConnectedHeartMonitor(), "any") == 0) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s", HRM, STRING_MATCHED_ANY); + } else { + bool nameMatched = (aDevName == userConfig->getConnectedHeartMonitor()) ? true : false; + bool addrMatched = strcmp(aDevAddr, userConfig->getConnectedHeartMonitor()) == 0; + if (!nameMatched && !addrMatched || strcmp(userConfig->getConnectedHeartMonitor(), "none") == 0) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s%s%s", THIS, HRM, DIDNT_MATCH_THE_SAVED, userConfig->getConnectedHeartMonitor()); + return; // Ignore this device; + } else { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s %s%s", HRM, NAME, MATCHED, aDevName); + } + } + } else { + // Power Meter + if (strcmp(userConfig->getConnectedPowerMeter(), "any") == 0) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s", PM, STRING_MATCHED_ANY); + } else { + bool nameMatched = (aDevName == userConfig->getConnectedPowerMeter()) ? true : false; + if (!nameMatched || strcmp(userConfig->getConnectedPowerMeter(), "none") == 0) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s%s%s", THIS, PM, DIDNT_MATCH_THE_SAVED, userConfig->getConnectedPowerMeter()); + return; // Ignore this device; + } else { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s %s%s", PM, NAME, MATCHED, aDevName); + } + } + } + + for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { + if ((spinBLEClient.myBLEDevices[i].advertisedDevice == nullptr) || (advertisedDevice->getAddress() == spinBLEClient.myBLEDevices[i].peerAddress)) { + spinBLEClient.myBLEDevices[i].set(advertisedDevice, BLE_HS_CONN_HANDLE_NONE, advertisedDevice->getServiceUUID()); + spinBLEClient.myBLEDevices[i].doConnect = true; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "doConnect set on device: %d", i); + return; + } + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Checking Slot %d", i); + } + } +} + +void SpinBLEClient::scanProcess(int duration) { + this->doScan = false; // Confirming we did the scan + + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Scanning for BLE servers and putting them into a list..."); + + BLEScan *pBLEScan = BLEDevice::getScan(); + pBLEScan->stop(); + vTaskDelay(50 / portTICK_PERIOD_MS); + pBLEScan->clearDuplicateCache(); + pBLEScan->clearResults(); + pBLEScan->setAdvertisedDeviceCallbacks(&myAdvertisedDeviceCallbacks); + pBLEScan->setInterval(49); // 97 + pBLEScan->setWindow(33); // 67 + pBLEScan->setDuplicateFilter(true); + pBLEScan->setActiveScan(true); // might cause memory leak if true - undetermined. We don't get device names without it. + BLEScanResults foundDevices = pBLEScan->start(duration, false); + this->dontBlockScan = false; + + int count = foundDevices.getCount(); + + StaticJsonDocument<1000> devices; + + // Check if 'devices' JSON document already exists and has content; if so, deserialize it. + const char *foundDevicesJson = userConfig->getFoundDevices(); + if (foundDevicesJson[0] != '\0') { + deserializeJson(devices, userConfig->getFoundDevices()); + } + + for (int i = 0; i < count; i++) { + BLEAdvertisedDevice d = foundDevices.getDevice(i); + + // Check for duplicates by name or address before adding + bool isDuplicate = false; + for (JsonPair kv : devices.as()) { + JsonObject obj = kv.value().as(); + if (obj.containsKey("name") && obj["name"] == this->adevName2UniqueName(&d)) { + isDuplicate = true; + break; + } + } + + // is this device advertising something we're interested in? + if (!isDuplicate && (d.isAdvertisingService(CYCLINGPOWERSERVICE_UUID) || d.isAdvertisingService(HEARTSERVICE_UUID) || d.isAdvertisingService(FLYWHEEL_UART_SERVICE_UUID) || + d.isAdvertisingService(FITNESSMACHINESERVICE_UUID) || d.isAdvertisingService(ECHELON_DEVICE_UUID) || d.isAdvertisingService(HID_SERVICE_UUID))) { + String device = "device " + String(devices.size()); // Use the current size to index the new device + + devices[device]["name"] = this->adevName2UniqueName(&d); + + // Workaround for IC4 not advertising FTMS as the first service. + // Potentially others may need to be added in the future. + // The symptom was the bike name not showing up in the HTML. + if (d.haveServiceUUID() && d.isAdvertisingService(FITNESSMACHINESERVICE_UUID)) { + devices[device]["UUID"] = FITNESSMACHINESERVICE_UUID.toString(); + } else { + devices[device]["UUID"] = d.getServiceUUID().toString(); + } + } + } + + String output; + serializeJson(devices, output); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Bluetooth Client Found Devices: %s", output.c_str()); +#ifdef USE_TELEGRAM + SEND_TO_TELEGRAM("Bluetooth Client Found Devices: " + output); +#endif + userConfig->setFoundDevices(output); // Save the updated JSON document +} + +// remove the last connected BLE Power Meter +void SpinBLEClient::removeDuplicates(NimBLEClient *pClient) { + // BLEAddress thisAddress = pClient->getPeerAddress(); + SpinBLEAdvertisedDevice tBLEd; + SpinBLEAdvertisedDevice oldBLEd; + for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { // Disconnect oldest PM to avoid two connected. + tBLEd = this->myBLEDevices[i]; + if (tBLEd.peerAddress == pClient->getPeerAddress()) { + break; + } + } + + for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { // Disconnect oldest PM to avoid two connected. + oldBLEd = this->myBLEDevices[i]; + if (oldBLEd.advertisedDevice) { + if ((tBLEd.serviceUUID == oldBLEd.serviceUUID) && (tBLEd.peerAddress != oldBLEd.peerAddress)) { + if (BLEDevice::getClientByPeerAddress(oldBLEd.peerAddress)) { + if (BLEDevice::getClientByPeerAddress(oldBLEd.peerAddress)->isConnected()) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s Matched another service. Disconnecting: %s", tBLEd.peerAddress.toString().c_str(), oldBLEd.peerAddress.toString().c_str()); + NimBLEDevice::deleteClient(BLEDevice::getClientByPeerAddress(oldBLEd.peerAddress)); + oldBLEd.reset(); + spinBLEClient.intentionalDisconnect++; + return; + } + } + } + } + } +} + +void SpinBLEClient::resetDevices(NimBLEClient *pClient) { + for (auto &_BLEd : spinBLEClient.myBLEDevices) { + if (pClient->getPeerAddress() == _BLEd.peerAddress) { + SS2K_LOGW(BLE_CLIENT_LOG_TAG, "Reset Client: %s", _BLEd.peerAddress.toString().c_str()); + _BLEd.reset(); + } + } +} + +// Control a connected FTMS trainer. If no args are passed, treat it like an external stepper motor. +void SpinBLEClient::FTMSControlPointWrite(const uint8_t *pData, int length) { + if (userConfig->getFTMSControlPointWrite()) { + NimBLEClient *pClient = nullptr; + uint8_t modData[7]; + for (int i = 0; i < length; i++) { + modData[i] = pData[i]; + } + for (int i = 0; i < NUM_BLE_DEVICES; i++) { + if (myBLEDevices[i].getPostConnected() && (myBLEDevices[i].serviceUUID == FITNESSMACHINESERVICE_UUID)) { + if (NimBLEDevice::getClientByPeerAddress(myBLEDevices[i].peerAddress)->getService(FITNESSMACHINESERVICE_UUID)) { + pClient = NimBLEDevice::getClientByPeerAddress(myBLEDevices[i].peerAddress); + break; + } + } + } + if (pClient) { + NimBLERemoteCharacteristic *writeCharacteristic = pClient->getService(FITNESSMACHINESERVICE_UUID)->getCharacteristic(FITNESSMACHINECONTROLPOINT_UUID); + int logBufLength = 0; + if (writeCharacteristic) { + const int kLogBufCapacity = length + 40; + char logBuf[kLogBufCapacity]; + if (modData[0] == FitnessMachineControlPointProcedure::SetIndoorBikeSimulationParameters) { // use virtual Shifting + int incline = ss2k->getTargetPosition() / userConfig->getInclineMultiplier(); + modData[3] = (uint8_t)(incline & 0xff); + modData[4] = (uint8_t)(incline >> 8); + writeCharacteristic->writeValue(modData, length); + logBufLength = ss2k_log_hex_to_buffer(modData, length, logBuf, 0, kLogBufCapacity); + logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> Shifted Sim Data: %d", rtConfig->getShifterPosition()); + } else { + writeCharacteristic->writeValue(modData, length); + logBufLength = ss2k_log_hex_to_buffer(modData, length, logBuf, 0, kLogBufCapacity); + logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> Shifted ERG Data: %d", rtConfig->getShifterPosition()); + } + SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s", logBuf); + } + } + } +} + +void SpinBLEClient::postConnect() { + for (auto &_BLEd : spinBLEClient.myBLEDevices) { + // Check that the device has been assigned and it hasn't been post connected. + if ((_BLEd.connectedClientID != BLE_HS_CONN_HANDLE_NONE) && !_BLEd.getPostConnected()) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Post connecting: %s , ConnID %d", _BLEd.peerAddress.toString().c_str(), _BLEd.connectedClientID); + if (NimBLEDevice::getClientByPeerAddress(_BLEd.peerAddress)) { + _BLEd.setPostConnected(true); + NimBLEClient *pClient = NimBLEDevice::getClientByPeerAddress(_BLEd.peerAddress); + if (_BLEd.charUUID == ECHELON_DATA_UUID) { + NimBLERemoteCharacteristic *writeCharacteristic = pClient->getService(ECHELON_SERVICE_UUID)->getCharacteristic(ECHELON_WRITE_UUID); + if (writeCharacteristic == nullptr) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to find Echelon write characteristic UUID: %s", ECHELON_WRITE_UUID.toString().c_str()); + pClient->disconnect(); + return; + } + // Enable device notifications + byte message[] = {0xF0, 0xB0, 0x01, 0x01, 0xA2}; + writeCharacteristic->writeValue(message, 5); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Activated Echelon callbacks."); + rtConfig->setMinResistance(MIN_ECHELON_RESISTANCE); + rtConfig->setMaxResistance(MAX_ECHELON_RESISTANCE); + } + + if ((_BLEd.charUUID == FITNESSMACHINEINDOORBIKEDATA_UUID)) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Updating Connection Params for: %s", _BLEd.peerAddress.toString().c_str()); + BLEDevice::getServer()->updateConnParams(pClient->getConnId(), 100, 100, 2, 1000); + spinBLEClient.handleBattInfo(pClient, true); + + auto featuresCharacteristic = pClient->getService(FITNESSMACHINESERVICE_UUID)->getCharacteristic(FITNESSMACHINEFEATURE_UUID); + if (featuresCharacteristic == nullptr) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to find FTMS features characteristic UUID: %s", FITNESSMACHINEFEATURE_UUID.toString().c_str()); + return; + } + + if (featuresCharacteristic->canRead()) { + auto value = featuresCharacteristic->readValue(); + if (value.size() < sizeof(uint64_t)) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to read FTMS features characteristic"); + return; + } + + // We're only interested in the machine fitness features, not the target setting features. + auto features = *reinterpret_cast(value.data()); + if (!(features & FitnessMachineFeatureFlags::Types::ElapsedTimeSupported) || !(features & FitnessMachineFeatureFlags::Types::RemainingTimeSupported)) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "FTMS Control Point StartOrResume not supported"); + return; + } + } + + NimBLERemoteCharacteristic *writeCharacteristic = pClient->getService(FITNESSMACHINESERVICE_UUID)->getCharacteristic(FITNESSMACHINECONTROLPOINT_UUID); + if (writeCharacteristic == nullptr) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to find FTMS control characteristic UUID: %s", FITNESSMACHINECONTROLPOINT_UUID.toString().c_str()); + return; + } + + // If we would like to control an external FTMS trainer. With most spin bikes we would want this off, but it's useful if you want to use the SmartSpin2k as an + // appliance. + if (userConfig->getFTMSControlPointWrite()) { + writeCharacteristic->writeValue(FitnessMachineControlPointProcedure::RequestControl, 1); + vTaskDelay(BLE_NOTIFY_DELAY / portTICK_PERIOD_MS); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Activated FTMS Training."); + } + writeCharacteristic->writeValue(FitnessMachineControlPointProcedure::StartOrResume, 1); + } + } + } + } +} + +bool SpinBLEAdvertisedDevice::enqueueData(uint8_t *data, size_t length) { + NotifyData notifyData; + + if (!uxQueueSpacesAvailable(this->dataBufferQueue)) { + // Serial.println("No space available in queue. Skipping enqueue of data."); + return pdFALSE; + } + + notifyData.length = length; + for (size_t i = 0; i < length; i++) { + notifyData.data[i] = data[i]; + // Serial.printf("%02x ", notifyData.data[i]); + } + // Serial.printf("\n"); + + if (xQueueSendToBack(this->dataBufferQueue, ¬ifyData, 10) == pdFALSE) { + // Serial.println("Failed to enqueue data. Freeing data."); + return pdFALSE; + } + // Serial.printf("Successfully enqueued data. %d. \n", notifyData.length); + return pdTRUE; +} + +NotifyData SpinBLEAdvertisedDevice::dequeueData() { + NotifyData receivedNotifyData; + if (this->dataBufferQueue == nullptr) { + // Serial.println("Queue not created. Skipping dequeue of data."); + receivedNotifyData.length = 0; + return receivedNotifyData; + } + if (xQueueReceive(this->dataBufferQueue, &receivedNotifyData, 0) == pdTRUE) { + // Serial.printf("Successfully dequeued data from queue. %d \n", receivedNotifyData.length); + return receivedNotifyData; + } + // Serial.println("buffer was empty"); + receivedNotifyData.length = 0; + return receivedNotifyData; +} + +// Was changed in notify-Buffer - - may not be needed ********************************************************************** +void SpinBLEAdvertisedDevice::print() { + char logBuf[250]; + char *logBufP = logBuf; + logBufP += sprintf(logBufP, "Address: (%s)", peerAddress.toString().c_str()); + logBufP += sprintf(logBufP, " Client ID: (%d)", connectedClientID); + logBufP += sprintf(logBufP, " SerUUID: (%s)", serviceUUID.toString().c_str()); + logBufP += sprintf(logBufP, " CharUUID: (%s)", charUUID.toString().c_str()); + logBufP += sprintf(logBufP, " HRM: (%s)", isHRM ? "true" : "false"); + logBufP += sprintf(logBufP, " PM: (%s)", isPM ? "true" : "false"); + logBufP += sprintf(logBufP, " CSC: (%s)", isCSC ? "true" : "false"); + logBufP += sprintf(logBufP, " CT: (%s)", isCT ? "true" : "false"); + logBufP += sprintf(logBufP, " doConnect: (%s)", doConnect ? "true" : "false"); + strcat(logBufP, "|"); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s", String(logBuf)); +} + +void SpinBLEClient::connectBLE_HID(NimBLEClient *pClient) { + NimBLERemoteService *pSvc = nullptr; + NimBLERemoteCharacteristic *pChr = nullptr; + pSvc = pClient->getService(HID_SERVICE_UUID); + if (pSvc) { /** make sure it's not null */ + // This returns the HID report descriptor like this + // HID_REPORT_MAP 0x2a4b Value: 5,1,9,2,A1,1,9,1,A1,0,5,9,19,1,29,5,15,0,25,1,75,1, + // Copy and paste the value digits to http://eleccelerator.com/usbdescreqparser/ + // to see the decoded report descriptor. + /*pChr = pSvc->getCharacteristic(HID_REPORT_MAP_UUID); + if (pChr) { /** make sure it's not null */ + /* Serial.print("HID_REPORT_MAP "); + if (pChr->canRead()) { + std::string value = pChr->readValue(); + Serial.print(pChr->getUUID().toString().c_str()); + Serial.print(" Value: "); + uint8_t *p = (uint8_t *)value.data(); + for (size_t i = 0; i < value.length(); i++) { + Serial.print(p[i], HEX); + Serial.print(','); + } + Serial.println(); + } + } else { + Serial.println("HID REPORT MAP char not found."); + } +*/ + // Subscribe to characteristics HID_REPORT_DATA. + // One real device reports 2 with the same UUID but + // different handles. Using getCharacteristic() results + // in subscribing to only one. + std::vector *charVector; + charVector = pSvc->getCharacteristics(true); + for (auto &it : *charVector) { + if (it->getUUID() == NimBLEUUID(HID_REPORT_DATA_UUID)) { + Serial.println(it->toString().c_str()); + if (it->canNotify()) { + if (!it->subscribe(true, onNotify)) { + /** Disconnect if subscribe failed */ + Serial.println("subscribe notification failed"); + NimBLEDevice::deleteClient(pClient); + return; // false; + } else { + Serial.println("subscribed"); + } + } + } + } + } + Serial.println("Done with this device!"); + return; // true; +} + +void SpinBLEClient::keepAliveBLE_HID(NimBLEClient *pClient) { + static int intervalTimer = millis(); + if ((millis() - intervalTimer) < 6000) { + return; + } + NimBLERemoteService *pSvc = nullptr; + NimBLERemoteCharacteristic *pChr = nullptr; + pSvc = pClient->getService(HID_SERVICE_UUID); + if (pSvc) { /** make sure it's not null */ + pChr = pSvc->getCharacteristic(HID_REPORT_MAP_UUID); + if (pChr) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "BLE HID Keep Alive"); + pClient->setConnectionParams(12, 12, 0, 3200); + intervalTimer = millis(); + } else { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Keep Alive failed"); + } + } +} + +void SpinBLEClient::checkBLEReconnect() { + if ((String(userConfig->getConnectedHeartMonitor()) != "none") && !(spinBLEClient.connectedHRM)) { + this->doScan = true; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "No HRM Connected"); + } + if ((String(userConfig->getConnectedPowerMeter()) != "none") && !(spinBLEClient.connectedPM)) { + this->doScan = true; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "No PM Connected"); + } + if ((String(userConfig->getConnectedRemote()) != "none") && !(spinBLEClient.connectedRemote)) { + this->doScan = true; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "No Rem Connected"); + } +} + +void SpinBLEClient::reconnectAllDevices() { + for (auto i : spinBLEClient.myBLEDevices) { + if (NimBLEDevice::getClientByPeerAddress(i.peerAddress)) { + if (NimBLEDevice::getClientByPeerAddress(i.peerAddress)->isConnected()) { + NimBLEDevice::getClientByPeerAddress(i.peerAddress)->disconnect(); + i.reset(); + spinBLEClient.intentionalDisconnect++; + } + } + } +} + +// Poll BLE devices for battCharacteristic if available and read value. +void SpinBLEClient::handleBattInfo(NimBLEClient *pClient, bool updateNow = false) { + static unsigned long last_battery_update = 0; + if ((millis() - last_battery_update >= BATTERY_UPDATE_INTERVAL_MILLIS) || (last_battery_update == 0) || updateNow) { + last_battery_update = millis(); + if (pClient->getService(HEARTSERVICE_UUID) && pClient->getService(BATTERYSERVICE_UUID)) { // get battery level at first connect + BLERemoteCharacteristic *battCharacteristic = pClient->getService(BATTERYSERVICE_UUID)->getCharacteristic(BATTERYCHARACTERISTIC_UUID); + if (battCharacteristic != nullptr) { + std::string value = battCharacteristic->readValue(); + rtConfig->hr_batt.setValue((uint8_t)value[0]); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "HRM battery updated %d", (int)value[0]); + } else { + rtConfig->hr_batt.setValue(0); + } + } else if ((pClient->getService(CYCLINGPOWERMEASUREMENT_UUID) || pClient->getService(CYCLINGPOWERSERVICE_UUID)) && + pClient->getService(BATTERYSERVICE_UUID)) { // get batterylevel at first connect + BLERemoteCharacteristic *battCharacteristic = pClient->getService(BATTERYSERVICE_UUID)->getCharacteristic(BATTERYCHARACTERISTIC_UUID); + if (battCharacteristic != nullptr) { + std::string value = battCharacteristic->readValue(); + rtConfig->pm_batt.setValue((uint8_t)value[0]); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "PM battery updated %d", (int)value[0]); + } else { + rtConfig->pm_batt.setValue(0); + } + } + } +} +// Returns a device name with the las two of the peer address attached. This lets us distinguish between multiple devices with the same device name. +String SpinBLEClient::adevName2UniqueName(NimBLEAdvertisedDevice *inDev) { + if (inDev->haveName()) { + String _outDevName = String(inDev->getName().c_str()); + // add the last two of the string + _outDevName += +" " + String(inDev->getAddress().toString().c_str()).substring(inDev->getAddress().toString().length() - 2); + return _outDevName; + } else { + String _outDevName = inDev->getAddress().toString().c_str(); + return _outDevName; + } +} + +void SpinBLEAdvertisedDevice::set(BLEAdvertisedDevice *device, int id, BLEUUID inServiceUUID, BLEUUID inCharUUID) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Setting Device %s", device->getAddress().toString().c_str()); + this->advertisedDevice = device; + this->peerAddress = device->getAddress(); + this->connectedClientID = id; + this->serviceUUID = BLEUUID(inServiceUUID); + this->charUUID = BLEUUID(inCharUUID); + this->dataBufferQueue = xQueueCreate(4, sizeof(NotifyData)); + if (inServiceUUID == HEARTSERVICE_UUID) { + this->isHRM = true; + spinBLEClient.connectedHRM = true; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered HRM on Connect"); + } else if (inServiceUUID == CSCSERVICE_UUID) { + this->isCSC = true; + spinBLEClient.connectedCD = true; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered CSC on Connect"); + } else if (inServiceUUID == CYCLINGPOWERSERVICE_UUID || inServiceUUID == FITNESSMACHINESERVICE_UUID || inServiceUUID == FLYWHEEL_UART_SERVICE_UUID || + inServiceUUID == ECHELON_SERVICE_UUID || inServiceUUID == PELOTON_DATA_UUID) { + this->isPM = true; + spinBLEClient.connectedPM = true; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered PM on Connect"); + } else if (inServiceUUID == HID_SERVICE_UUID) { + this->isRemote = true; + spinBLEClient.connectedRemote = true; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered Remote on Connect"); + } else { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to set service!"); + } +} + +void SpinBLEAdvertisedDevice::reset() { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Resetting Device: %d", this->connectedClientID); + if (this->isHRM) spinBLEClient.connectedHRM = false; + if (this->isPM) spinBLEClient.connectedPM = false; + if (this->isCSC) spinBLEClient.connectedCD = false; + spinBLEClient.connectedSpeed = false; + advertisedDevice = nullptr; + // NimBLEAddress peerAddress; + this->connectedClientID = BLE_HS_CONN_HANDLE_NONE; + this->serviceUUID = (uint16_t)0x0000; + this->charUUID = (uint16_t)0x0000; + this->isHRM = false; // Heart Rate Monitor + this->isPM = false; // Power Meter + this->isCSC = false; // Cycling Speed/Cadence + this->isCT = false; // Controllable Trainer + this->isRemote = false; // BLE Remote + this->doConnect = false; // Initiate connection flag + this->isPostConnected = false; // Has Post Connect Been Run? + if (this->dataBufferQueue != nullptr) { + // Serial.println("Resetting queue"); + xQueueReset(this->dataBufferQueue); + } +} From e9b6f423bc00b4e4aa8e88fe273a9bcaf5a72398 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Sun, 2 Feb 2025 22:17:26 -0600 Subject: [PATCH 039/451] averaged out failed neighbor target position and current position if current and failed are within a specific range --- src/ERG_Mode.cpp | 145 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 134 insertions(+), 11 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index af99ad07..4bc755b5 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -341,7 +341,7 @@ TestResults PowerTable::testNeighbors(int i, int j, int testValue) { returnResult.leftNeighbor.i = i; returnResult.leftNeighbor.j = left; returnResult.leftNeighbor.found = 1; - break; + break; } } } @@ -796,28 +796,150 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { // test which bit fields didn't match if (!testResults.leftNeighbor.passedTest) { - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, + if(testResults.leftNeighbor.j == k){ //if they are the same cadence + SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed but have same cadence, left targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, targetPosition); + if((testResults.leftNeighbor.targetPosition+5) >= targetPosition || (testResults.leftNeighbor.targetPosition+5) <= targetPosition){ + float averagedPosition = float(targetPosition + testResults.leftNeighbor.targetPosition) / 2.0f; + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].targetPosition = averagedPosition; + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence match: Averaged position for Left neighbor: (%d)(%d) new targetPosition: %f", testResults.leftNeighbor.i, testResults.leftNeighbor.j, averagedPosition); + } + }else { + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + } } + if (!testResults.rightNeighbor.passedTest) { - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, - testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + if(testResults.rightNeighbor.j == k) //if they are the same cadence + { SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed but have same cadence, right targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, targetPosition); + if((testResults.rightNeighbor.targetPosition+5) >= targetPosition || (testResults.rightNeighbor.targetPosition+5) <= targetPosition){ + float averagedPosition = float(targetPosition + testResults.rightNeighbor.targetPosition) / 2.0f; + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].targetPosition = averagedPosition; + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence match: Averaged position for Left neighbor: (%d)(%d) new targetPosition: %f", testResults.rightNeighbor.i, testResults.rightNeighbor.j, averagedPosition); + } + }else { + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.rightNeighbor.targetPosition, + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + } } + if (!testResults.topNeighbor.passedTest) { - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, + if(testResults.topNeighbor.j == k) //if they are the same cadence + { SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed but have same cadence, top targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, ss2k->getCurrentPosition()); + if((testResults.topNeighbor.targetPosition+5) >= targetPosition || (testResults.topNeighbor.targetPosition+5)<= targetPosition){ + float averagedPosition = float(targetPosition + testResults.topNeighbor.targetPosition) / 2.0f; + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].targetPosition = averagedPosition; + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence match: Averaged position for Left neighbor: (%d)(%d) new targetPosition: %f", testResults.topNeighbor.i, testResults.topNeighbor.j, averagedPosition); + } + }else { + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + } } + if (!testResults.bottomNeighbor.passedTest) { - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, - testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + if(testResults.bottomNeighbor.j == k) //if they are the same cadence + { SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed but have same cadence, bottom targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, targetPosition); + if((testResults.bottomNeighbor.targetPosition+5) >= targetPosition || (testResults.bottomNeighbor.targetPosition+5) <= targetPosition){ + float averagedPosition = float(targetPosition + testResults.bottomNeighbor.targetPosition) / 2.0f; + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].targetPosition = averagedPosition; + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence match: Averaged position for Left neighbor: (%d)(%d) new targetPosition: %f", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, averagedPosition); + } + }else { + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.bottomNeighbor.targetPosition, + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + } } return; } + /* + // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table +TestResults testResults = this->testNeighbors(k, i, targetPosition); +if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { + + // Check the failed neighbors + if (!testResults.leftNeighbor.passedTest) { + if (testResults.leftNeighbor.cad == cad && abs(testResults.leftNeighbor.targetPosition - targetPosition) <= 5) { + // If cadence is the same and targetPosition is within a 5-unit range, average the positions + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].targetPosition = + (testResults.leftNeighbor.targetPosition + targetPosition) / 2.0; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT Left Neighbor Fixed (%d)(%d)(%f), averaged with current position (%f)", + testResults.leftNeighbor.i, testResults.leftNeighbor.j, + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].targetPosition, targetPosition); + } else { + // If not within range, downvote the left neighbor + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT Left Neighbor Downvoted (%d)(%d)(%f), readings now (%d)", + testResults.leftNeighbor.i, testResults.leftNeighbor.j, + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].targetPosition, + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + } + } + + if (!testResults.rightNeighbor.passedTest) { + if (testResults.rightNeighbor.cad == cad && abs(testResults.rightNeighbor.targetPosition - targetPosition) <= 5) { + // If cadence is the same and targetPosition is within a 5-unit range, average the positions + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].targetPosition = + (testResults.rightNeighbor.targetPosition + targetPosition) / 2.0; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT Right Neighbor Fixed (%d)(%d)(%f), averaged with current position (%f)", + testResults.rightNeighbor.i, testResults.rightNeighbor.j, + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].targetPosition, targetPosition); + } else { + // If not within range, downvote the right neighbor + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT Right Neighbor Downvoted (%d)(%d)(%f), readings now (%d)", + testResults.rightNeighbor.i, testResults.rightNeighbor.j, + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].targetPosition, + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + } + } + + if (!testResults.topNeighbor.passedTest) { + if (testResults.topNeighbor.cad == cad && abs(testResults.topNeighbor.targetPosition - targetPosition) <= 5) { + // If cadence is the same and targetPosition is within a 5-unit range, average the positions + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].targetPosition = + (testResults.topNeighbor.targetPosition + targetPosition) / 2.0; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT Top Neighbor Fixed (%d)(%d)(%f), averaged with current position (%f)", + testResults.topNeighbor.i, testResults.topNeighbor.j, + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].targetPosition, targetPosition); + } else { + // If not within range, downvote the top neighbor + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT Top Neighbor Downvoted (%d)(%d)(%f), readings now (%d)", + testResults.topNeighbor.i, testResults.topNeighbor.j, + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].targetPosition, + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + } + } + + if (!testResults.bottomNeighbor.passedTest) { + if (testResults.bottomNeighbor.cad == cad && abs(testResults.bottomNeighbor.targetPosition - targetPosition) <= 5) { + // If cadence is the same and targetPosition is within a 5-unit range, average the positions + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].targetPosition = + (testResults.bottomNeighbor.targetPosition + targetPosition) / 2.0; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT Bottom Neighbor Fixed (%d)(%d)(%f), averaged with current position (%f)", + testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].targetPosition, targetPosition); + } else { + // If not within range, downvote the bottom neighbor + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT Bottom Neighbor Downvoted (%d)(%d)(%f), readings now (%d)", + testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].targetPosition, + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + } + } + + // If none of the neighbors could be fixed, return without modifying the table + return; +}s + */ + // Update or create a new entry if (this->tableRow[k].tableEntry[i].readings == 0) { // if first reading in this entry this->tableRow[k].tableEntry[i].targetPosition = targetPosition; @@ -832,6 +954,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } } this->tableRow[k].tableEntry[i].readings++; + // Attempt to fill the table with calculated data... if (this->getNumEntries() > 4) { int entries = 0; From b627264d263b5fdb8795dfeb69f4f7f56d087a98 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Mon, 3 Feb 2025 17:41:42 -0600 Subject: [PATCH 040/451] added constraints for entering averageposition --- src/ERG_Mode.cpp | 182 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 180 insertions(+), 2 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 4bc755b5..d5c484b9 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -791,6 +791,183 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { return; } + // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table + TestResults testResults = this->testNeighbors(k, i, targetPosition); + if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { + // test which bit fields didn't match + if (!testResults.leftNeighbor.passedTest) { + if(testResults.leftNeighbor.j == k && ((testResults.leftNeighbor.targetPosition+5) >= (int)targetPosition && (testResults.leftNeighbor.targetPosition-5) <= (int)targetPosition)){ //if they are the same cadence + SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed but have same cadence, left targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, (int)targetPosition); + + int averagedPosition = ((int)targetPosition + testResults.leftNeighbor.targetPosition) / 2; + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position: %d", averagedPosition); + if(this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, averagedPosition).allNeighborsPassed){ + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].targetPosition = averagedPosition; + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence match: Averaged position for Left neighbor: (%d)(%d) new targetPosition: %d", testResults.leftNeighbor.i, testResults.leftNeighbor.j, averagedPosition); + }else{ + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + } + }else { + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + } + } + + if (!testResults.rightNeighbor.passedTest) { + if(testResults.rightNeighbor.j == k && ((testResults.rightNeighbor.targetPosition+5) >= (int)targetPosition && (testResults.rightNeighbor.targetPosition-5) <= (int)targetPosition)) //if they are the same cadence + { SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed but have same cadence, right targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, (int)targetPosition); + int averagedPosition = ((int)targetPosition + testResults.rightNeighbor.targetPosition) / 2; + + if(this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, averagedPosition).allNeighborsPassed){ + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].targetPosition = averagedPosition; + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence match: Averaged position for Right neighbor: (%d)(%d) new targetPosition: %d", testResults.rightNeighbor.i, testResults.rightNeighbor.j, averagedPosition); + }else{ + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.rightNeighbor.targetPosition, + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + } + + }else { + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.rightNeighbor.targetPosition, + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + } + } + + if (!testResults.topNeighbor.passedTest) { + if(testResults.topNeighbor.j == k && ((testResults.topNeighbor.targetPosition+5) >= (int)targetPosition && (testResults.topNeighbor.targetPosition-5) <= (int)targetPosition)) //if they are the same cadence + { SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed but have same cadence, top targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, (int)targetPosition); + + int averagedPosition = ((int)targetPosition + testResults.topNeighbor.targetPosition) / 2; + if(this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, averagedPosition).allNeighborsPassed){ + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].targetPosition = averagedPosition; + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence match: Averaged position for Top neighbor: (%d)(%d) new targetPosition: %d", testResults.topNeighbor.i, testResults.topNeighbor.j, averagedPosition); + }else{ + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + } + + }else { + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + } + } + + if (!testResults.bottomNeighbor.passedTest) { + if(testResults.bottomNeighbor.j == k && ((testResults.bottomNeighbor.targetPosition+5) >= (int)targetPosition && (testResults.bottomNeighbor.targetPosition-5) <= (int)targetPosition)) //if they are the same cadence + { SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed but have same cadence, bottom targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, (int)targetPosition); + if((testResults.bottomNeighbor.targetPosition+5) >= targetPosition || (testResults.bottomNeighbor.targetPosition+5) <= targetPosition){ + int averagedPosition = ((int)targetPosition + testResults.bottomNeighbor.targetPosition) / 2; + + if(this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, averagedPosition).allNeighborsPassed){ + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].targetPosition = averagedPosition; + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence match: Averaged position for Bottom neighbor: (%d)(%d) new targetPosition: %d", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, averagedPosition); + }else{ + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.bottomNeighbor.targetPosition, + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + } + } + + }else { + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.bottomNeighbor.targetPosition, + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + } + } + return; + } + + + + /*Continous loop until we find a valid entry with the failed neighbor + // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table + TestResults testResults = this->testNeighbors(k, i, targetPosition); + if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { + // test which bit fields didn't match + if (!testResults.leftNeighbor.passedTest) { + if(testResults.leftNeighbor.j == k && ((testResults.leftNeighbor.targetPosition+5) >= (int)targetPosition && (testResults.leftNeighbor.targetPosition-5) <= (int)targetPosition)){ //if they are the same cadence + SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed but have same cadence, left targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, (int)targetPosition); + + int averagedPosition = ((int)targetPosition + testResults.leftNeighbor.targetPosition) / 2; + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position: %d", averagedPosition); + + while(!(this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, averagedPosition).allNeighborsPassed)){ + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].targetPosition = averagedPosition; + this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, averagedPosition); + } + + }else { + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + } + } + + if (!testResults.rightNeighbor.passedTest) { + if(testResults.rightNeighbor.j == k && ((testResults.rightNeighbor.targetPosition+5) >= (int)targetPosition && (testResults.rightNeighbor.targetPosition-5) <= (int)targetPosition)) //if they are the same cadence + { SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed but have same cadence, right targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, (int)targetPosition); + int averagedPosition = ((int)targetPosition + testResults.rightNeighbor.targetPosition) / 2; + + while(!(this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, averagedPosition).allNeighborsPassed)){ + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].targetPosition = averagedPosition; + this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, averagedPosition); + } + + }else { + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.rightNeighbor.targetPosition, + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + } + } + + if (!testResults.topNeighbor.passedTest) { + if(testResults.topNeighbor.j == k && ((testResults.topNeighbor.targetPosition+5) >= (int)targetPosition && (testResults.topNeighbor.targetPosition-5) <= (int)targetPosition)) //if they are the same cadence + { SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed but have same cadence, top targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, (int)targetPosition); + + int averagedPosition = ((int)targetPosition + testResults.topNeighbor.targetPosition) / 2; + + while(!(this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, averagedPosition).allNeighborsPassed)){ + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].targetPosition = averagedPosition; + this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, averagedPosition); + } + + }else { + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + } + } + + if (!testResults.bottomNeighbor.passedTest) { + if(testResults.bottomNeighbor.j == k && ((testResults.bottomNeighbor.targetPosition+5) >= (int)targetPosition && (testResults.bottomNeighbor.targetPosition-5) <= (int)targetPosition)) //if they are the same cadence + { SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed but have same cadence, bottom targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, (int)targetPosition); + if((testResults.bottomNeighbor.targetPosition+5) >= targetPosition || (testResults.bottomNeighbor.targetPosition+5) <= targetPosition){ + int averagedPosition = ((int)targetPosition + testResults.bottomNeighbor.targetPosition) / 2; + + while(!(this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, averagedPosition).allNeighborsPassed)){ + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].targetPosition = averagedPosition; + this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, averagedPosition); + } + + } + + }else { + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.bottomNeighbor.targetPosition, + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + } + } + return; + } + */ + +/* Without testing neighbor of averaged value // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table TestResults testResults = this->testNeighbors(k, i, targetPosition); if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { @@ -856,6 +1033,8 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } return; } +*/ + /* // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table @@ -937,8 +1116,7 @@ if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTes // If none of the neighbors could be fixed, return without modifying the table return; -}s - */ +}*/ // Update or create a new entry if (this->tableRow[k].tableEntry[i].readings == 0) { // if first reading in this entry From c90d24e7152f455f110d98ea55bc951028a2b8c3 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Wed, 5 Feb 2025 20:08:46 -0600 Subject: [PATCH 041/451] rewrote the code to avg the failed and current data. added function for actually entering the data --- include/ERG_Mode.h | 3 + src/ERG_Mode.cpp | 378 ++++++++++----------------------------------- 2 files changed, 83 insertions(+), 298 deletions(-) diff --git a/include/ERG_Mode.h b/include/ERG_Mode.h index 4880333a..be3663c8 100644 --- a/include/ERG_Mode.h +++ b/include/ERG_Mode.h @@ -105,6 +105,9 @@ class PowerTable { // Catalogs a new entry into the power table. void newEntry(PowerBuffer& powerBuffer); + // enters data into power table + void enterData(int i, int j, float pos); + // returns incline for wattTarget. Null if not found. int32_t lookup(int watts, int cad); diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index d5c484b9..bf8bd19b 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -791,332 +791,97 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { return; } + // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table TestResults testResults = this->testNeighbors(k, i, targetPosition); if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { // test which bit fields didn't match if (!testResults.leftNeighbor.passedTest) { - if(testResults.leftNeighbor.j == k && ((testResults.leftNeighbor.targetPosition+5) >= (int)targetPosition && (testResults.leftNeighbor.targetPosition-5) <= (int)targetPosition)){ //if they are the same cadence - SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed but have same cadence, left targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, (int)targetPosition); - - int averagedPosition = ((int)targetPosition + testResults.leftNeighbor.targetPosition) / 2; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position: %d", averagedPosition); - if(this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, averagedPosition).allNeighborsPassed){ - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].targetPosition = averagedPosition; - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence match: Averaged position for Left neighbor: (%d)(%d) new targetPosition: %d", testResults.leftNeighbor.i, testResults.leftNeighbor.j, averagedPosition); - }else{ - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); - } - }else { - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); - } - } - - if (!testResults.rightNeighbor.passedTest) { - if(testResults.rightNeighbor.j == k && ((testResults.rightNeighbor.targetPosition+5) >= (int)targetPosition && (testResults.rightNeighbor.targetPosition-5) <= (int)targetPosition)) //if they are the same cadence - { SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed but have same cadence, right targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, (int)targetPosition); - int averagedPosition = ((int)targetPosition + testResults.rightNeighbor.targetPosition) / 2; - - if(this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, averagedPosition).allNeighborsPassed){ - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].targetPosition = averagedPosition; - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence match: Averaged position for Right neighbor: (%d)(%d) new targetPosition: %d", testResults.rightNeighbor.i, testResults.rightNeighbor.j, averagedPosition); - }else{ - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.rightNeighbor.targetPosition, - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); - } - - }else { - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.rightNeighbor.targetPosition, - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); - } - } - - if (!testResults.topNeighbor.passedTest) { - if(testResults.topNeighbor.j == k && ((testResults.topNeighbor.targetPosition+5) >= (int)targetPosition && (testResults.topNeighbor.targetPosition-5) <= (int)targetPosition)) //if they are the same cadence - { SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed but have same cadence, top targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, (int)targetPosition); - - int averagedPosition = ((int)targetPosition + testResults.topNeighbor.targetPosition) / 2; - if(this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, averagedPosition).allNeighborsPassed){ - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].targetPosition = averagedPosition; - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence match: Averaged position for Top neighbor: (%d)(%d) new targetPosition: %d", testResults.topNeighbor.i, testResults.topNeighbor.j, averagedPosition); - }else{ - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - } - - }else { - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - } - } - - if (!testResults.bottomNeighbor.passedTest) { - if(testResults.bottomNeighbor.j == k && ((testResults.bottomNeighbor.targetPosition+5) >= (int)targetPosition && (testResults.bottomNeighbor.targetPosition-5) <= (int)targetPosition)) //if they are the same cadence - { SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed but have same cadence, bottom targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, (int)targetPosition); - if((testResults.bottomNeighbor.targetPosition+5) >= targetPosition || (testResults.bottomNeighbor.targetPosition+5) <= targetPosition){ - int averagedPosition = ((int)targetPosition + testResults.bottomNeighbor.targetPosition) / 2; - - if(this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, averagedPosition).allNeighborsPassed){ - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].targetPosition = averagedPosition; - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence match: Averaged position for Bottom neighbor: (%d)(%d) new targetPosition: %d", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, averagedPosition); - }else{ - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.bottomNeighbor.targetPosition, - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); - } + if(testResults.leftNeighbor.i == k && (testResults.leftNeighbor.targetPosition+5 >= targetPosition && testResults.leftNeighbor.targetPosition-5 <= targetPosition)){ //check if the cadence is the same and positions are within a set range + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and targetPosition is within range"); + float avgPosition = (targetPosition + float(testResults.leftNeighbor.targetPosition)) / 2.0f; //calculate the average + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %f", avgPosition); + if(this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ //check if that new avg position with the current cad and watts passes + float leftValue = avgPosition; //store the value + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %f", leftValue); + this->enterData(k, i, leftValue); //enter the data + }else { + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left with Avg Position (%d)(%d)(%f), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, avgPosition, + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); } - - }else { - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.bottomNeighbor.targetPosition, - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); } - } - return; - } - - - - /*Continous loop until we find a valid entry with the failed neighbor - // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table - TestResults testResults = this->testNeighbors(k, i, targetPosition); - if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { - // test which bit fields didn't match - if (!testResults.leftNeighbor.passedTest) { - if(testResults.leftNeighbor.j == k && ((testResults.leftNeighbor.targetPosition+5) >= (int)targetPosition && (testResults.leftNeighbor.targetPosition-5) <= (int)targetPosition)){ //if they are the same cadence - SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed but have same cadence, left targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, (int)targetPosition); - - int averagedPosition = ((int)targetPosition + testResults.leftNeighbor.targetPosition) / 2; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position: %d", averagedPosition); - - while(!(this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, averagedPosition).allNeighborsPassed)){ - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].targetPosition = averagedPosition; - this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, averagedPosition); - } - - }else { - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, + else { //if not we still get rid of the reading + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%f), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); } } if (!testResults.rightNeighbor.passedTest) { - if(testResults.rightNeighbor.j == k && ((testResults.rightNeighbor.targetPosition+5) >= (int)targetPosition && (testResults.rightNeighbor.targetPosition-5) <= (int)targetPosition)) //if they are the same cadence - { SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed but have same cadence, right targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, (int)targetPosition); - int averagedPosition = ((int)targetPosition + testResults.rightNeighbor.targetPosition) / 2; - - while(!(this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, averagedPosition).allNeighborsPassed)){ - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].targetPosition = averagedPosition; - this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, averagedPosition); - } - - }else { - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.rightNeighbor.targetPosition, - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); - } - } - - if (!testResults.topNeighbor.passedTest) { - if(testResults.topNeighbor.j == k && ((testResults.topNeighbor.targetPosition+5) >= (int)targetPosition && (testResults.topNeighbor.targetPosition-5) <= (int)targetPosition)) //if they are the same cadence - { SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed but have same cadence, top targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, (int)targetPosition); - - int averagedPosition = ((int)targetPosition + testResults.topNeighbor.targetPosition) / 2; - - while(!(this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, averagedPosition).allNeighborsPassed)){ - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].targetPosition = averagedPosition; - this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, averagedPosition); - } - - }else { - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - } - } - - if (!testResults.bottomNeighbor.passedTest) { - if(testResults.bottomNeighbor.j == k && ((testResults.bottomNeighbor.targetPosition+5) >= (int)targetPosition && (testResults.bottomNeighbor.targetPosition-5) <= (int)targetPosition)) //if they are the same cadence - { SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed but have same cadence, bottom targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, (int)targetPosition); - if((testResults.bottomNeighbor.targetPosition+5) >= targetPosition || (testResults.bottomNeighbor.targetPosition+5) <= targetPosition){ - int averagedPosition = ((int)targetPosition + testResults.bottomNeighbor.targetPosition) / 2; - - while(!(this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, averagedPosition).allNeighborsPassed)){ - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].targetPosition = averagedPosition; - this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, averagedPosition); - } - + if(testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition+5 >= targetPosition && testResults.rightNeighbor.targetPosition-5 <= targetPosition)){ + float avgPosition = (targetPosition + float(testResults.rightNeighbor.targetPosition)) / 2.0f; + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %f", avgPosition); + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ + float rightValue = avgPosition; + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %f", rightValue); + this->enterData(k, i, rightValue); + }else { + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right with Avg position (%d)(%d)(%f), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, + avgPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); } - - }else { - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.bottomNeighbor.targetPosition, - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); } - } - return; - } - */ - -/* Without testing neighbor of averaged value - // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table - TestResults testResults = this->testNeighbors(k, i, targetPosition); - if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { - // test which bit fields didn't match - if (!testResults.leftNeighbor.passedTest) { - if(testResults.leftNeighbor.j == k){ //if they are the same cadence - SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed but have same cadence, left targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, targetPosition); - if((testResults.leftNeighbor.targetPosition+5) >= targetPosition || (testResults.leftNeighbor.targetPosition+5) <= targetPosition){ - float averagedPosition = float(targetPosition + testResults.leftNeighbor.targetPosition) / 2.0f; - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].targetPosition = averagedPosition; - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence match: Averaged position for Left neighbor: (%d)(%d) new targetPosition: %f", testResults.leftNeighbor.i, testResults.leftNeighbor.j, averagedPosition); - } - }else { - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + else { + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, + testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); } } - if (!testResults.rightNeighbor.passedTest) { - if(testResults.rightNeighbor.j == k) //if they are the same cadence - { SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed but have same cadence, right targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, targetPosition); - if((testResults.rightNeighbor.targetPosition+5) >= targetPosition || (testResults.rightNeighbor.targetPosition+5) <= targetPosition){ - float averagedPosition = float(targetPosition + testResults.rightNeighbor.targetPosition) / 2.0f; - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].targetPosition = averagedPosition; - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence match: Averaged position for Left neighbor: (%d)(%d) new targetPosition: %f", testResults.rightNeighbor.i, testResults.rightNeighbor.j, averagedPosition); - } - }else { - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.rightNeighbor.targetPosition, - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); - } - } - if (!testResults.topNeighbor.passedTest) { - if(testResults.topNeighbor.j == k) //if they are the same cadence - { SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed but have same cadence, top targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, ss2k->getCurrentPosition()); - if((testResults.topNeighbor.targetPosition+5) >= targetPosition || (testResults.topNeighbor.targetPosition+5)<= targetPosition){ - float averagedPosition = float(targetPosition + testResults.topNeighbor.targetPosition) / 2.0f; - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].targetPosition = averagedPosition; - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence match: Averaged position for Left neighbor: (%d)(%d) new targetPosition: %f", testResults.topNeighbor.i, testResults.topNeighbor.j, averagedPosition); + if(testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition+5 >= targetPosition && testResults.topNeighbor.targetPosition-5 <= targetPosition)){ + float avgPosition = (targetPosition + float(testResults.topNeighbor.targetPosition)) / 2.0f; + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %f", avgPosition); + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ + float topValue = avgPosition; + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %f", topValue); + this->enterData(k, i, topValue); + }else { + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom with avg Position(%d)(%d)(%f), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, + avgPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); } - }else { - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + } + else{ + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, + testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); } } if (!testResults.bottomNeighbor.passedTest) { - if(testResults.bottomNeighbor.j == k) //if they are the same cadence - { SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed but have same cadence, bottom targetPosition: %d, currentPosition: %d", testResults.leftNeighbor.targetPosition, targetPosition); - if((testResults.bottomNeighbor.targetPosition+5) >= targetPosition || (testResults.bottomNeighbor.targetPosition+5) <= targetPosition){ - float averagedPosition = float(targetPosition + testResults.bottomNeighbor.targetPosition) / 2.0f; - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].targetPosition = averagedPosition; - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence match: Averaged position for Left neighbor: (%d)(%d) new targetPosition: %f", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, averagedPosition); + if(testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition+5 >= targetPosition && testResults.bottomNeighbor.targetPosition-5 <= targetPosition)){ + float avgPosition = (targetPosition + float(testResults.bottomNeighbor.targetPosition)) / 2.0f; + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %f", avgPosition); + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ + float bottomValue = avgPosition; + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %f", bottomValue); + this->enterData(k, i, bottomValue); + }else { + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom with avg position(%d)(%d)(%f), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, + avgPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); } - }else { - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.bottomNeighbor.targetPosition, - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + } + else { + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, + testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); } } return; } -*/ - - - /* - // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table -TestResults testResults = this->testNeighbors(k, i, targetPosition); -if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { - - // Check the failed neighbors - if (!testResults.leftNeighbor.passedTest) { - if (testResults.leftNeighbor.cad == cad && abs(testResults.leftNeighbor.targetPosition - targetPosition) <= 5) { - // If cadence is the same and targetPosition is within a 5-unit range, average the positions - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].targetPosition = - (testResults.leftNeighbor.targetPosition + targetPosition) / 2.0; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT Left Neighbor Fixed (%d)(%d)(%f), averaged with current position (%f)", - testResults.leftNeighbor.i, testResults.leftNeighbor.j, - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].targetPosition, targetPosition); - } else { - // If not within range, downvote the left neighbor - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT Left Neighbor Downvoted (%d)(%d)(%f), readings now (%d)", - testResults.leftNeighbor.i, testResults.leftNeighbor.j, - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].targetPosition, - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); - } - } - - if (!testResults.rightNeighbor.passedTest) { - if (testResults.rightNeighbor.cad == cad && abs(testResults.rightNeighbor.targetPosition - targetPosition) <= 5) { - // If cadence is the same and targetPosition is within a 5-unit range, average the positions - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].targetPosition = - (testResults.rightNeighbor.targetPosition + targetPosition) / 2.0; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT Right Neighbor Fixed (%d)(%d)(%f), averaged with current position (%f)", - testResults.rightNeighbor.i, testResults.rightNeighbor.j, - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].targetPosition, targetPosition); - } else { - // If not within range, downvote the right neighbor - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT Right Neighbor Downvoted (%d)(%d)(%f), readings now (%d)", - testResults.rightNeighbor.i, testResults.rightNeighbor.j, - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].targetPosition, - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); - } - } - - if (!testResults.topNeighbor.passedTest) { - if (testResults.topNeighbor.cad == cad && abs(testResults.topNeighbor.targetPosition - targetPosition) <= 5) { - // If cadence is the same and targetPosition is within a 5-unit range, average the positions - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].targetPosition = - (testResults.topNeighbor.targetPosition + targetPosition) / 2.0; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT Top Neighbor Fixed (%d)(%d)(%f), averaged with current position (%f)", - testResults.topNeighbor.i, testResults.topNeighbor.j, - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].targetPosition, targetPosition); - } else { - // If not within range, downvote the top neighbor - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT Top Neighbor Downvoted (%d)(%d)(%f), readings now (%d)", - testResults.topNeighbor.i, testResults.topNeighbor.j, - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].targetPosition, - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - } - } - - if (!testResults.bottomNeighbor.passedTest) { - if (testResults.bottomNeighbor.cad == cad && abs(testResults.bottomNeighbor.targetPosition - targetPosition) <= 5) { - // If cadence is the same and targetPosition is within a 5-unit range, average the positions - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].targetPosition = - (testResults.bottomNeighbor.targetPosition + targetPosition) / 2.0; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT Bottom Neighbor Fixed (%d)(%d)(%f), averaged with current position (%f)", - testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].targetPosition, targetPosition); - } else { - // If not within range, downvote the bottom neighbor - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT Bottom Neighbor Downvoted (%d)(%d)(%f), readings now (%d)", - testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].targetPosition, - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); - } - } - - // If none of the neighbors could be fixed, return without modifying the table - return; -}*/ // Update or create a new entry if (this->tableRow[k].tableEntry[i].readings == 0) { // if first reading in this entry @@ -1150,6 +915,23 @@ if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTes BLE_ss2kCustomCharacteristic::notify(0x27, k); } +void PowerTable::enterData(int i, int j, float pos){ + // Update or create a new entry + if (this->tableRow[i].tableEntry[j].readings == 0) { // if first reading in this entry + this->tableRow[i].tableEntry[j].targetPosition = pos; + SS2K_LOG(POWERTABLE_LOG_TAG, "New entry recorded (%d)(%d)(%d)", i, j, this->tableRow[i].tableEntry[j].targetPosition); + } else { // Average and update the readings. + this->tableRow[i].tableEntry[j].targetPosition = + (pos + (this->tableRow[i].tableEntry[j].targetPosition * this->tableRow[i].tableEntry[j].readings)) / (this->tableRow[i].tableEntry[j].readings + 1.0); + SS2K_LOG(POWERTABLE_LOG_TAG, "Existing entry averaged (%d)(%d)(%d), readings(%d)", i, j, this->tableRow[i].tableEntry[j].targetPosition, + this->tableRow[i].tableEntry[j].readings); + if (this->tableRow[i].tableEntry[j].readings > POWER_SAMPLES * 2) { + this->tableRow[i].tableEntry[j].readings = POWER_SAMPLES * 2; // keep from diluting recent readings too far. + } + } + this->tableRow[i].tableEntry[j].readings++; +} + bool PowerTable::_manageSaveState() { // Check if the table has been loaded in this session if (!this->_hasBeenLoadedThisSession) { From 91a83753a88f92e46039f2ac295df336c31fbd16 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Wed, 5 Feb 2025 21:25:03 -0600 Subject: [PATCH 042/451] small constraint changed for checking if positions are in range --- src/ERG_Mode.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index bf8bd19b..e1b3f5e1 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -797,7 +797,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { // test which bit fields didn't match if (!testResults.leftNeighbor.passedTest) { - if(testResults.leftNeighbor.i == k && (testResults.leftNeighbor.targetPosition+5 >= targetPosition && testResults.leftNeighbor.targetPosition-5 <= targetPosition)){ //check if the cadence is the same and positions are within a set range + if(testResults.leftNeighbor.i == k && (testResults.leftNeighbor.targetPosition <= targetPosition+5 && testResults.leftNeighbor.targetPosition >= targetPosition)){ //check if the cadence is the same and positions are within a set range SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and targetPosition is within range"); float avgPosition = (targetPosition + float(testResults.leftNeighbor.targetPosition)) / 2.0f; //calculate the average SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %f", avgPosition); @@ -819,7 +819,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } if (!testResults.rightNeighbor.passedTest) { - if(testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition+5 >= targetPosition && testResults.rightNeighbor.targetPosition-5 <= targetPosition)){ + if(testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition-5 && testResults.rightNeighbor.targetPosition <= targetPosition)){ float avgPosition = (targetPosition + float(testResults.rightNeighbor.targetPosition)) / 2.0f; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %f", avgPosition); if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ @@ -840,7 +840,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } if (!testResults.topNeighbor.passedTest) { - if(testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition+5 >= targetPosition && testResults.topNeighbor.targetPosition-5 <= targetPosition)){ + if(testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition-5 && testResults.topNeighbor.targetPosition <= targetPosition)){ float avgPosition = (targetPosition + float(testResults.topNeighbor.targetPosition)) / 2.0f; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %f", avgPosition); if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ @@ -861,7 +861,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } if (!testResults.bottomNeighbor.passedTest) { - if(testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition+5 >= targetPosition && testResults.bottomNeighbor.targetPosition-5 <= targetPosition)){ + if(testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition+5 && testResults.bottomNeighbor.targetPosition >= targetPosition)){ float avgPosition = (targetPosition + float(testResults.bottomNeighbor.targetPosition)) / 2.0f; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %f", avgPosition); if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ From 500634a5f36529a7a3c23161bdbd1ddc181b569a Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Thu, 6 Feb 2025 15:53:43 -0600 Subject: [PATCH 043/451] fixed log bug and fixed avgpos calculation --- include/ERG_Mode.h | 2 +- src/ERG_Mode.cpp | 66 +++++++++++++++++++++++----------------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/include/ERG_Mode.h b/include/ERG_Mode.h index be3663c8..958e9f1b 100644 --- a/include/ERG_Mode.h +++ b/include/ERG_Mode.h @@ -106,7 +106,7 @@ class PowerTable { void newEntry(PowerBuffer& powerBuffer); // enters data into power table - void enterData(int i, int j, float pos); + void enterData(int i, int j, int pos); // returns incline for wattTarget. Null if not found. int32_t lookup(int watts, int cad); diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index e1b3f5e1..db85f6c8 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -797,18 +797,18 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { // test which bit fields didn't match if (!testResults.leftNeighbor.passedTest) { - if(testResults.leftNeighbor.i == k && (testResults.leftNeighbor.targetPosition <= targetPosition+5 && testResults.leftNeighbor.targetPosition >= targetPosition)){ //check if the cadence is the same and positions are within a set range + if(testResults.leftNeighbor.i == k && (testResults.leftNeighbor.targetPosition <= targetPosition+30 && testResults.leftNeighbor.targetPosition >= targetPosition)){ //check if the cadence is the same and positions are within a set range SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and targetPosition is within range"); - float avgPosition = (targetPosition + float(testResults.leftNeighbor.targetPosition)) / 2.0f; //calculate the average - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %f", avgPosition); + int avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; //calculate the average + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); if(this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ //check if that new avg position with the current cad and watts passes - float leftValue = avgPosition; //store the value - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %f", leftValue); + int leftValue = avgPosition; //store the value + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %d", leftValue); this->enterData(k, i, leftValue); //enter the data }else { - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left with Avg Position (%d)(%d)(%f), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, avgPosition, - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + this->tableRow[k].tableEntry[i].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left with Avg Position (%d)(%d)(%d), readings (%d)", k, i, avgPosition, + this->tableRow[k].tableEntry[i].readings); } } else { //if not we still get rid of the reading @@ -819,17 +819,17 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } if (!testResults.rightNeighbor.passedTest) { - if(testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition-5 && testResults.rightNeighbor.targetPosition <= targetPosition)){ - float avgPosition = (targetPosition + float(testResults.rightNeighbor.targetPosition)) / 2.0f; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %f", avgPosition); + if(testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition-30 && testResults.rightNeighbor.targetPosition <= targetPosition)){ + int avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ - float rightValue = avgPosition; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %f", rightValue); + int rightValue = avgPosition; + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %d", rightValue); this->enterData(k, i, rightValue); }else { - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right with Avg position (%d)(%d)(%f), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, - avgPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + this->tableRow[k].tableEntry[i].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right with Avg position (%d)(%d)(%d), readings (%d)", k, i, + avgPosition, this->tableRow[k].tableEntry[i].readings); } } else { @@ -840,17 +840,17 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } if (!testResults.topNeighbor.passedTest) { - if(testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition-5 && testResults.topNeighbor.targetPosition <= targetPosition)){ - float avgPosition = (targetPosition + float(testResults.topNeighbor.targetPosition)) / 2.0f; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %f", avgPosition); + if(testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition-30 && testResults.topNeighbor.targetPosition <= targetPosition)){ + int avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ - float topValue = avgPosition; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %f", topValue); + int topValue = avgPosition; + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %d", topValue); this->enterData(k, i, topValue); }else { - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom with avg Position(%d)(%d)(%f), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, - avgPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + this->tableRow[k].tableEntry[i].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right with Avg position (%d)(%d)(%d), readings (%d)", k, i, + avgPosition, this->tableRow[k].tableEntry[i].readings); } } else{ @@ -861,17 +861,17 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } if (!testResults.bottomNeighbor.passedTest) { - if(testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition+5 && testResults.bottomNeighbor.targetPosition >= targetPosition)){ - float avgPosition = (targetPosition + float(testResults.bottomNeighbor.targetPosition)) / 2.0f; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %f", avgPosition); + if(testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition+30 && testResults.bottomNeighbor.targetPosition >= targetPosition)){ + int avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ - float bottomValue = avgPosition; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %f", bottomValue); + int bottomValue = avgPosition; + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %d", bottomValue); this->enterData(k, i, bottomValue); }else { - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom with avg position(%d)(%d)(%f), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, - avgPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + this->tableRow[k].tableEntry[i].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right with Avg position (%d)(%d)(%d), readings (%d)", k, i, + avgPosition, this->tableRow[k].tableEntry[i].readings); } } else { @@ -915,7 +915,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { BLE_ss2kCustomCharacteristic::notify(0x27, k); } -void PowerTable::enterData(int i, int j, float pos){ +void PowerTable::enterData(int i, int j, int pos){ // Update or create a new entry if (this->tableRow[i].tableEntry[j].readings == 0) { // if first reading in this entry this->tableRow[i].tableEntry[j].targetPosition = pos; From e847eb4e66a5e86698580f6b79c34a53554a0a7c Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Thu, 6 Feb 2025 16:35:54 -0600 Subject: [PATCH 044/451] incorporated moving the failed neighbor and avg the failed neighbor with the current position --- src/ERG_Mode.cpp | 141 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 134 insertions(+), 7 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index db85f6c8..d605bf84 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -798,17 +798,25 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { // test which bit fields didn't match if (!testResults.leftNeighbor.passedTest) { if(testResults.leftNeighbor.i == k && (testResults.leftNeighbor.targetPosition <= targetPosition+30 && testResults.leftNeighbor.targetPosition >= targetPosition)){ //check if the cadence is the same and positions are within a set range - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and targetPosition is within range"); + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and target pos is within range"); int avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; //calculate the average + int newValue = targetPosition - (avgPosition - targetPosition); //this is the possible new value for the neighbor SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); if(this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ //check if that new avg position with the current cad and watts passes int leftValue = avgPosition; //store the value SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %d", leftValue); this->enterData(k, i, leftValue); //enter the data - }else { + }else if(!(this->testNeighbors(k, i, avgPosition).allNeighborsPassed)){ this->tableRow[k].tableEntry[i].readings--; SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left with Avg Position (%d)(%d)(%d), readings (%d)", k, i, avgPosition, this->tableRow[k].tableEntry[i].readings); + } if(this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, newValue).allNeighborsPassed){ + SS2K_LOG(POWERTABLE_LOG_TAG, "New Value is valid, %d", newValue); + this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, newValue); + }else if(!(this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, newValue).allNeighborsPassed)){ + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed with new Value (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, newValue, + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); } } else { //if not we still get rid of the reading @@ -820,17 +828,26 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (!testResults.rightNeighbor.passedTest) { if(testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition-30 && testResults.rightNeighbor.targetPosition <= targetPosition)){ + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and target pos is within range"); int avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; + int newValue = targetPosition - (avgPosition - targetPosition); //this is the possible new value for the neighbor SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ int rightValue = avgPosition; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %d", rightValue); this->enterData(k, i, rightValue); - }else { + }else if(!(this->testNeighbors(k, i, avgPosition).allNeighborsPassed)) { this->tableRow[k].tableEntry[i].readings--; SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right with Avg position (%d)(%d)(%d), readings (%d)", k, i, avgPosition, this->tableRow[k].tableEntry[i].readings); - } + } if(this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, newValue).allNeighborsPassed){ + SS2K_LOG(POWERTABLE_LOG_TAG, "New Value is valid, %d", newValue); + this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, newValue); + } else if(!(this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, newValue).allNeighborsPassed)){ + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right with new value(%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, + newValue, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + } } else { this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; @@ -841,16 +858,25 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (!testResults.topNeighbor.passedTest) { if(testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition-30 && testResults.topNeighbor.targetPosition <= targetPosition)){ + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and target pos is within range"); int avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; + int newValue = targetPosition - (avgPosition - targetPosition); //this is the possible new value for the neighbor SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ int topValue = avgPosition; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %d", topValue); this->enterData(k, i, topValue); - }else { + }else if(!(this->testNeighbors(k, i, avgPosition).allNeighborsPassed)) { this->tableRow[k].tableEntry[i].readings--; SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right with Avg position (%d)(%d)(%d), readings (%d)", k, i, avgPosition, this->tableRow[k].tableEntry[i].readings); + } if(this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, newValue).allNeighborsPassed){ + SS2K_LOG(POWERTABLE_LOG_TAG, "New Value is valid, %d", newValue); + this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, newValue); + }else if(!(this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, newValue).allNeighborsPassed)){ + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top with new Value (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, newValue, + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); } } else{ @@ -862,17 +888,26 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (!testResults.bottomNeighbor.passedTest) { if(testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition+30 && testResults.bottomNeighbor.targetPosition >= targetPosition)){ + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and target pos is within range"); int avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; + int newValue = targetPosition - (avgPosition - targetPosition); //this is the possible new value for the neighbor SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ int bottomValue = avgPosition; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %d", bottomValue); this->enterData(k, i, bottomValue); - }else { + }else if(!(this->testNeighbors(k, i, avgPosition).allNeighborsPassed)) { this->tableRow[k].tableEntry[i].readings--; SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right with Avg position (%d)(%d)(%d), readings (%d)", k, i, avgPosition, this->tableRow[k].tableEntry[i].readings); - } + } if(this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, newValue).allNeighborsPassed){ + SS2K_LOG(POWERTABLE_LOG_TAG, "New Value is valid, %d", newValue); + this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, newValue); + }else if(!(this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, newValue).allNeighborsPassed)){ + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom with new Value (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, + newValue, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + } } else { this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; @@ -883,6 +918,98 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { return; } + /* + // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table + TestResults testResults = this->testNeighbors(k, i, targetPosition); + if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { + // test which bit fields didn't match + if (!testResults.leftNeighbor.passedTest) { + if(testResults.leftNeighbor.i == k && (testResults.leftNeighbor.targetPosition <= targetPosition+30 && testResults.leftNeighbor.targetPosition >= targetPosition)){ + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and target pos is within range"); + SS2K_LOG(POWERTABLE_LOG_TAG, "Range: %f to %d", targetPosition, testResults.leftNeighbor.targetPosition); + int avgValue = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; + int newValue = targetPosition - (avgValue - targetPosition); //this is the possible new value for the neighbor + if(this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, newValue).allNeighborsPassed){ + SS2K_LOG(POWERTABLE_LOG_TAG, "New Value is valid, %d", newValue); + this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, newValue); + }else { + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed with new Value (%d)(%d)(%f), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, newValue, + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + } + }else{ + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + } + } + + if (!testResults.rightNeighbor.passedTest) { + if(testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition-30 && testResults.rightNeighbor.targetPosition <= targetPosition)){ + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and target pos is within range"); + SS2K_LOG(POWERTABLE_LOG_TAG, "Range: %f to %d", targetPosition, testResults.rightNeighbor.targetPosition); + int avgValue = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; + int newValue = targetPosition + (avgValue - targetPosition); //this is the possible new value for the neighbor + if(this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, newValue).allNeighborsPassed){ + SS2K_LOG(POWERTABLE_LOG_TAG, "New Value is valid, %d", newValue); + this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, newValue); + } else { + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right with new value(%d)(%d)(%f), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, + newValue, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + } + }else { + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, + testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + } + } + + if (!testResults.topNeighbor.passedTest) { + if(testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition-30 && testResults.topNeighbor.targetPosition <= targetPosition)){ + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and target pos is within range"); + SS2K_LOG(POWERTABLE_LOG_TAG, "Range: %f to %d", targetPosition, testResults.topNeighbor.targetPosition); + int avgValue = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; + int newValue = targetPosition + (avgValue - targetPosition); //this is the possible new value for the neighbor + if(this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, newValue).allNeighborsPassed){ + SS2K_LOG(POWERTABLE_LOG_TAG, "New Value is valid, %d", newValue); + this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, newValue); + }else { + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top with new Value (%d)(%d)(%f), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, newValue, + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + } + }else{ + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + } + } + + if (!testResults.bottomNeighbor.passedTest) { + if(testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition+30 && testResults.bottomNeighbor.targetPosition >= targetPosition)){ + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and target pos is within range"); + SS2K_LOG(POWERTABLE_LOG_TAG, "Range: %f to %d", targetPosition, testResults.bottomNeighbor.targetPosition); + int avgValue = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; + int newValue = targetPosition + (avgValue - targetPosition); //this is the possible new value for the neighbor + if(this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, newValue).allNeighborsPassed){ + SS2K_LOG(POWERTABLE_LOG_TAG, "New Value is valid, %d", newValue); + this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, newValue); + }else { + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom with new Value (%d)(%d)(%f), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, + newValue, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + } + }else{ + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, + testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + } + } + return; + } + */ + // Update or create a new entry if (this->tableRow[k].tableEntry[i].readings == 0) { // if first reading in this entry this->tableRow[k].tableEntry[i].targetPosition = targetPosition; From 43c9ce0a43d875e671b142a04915307056b79409 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Thu, 6 Feb 2025 17:02:17 -0600 Subject: [PATCH 045/451] fixed calculation error --- src/ERG_Mode.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index d605bf84..9ae14f13 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -830,7 +830,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if(testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition-30 && testResults.rightNeighbor.targetPosition <= targetPosition)){ SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and target pos is within range"); int avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; - int newValue = targetPosition - (avgPosition - targetPosition); //this is the possible new value for the neighbor + int newValue = targetPosition + (avgPosition - targetPosition); //this is the possible new value for the neighbor SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ int rightValue = avgPosition; @@ -860,7 +860,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if(testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition-30 && testResults.topNeighbor.targetPosition <= targetPosition)){ SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and target pos is within range"); int avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; - int newValue = targetPosition - (avgPosition - targetPosition); //this is the possible new value for the neighbor + int newValue = targetPosition + (avgPosition - targetPosition); //this is the possible new value for the neighbor SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ int topValue = avgPosition; From dced2c63ca46229c8ece7690e2a5311910709d5a Mon Sep 17 00:00:00 2001 From: ddtomic Date: Tue, 11 Feb 2025 16:32:06 -0600 Subject: [PATCH 046/451] defined a table divisor for clarity --- include/settings.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/settings.h b/include/settings.h index 51314d62..6173367f 100644 --- a/include/settings.h +++ b/include/settings.h @@ -274,6 +274,12 @@ const char* const DEFAULT_PASSWORD = "password"; // Number of similar power samples to take before writing to the Power Table #define POWER_SAMPLES 5 +// Max downvotes that a neighbor can have +#define MAX_NEIGHBOR_WEIGHT + +// Min downvotes that a neighbor can have +#define MIN_NEIGHBOR_WEIGHT + // How often in ms to save the power table if no new data is added and user is pedaling. #define POWER_TABLE_SAVE_INTERVAL 240000 @@ -318,6 +324,9 @@ const char* const DEFAULT_PASSWORD = "password"; #define MAIN_STACK 6500 #define BLE_CLIENT_STACK 6000 +// Limit table size to save memory +#define TABLE_DIVISOR 10 + // Uncomment to enable stack size debugging info // #define DEBUG_STACK From a942aeafe37f9dd6b1cc852f848b11879fea630a Mon Sep 17 00:00:00 2001 From: ddtomic Date: Tue, 11 Feb 2025 16:37:01 -0600 Subject: [PATCH 047/451] implemented table diviso r --- include/ERG_Mode.h | 1 + src/ERG_Mode.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/include/ERG_Mode.h b/include/ERG_Mode.h index afdba436..5faf7191 100644 --- a/include/ERG_Mode.h +++ b/include/ERG_Mode.h @@ -44,6 +44,7 @@ class TableEntry { public: int16_t targetPosition; int8_t readings; + TableEntry() { this->targetPosition = INT16_MIN; this->readings = 0; diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 7b7f3a34..6b8ce119 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -85,7 +85,7 @@ void PowerBuffer::set(int i) { this->powerEntry[i].readings++; this->powerEntry[i].watts = rtConfig->watts.getValue(); this->powerEntry[i].cad = rtConfig->cad.getValue(); - this->powerEntry[i].targetPosition = ss2k->getCurrentPosition() / 100; // dividing by 100 to save memory. + this->powerEntry[i].targetPosition = ss2k->getCurrentPosition() / TABLE_DIVISOR; // dividing by 10 to save memory. } void PowerBuffer::reset() { @@ -225,7 +225,7 @@ int32_t PowerTable::lookup(int watts, int cad) { int val2 = this->tableRow[extrapRow2].tableEntry[wattIndex].targetPosition; extrapolatedValue = val1 + (val2 - val1) * (cad - cad1) / (cad2 - cad1); SS2K_LOG(ERG_MODE_LOG_TAG, "Lookup Extrapolated %d from %d, %d, for %dw %dcad", extrapolatedValue, val2, val1, watts, cad); - return extrapolatedValue * 100; + return extrapolatedValue * TABLE_DIVISOR; } } @@ -249,7 +249,7 @@ int32_t PowerTable::lookup(int watts, int cad) { int val2 = this->tableRow[cadIndex].tableEntry[extrapCol2].targetPosition; extrapolatedValue = val1 + (val2 - val1) * (watts - watts1) / (watts2 - watts1); SS2K_LOG(ERG_MODE_LOG_TAG, "Lookup Extrapolated %d from %d, %d, for %dw %dcad", extrapolatedValue, val2, val1, watts, cad); - return extrapolatedValue * 100; + return extrapolatedValue * TABLE_DIVISOR; } } // Not enough data. @@ -311,7 +311,7 @@ int32_t PowerTable::lookup(int watts, int cad) { return INT16_MIN; } - int ret = (sum / count) * 100; + int ret = (sum / count) * TABLE_DIVISOR; SS2K_LOG(ERG_MODE_LOG_TAG, "Lookup result: %dw %dcad %d", watts, cad, ret); return ret; } @@ -1104,7 +1104,7 @@ void ErgMode::computeResistance() { int actualDelta = rtConfig->resistance.getTarget() - rtConfig->resistance.getValue(); if (actualDelta != 0) { - rtConfig->setTargetIncline(rtConfig->getTargetIncline() + (100 * actualDelta)); + rtConfig->setTargetIncline(rtConfig->getTargetIncline() + (TABLE_DIVISOR * actualDelta)); } else { rtConfig->setTargetIncline(ss2k->getCurrentPosition()); } @@ -1204,7 +1204,7 @@ void ErgMode::_updateValues(int newCadence, Measurement& newWatts, float newIncl bool ErgMode::_userIsSpinning(int cadence, float incline) { if (cadence <= MIN_ERG_CADENCE) { - if (!this->engineStopped) { // Test so motor stop command only happens once. // release tension + if (!this->engineStopped) { // Test so motor stop command only happens once. // release tension rtConfig->setTargetIncline(0); // release incline this->engineStopped = true; } From 3e6fce05971435d9bd2dec91855eb82efe42348f Mon Sep 17 00:00:00 2001 From: ddtomic Date: Tue, 11 Feb 2025 17:01:57 -0600 Subject: [PATCH 048/451] defined min and max neighbor weight more accurately --- include/settings.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/settings.h b/include/settings.h index 6173367f..018945f8 100644 --- a/include/settings.h +++ b/include/settings.h @@ -275,10 +275,10 @@ const char* const DEFAULT_PASSWORD = "password"; #define POWER_SAMPLES 5 // Max downvotes that a neighbor can have -#define MAX_NEIGHBOR_WEIGHT +#define MAX_NEIGHBOR_WEIGHT 2 * POWER_SAMPLES // Min downvotes that a neighbor can have -#define MIN_NEIGHBOR_WEIGHT +#define MIN_NEIGHBOR_WEIGHT 0 // How often in ms to save the power table if no new data is added and user is pedaling. #define POWER_TABLE_SAVE_INTERVAL 240000 From 6390a4d080234b260b4d4f9f55179824d34842a0 Mon Sep 17 00:00:00 2001 From: ddtomic Date: Tue, 11 Feb 2025 17:42:50 -0600 Subject: [PATCH 049/451] UNTESTED downvote logic implemented --- src/ERG_Mode.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 6 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 6b8ce119..16e4980f 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -729,6 +729,34 @@ void PowerTable::clean() { } } +// function for weighted downvoting +int downVote(int targetValue, int neighborValue) { + // calculate diff between target and neighbor + int delta = abs(targetValue - neighborValue); + float penalty; + float penaltyFactor = 0.2; + // we have a few different options for penalty calculations here, will need to test which works best: + + // linear function, low agression + penalty = delta * penaltyFactor; + + // quadratic function, high aggression + // penalty = penaltyFactor * (delta * delta) + + // log function, medium aggression + // penalty = penaltyFactor * log(delta + 1); + + // max penalty is 10 + if (penalty > 10) { + penalty = 10; + } + + // round up penalty to make it an int + penalty = round(penalty); + + return penalty; +} + void PowerTable::newEntry(PowerBuffer& powerBuffer) { // these are floats so that we make sure division works correctly. float watts = 0; @@ -783,25 +811,65 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { // test which bit fields didn't match if (!testResults.leftNeighbor.passedTest) { - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + // determine penalty amount before applying to failed neighbor + int penalty = downVote(targetPosition, testResults.leftNeighbor.targetPosition); + + // make sure downvotes isn't at max + if (this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; + penalty = 0; + } + + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings -= penalty; SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); } + if (!testResults.rightNeighbor.passedTest) { - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + // determine penalty amount before applying to failed neighbor + int penalty = downVote(targetPosition, testResults.rightNeighbor.targetPosition); + + // make sure downvotes isn't at max + if (this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; + penalty = 0; + } + + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings -= penalty; SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); } + if (!testResults.topNeighbor.passedTest) { - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + // determine penalty amount before applying to failed neighbor + int penalty = downVote(targetPosition, testResults.topNeighbor.targetPosition); + + // make sure downvotes isn't at max + if (this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; + penalty = 0; + } + + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings -= penalty; SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); } + if (!testResults.bottomNeighbor.passedTest) { - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + // determine penalty amount before applying to failed neighbor + int penalty = downVote(targetPosition, testResults.bottomNeighbor.targetPosition); + + // make sure downvotes isn't at max + if (this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; + penalty = 0; + } + + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings -= penalty; SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); } + return; } @@ -814,8 +882,8 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { (targetPosition + (this->tableRow[k].tableEntry[i].targetPosition * this->tableRow[k].tableEntry[i].readings)) / (this->tableRow[k].tableEntry[i].readings + 1.0); SS2K_LOG(POWERTABLE_LOG_TAG, "Existing entry averaged (%d)(%d)(%d), readings(%d)", k, i, this->tableRow[k].tableEntry[i].targetPosition, this->tableRow[k].tableEntry[i].readings); - if (this->tableRow[k].tableEntry[i].readings > POWER_SAMPLES * 2) { - this->tableRow[k].tableEntry[i].readings = POWER_SAMPLES * 2; // keep from diluting recent readings too far. + if (this->tableRow[k].tableEntry[i].readings > MAX_NEIGHBOR_WEIGHT) { + this->tableRow[k].tableEntry[i].readings = MAX_NEIGHBOR_WEIGHT; // keep from diluting recent readings too far. } } this->tableRow[k].tableEntry[i].readings++; From 486cde2625dfe56fe8dfe84184f8a6d7fb595a62 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 12 Feb 2025 10:07:56 -0800 Subject: [PATCH 050/451] working --- platformio.ini | 4 ++-- src/BLE_Fitness_Machine_Service.cpp | 19 ++++++++++++------- src/BLE_Server.cpp | 2 +- src/HTTP_Server_Basic.cpp | 4 ++-- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/platformio.ini b/platformio.ini index 3860dee8..3f700599 100644 --- a/platformio.ini +++ b/platformio.ini @@ -32,8 +32,8 @@ build_flags = lib_deps = #use a PR version of the library to fix a bug. Remove this line when the PR is merged #NimBLE-Arduino PR #878 - https://github.com/h2zero/NimBLE-Arduino.git#refactor - #https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.1.3.zip + #https://github.com/h2zero/NimBLE-Arduino.git#refactor + https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.2.1.zip https://github.com/teemuatlut/TMCStepper/archive/refs/tags/v0.7.3.zip https://github.com/bblanchon/ArduinoJson/archive/refs/tags/v6.20.0.zip https://github.com/gin66/FastAccelStepper/archive/refs/tags/0.31.2.zip diff --git a/src/BLE_Fitness_Machine_Service.cpp b/src/BLE_Fitness_Machine_Service.cpp index 4a570236..2131caca 100644 --- a/src/BLE_Fitness_Machine_Service.cpp +++ b/src/BLE_Fitness_Machine_Service.cpp @@ -19,7 +19,7 @@ BLE_Fitness_Machine_Service::BLE_Fitness_Machine_Service() fitnessMachineInclinationRange(nullptr), fitnessMachineTrainingStatus(nullptr) {} -uint8_t ftmsTrainingStatus[2] = {0x08, 0x00}; +uint8_t ftmsTrainingStatus[2] = {0x00, 0x00}; // Initialize to Other state void BLE_Fitness_Machine_Service::setupService(NimBLEServer *pServer, MyCharacteristicCallbacks *chrCallbacks) { // Resistance, IPower, HeartRate @@ -269,7 +269,7 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x00; } fitnessMachineStatusCharacteristic->setValue(ftmsStatus.data(), ftmsStatus.size()); - SS2K_LOG(FMTS_SERVER_LOG_TAG, "Calling notify %s -> %02x %02x", fitnessMachineStatusCharacteristic->getUUID().toString().c_str(), ftmsStatus[0], ftmsStatus[1]); + //SS2K_LOG(FMTS_SERVER_LOG_TAG, "Calling notify %s -> %02x %02x", fitnessMachineStatusCharacteristic->getUUID().toString().c_str(), ftmsStatus[0], ftmsStatus[1]); std::string characteristicValue = pCharacteristic->getValue(); std::string logValue; for (size_t i = 0; i < characteristicValue.length(); ++i) { @@ -277,12 +277,17 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { snprintf(buf, sizeof(buf), "%02x ", (unsigned char)characteristicValue[i]); logValue += buf; } - SS2K_LOG(FMTS_SERVER_LOG_TAG, "Caling notify %s -> %s", pCharacteristic->getUUID().toString().c_str(), logValue.c_str()); + SS2K_LOG(FMTS_SERVER_LOG_TAG, "Calling notify %s -> %s", pCharacteristic->getUUID().toString().c_str(), logValue.c_str()); fitnessMachineControlPoint->setValue(returnValue, 3); fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); - fitnessMachineControlPoint->notify(); - //fitnessMachineTrainingStatus->notify(); - //fitnessMachineStatusCharacteristic->notify(); + fitnessMachineControlPoint->indicate(); + // only notify if the value has changed + static uint8_t _lastTrainingStatus[2] = {0x00, 0x00}; + if (memcmp(_lastTrainingStatus, ftmsTrainingStatus, 2) != 0) { + memcpy(_lastTrainingStatus, ftmsTrainingStatus, 2); + fitnessMachineTrainingStatus->notify(); + } + fitnessMachineStatusCharacteristic->notify(); } } @@ -328,4 +333,4 @@ bool BLE_Fitness_Machine_Service::spinDown(uint8_t response) { }*/ return true; -} \ No newline at end of file +} diff --git a/src/BLE_Server.cpp b/src/BLE_Server.cpp index 6b19c68c..98b6dd2d 100644 --- a/src/BLE_Server.cpp +++ b/src/BLE_Server.cpp @@ -193,7 +193,7 @@ void MyCharacteristicCallbacks::onStatus(NimBLECharacteristic* pCharacteristic, logValue += buf; } - SS2K_LOG(BLE_SERVER_LOG_TAG, "Notification/Indication status code: %d for char: %s Data: %s", + SS2K_LOGW(BLE_SERVER_LOG_TAG, "Notification/Indication status code: %d for char: %s Data: %s", code, pCharacteristic->getUUID().toString().c_str(), logValue.c_str()); } diff --git a/src/HTTP_Server_Basic.cpp b/src/HTTP_Server_Basic.cpp index 2324e500..e17ef0e7 100644 --- a/src/HTTP_Server_Basic.cpp +++ b/src/HTTP_Server_Basic.cpp @@ -58,7 +58,7 @@ void _APSetup() { //WiFi.setHostname(userConfig->getDeviceName()); WiFi.softAPsetHostname(userConfig->getDeviceName()); WiFi.enableAP(true); - vTaskDelay(500); // Micro controller requires some time to reset the mode + vTaskDelay(500/portTICK_RATE_MS); // Micro controller requires some time to reset the mode } // ********************************WIFI Setup************************* @@ -104,7 +104,7 @@ void startWifi() { SS2K_LOG(HTTP_SERVER_LOG_TAG, "Using Default Password"); WiFi.softAP(userConfig->getDeviceName(), DEFAULT_PASSWORD); } - vTaskDelay(50); + vTaskDelay(50/portTICK_RATE_MS); myIP = WiFi.softAPIP(); /* Setup the DNS server redirecting all the domains to the apIP */ dnsServer.setErrorReplyCode(DNSReplyCode::NoError); From 7b1dbf2369d0b65186a09b0981660ad1bcff73a0 Mon Sep 17 00:00:00 2001 From: ddtomic Date: Wed, 12 Feb 2025 16:55:19 -0600 Subject: [PATCH 051/451] more logging for further troubleshooting --- src/ERG_Mode.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 16e4980f..0fcb2ed6 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -735,6 +735,10 @@ int downVote(int targetValue, int neighborValue) { int delta = abs(targetValue - neighborValue); float penalty; float penaltyFactor = 0.2; + + // currently consistently getting a 0 for neighbor value... + SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Target Value: (%d), NeighborValue: (%f)", targetValue, neighborValue); + // we have a few different options for penalty calculations here, will need to test which works best: // linear function, low agression @@ -754,6 +758,7 @@ int downVote(int targetValue, int neighborValue) { // round up penalty to make it an int penalty = round(penalty); + SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Delta: (%d), Penalty: (%f)", delta, penalty); return penalty; } From 1a1f0e80db131f8fcac858ec6f0b3286071b2628 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 12 Feb 2025 15:47:48 -0800 Subject: [PATCH 052/451] added incomplete SB20 service --- include/BLE_SB20_Service.h | 39 +++++++++++++++++++++++++++++++++ src/BLE_SB20_Service.cpp | 44 ++++++++++++++++++++++++++++++++++++++ src/BLE_Server.cpp | 4 ++++ 3 files changed, 87 insertions(+) create mode 100644 include/BLE_SB20_Service.h create mode 100644 src/BLE_SB20_Service.cpp diff --git a/include/BLE_SB20_Service.h b/include/BLE_SB20_Service.h new file mode 100644 index 00000000..e29f5bde --- /dev/null +++ b/include/BLE_SB20_Service.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 Anthony Doud & Joel Baranick + * All rights reserved + * + * SPDX-License-Identifier: GPL-2.0-only + */ + +#pragma once + +#include +#include "BLE_Common.h" + +// See https://github.com/JanDeVisser/stages-monitor/tree/master/sb20display +#define SB20_SERVICE_UUID "a026ee0b-0a7d-4ab3-97fa-f1500f9feb8b" +#define SB20_CHARACTERISTIC_UUID "a026e037-0a7d-4ab3-97fa-f1500f9feb8b" + +struct SB20Data { + uint8_t gear; // Calculated Gear (1-22) + uint16_t cadence; // Cadence in RPM + uint16_t power; // Power in Watts + uint16_t heartrate; // Heart Rate in BPM + uint8_t battery; // always 4 +}; + +class BLE_SB20_Service { +public: + BLE_SB20_Service(); + + void begin(); + void setData(SB20Data data); + void notify(); + +private: + BLEService *pService; + BLECharacteristic *pCharacteristic; + SB20Data currentData; + bool deviceConnected; + +}; diff --git a/src/BLE_SB20_Service.cpp b/src/BLE_SB20_Service.cpp new file mode 100644 index 00000000..65710d9b --- /dev/null +++ b/src/BLE_SB20_Service.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 Anthony Doud & Joel Baranick + * All rights reserved + * + * SPDX-License-Identifier: GPL-2.0-only + */ + +#include "BLE_SB20_Service.h" + +BLE_SB20_Service::BLE_SB20_Service() : pService(nullptr), pCharacteristic(nullptr) { + currentData.gear = 1; + currentData.cadence = 0; + currentData.power = 0; + currentData.heartrate = 0; + currentData.battery = 4; // Always full +} + +void BLE_SB20_Service::begin() { + pService = BLEDevice::createServer()->createService(SB20_SERVICE_UUID); + pCharacteristic = pService->createCharacteristic(SB20_CHARACTERISTIC_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); + pService->start(); + SS2K_LOG(SS2K_LOG_TAG,"SB20 Service started\n"); +} + +void BLE_SB20_Service::setData(SB20Data data) { currentData = data; } + +void BLE_SB20_Service::notify() { + if (pCharacteristic == nullptr) { + return; + } + + // Get current values and populate data struct + int shifterPosition = rtConfig->getShifterPosition(); + shifterPosition = constrain(shifterPosition, 1, 22); // Clamp to 1-22 + + currentData.gear = shifterPosition; + currentData.cadence = rtConfig->cad.getValue(); // direct value, no scaling + currentData.power = rtConfig->watts.getValue(); + currentData.heartrate = rtConfig->hr.getValue(); + + pCharacteristic->setValue((uint8_t *)¤tData, sizeof(currentData)); + pCharacteristic->notify(); + SS2K_LOG(SS2K_LOG_TAG,"SB20 data sent: Gear=%d, Cadence=%d, Power=%d, HR=%d\n", currentData.gear, currentData.cadence, currentData.power, currentData.heartrate); +} \ No newline at end of file diff --git a/src/BLE_Server.cpp b/src/BLE_Server.cpp index 98b6dd2d..a352cf3e 100644 --- a/src/BLE_Server.cpp +++ b/src/BLE_Server.cpp @@ -15,6 +15,7 @@ #include "BLE_Custom_Characteristic.h" #include "BLE_Device_Information_Service.h" #include "BLE_Wattbike_Service.h" +#include "BLE_SB20_Service.h" #include #include @@ -34,6 +35,7 @@ BLE_Fitness_Machine_Service fitnessMachineService; BLE_ss2kCustomCharacteristic ss2kCustomCharacteristic; BLE_Device_Information_Service deviceInformationService; BLE_Wattbike_Service wattbikeService; +//BLE_SB20_Service sb20Service; void startBLEServer() { // Server Setup @@ -51,6 +53,7 @@ void startBLEServer() { ss2kCustomCharacteristic.setupService(spinBLEServer.pServer); deviceInformationService.setupService(spinBLEServer.pServer); wattbikeService.setupService(spinBLEServer.pServer); // No callback needed + //sb20Service.begin(); BLEFirmwareSetup(); // const std::string fitnessData = {0b00000001, 0b00100000, 0b00000000}; @@ -73,6 +76,7 @@ void SpinBLEServer::update() { cyclingSpeedCadenceService.update(); fitnessMachineService.update(); wattbikeService.parseNemit(); // Changed from update() to parseNemit() + ///sb20Service.notify(); } double SpinBLEServer::calculateSpeed() { From 102533d4c2bea0bdae0a7801e71778fb3d8efe62 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Wed, 12 Feb 2025 20:40:11 -0600 Subject: [PATCH 053/451] updated newEntry function. Moves avg, current, and failed neighbor positions. --- src/ERG_Mode.cpp | 252 +++++++++++++++-------------------------------- 1 file changed, 79 insertions(+), 173 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 9ae14f13..d2dc13db 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -791,35 +791,34 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { return; } - // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table TestResults testResults = this->testNeighbors(k, i, targetPosition); if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { // test which bit fields didn't match if (!testResults.leftNeighbor.passedTest) { - if(testResults.leftNeighbor.i == k && (testResults.leftNeighbor.targetPosition <= targetPosition+30 && testResults.leftNeighbor.targetPosition >= targetPosition)){ //check if the cadence is the same and positions are within a set range - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and target pos is within range"); + if(testResults.leftNeighbor.i == k && (testResults.leftNeighbor.targetPosition <= targetPosition+30 && testResults.leftNeighbor.targetPosition >= targetPosition)){ //check if the cadence is the same and positions are within a set range in this case its 30. + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and targetPosition is within range"); + int avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; //calculate the average - int newValue = targetPosition - (avgPosition - targetPosition); //this is the possible new value for the neighbor SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - if(this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ //check if that new avg position with the current cad and watts passes - int leftValue = avgPosition; //store the value - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %d", leftValue); - this->enterData(k, i, leftValue); //enter the data - }else if(!(this->testNeighbors(k, i, avgPosition).allNeighborsPassed)){ - this->tableRow[k].tableEntry[i].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left with Avg Position (%d)(%d)(%d), readings (%d)", k, i, avgPosition, - this->tableRow[k].tableEntry[i].readings); - } if(this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, newValue).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "New Value is valid, %d", newValue); - this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, newValue); - }else if(!(this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, newValue).allNeighborsPassed)){ - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed with new Value (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, newValue, - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + + if(this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed){ //check if the current position moved left is valid + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %d", targetPosition); + this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); //enter the data + } + + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ //checks if the avg position with the current watts and cadence is valid + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); + this->enterData(k, i, avgPosition); //enter the data + } + + if(this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition).allNeighborsPassed){ //checks if the failed nighbor is valid with the right neighbors cadence and watts + SS2K_LOG(POWERTABLE_LOG_TAG, "Left Neighbors position was valid with Right Neighbors cadence and watts! Left Neighbor Position: %d", testResults.leftNeighbor.targetPosition); + this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition); } - } - else { //if not we still get rid of the reading + + return; + } else { //if not we still get rid of the reading this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%f), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); @@ -828,28 +827,27 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (!testResults.rightNeighbor.passedTest) { if(testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition-30 && testResults.rightNeighbor.targetPosition <= targetPosition)){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and target pos is within range"); + int avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; - int newValue = targetPosition + (avgPosition - targetPosition); //this is the possible new value for the neighbor SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ - int rightValue = avgPosition; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %d", rightValue); - this->enterData(k, i, rightValue); - }else if(!(this->testNeighbors(k, i, avgPosition).allNeighborsPassed)) { - this->tableRow[k].tableEntry[i].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right with Avg position (%d)(%d)(%d), readings (%d)", k, i, - avgPosition, this->tableRow[k].tableEntry[i].readings); - } if(this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, newValue).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "New Value is valid, %d", newValue); - this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, newValue); - } else if(!(this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, newValue).allNeighborsPassed)){ - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right with new value(%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, - newValue, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); - } - } - else { + + if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed){ + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved right was valid! Current position: %d", targetPosition); + this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); + } + + if(this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); + this->enterData(k, i, avgPosition); + } + + if(this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed){ + SS2K_LOG(POWERTABLE_LOG_TAG, "Right Neighbors position was valid with Left Neighbors cadence and watts! Right Neighbor Position: %d", testResults.rightNeighbor.targetPosition); + this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition); + } + + return; + } else { this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); @@ -858,28 +856,27 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (!testResults.topNeighbor.passedTest) { if(testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition-30 && testResults.topNeighbor.targetPosition <= targetPosition)){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and target pos is within range"); + int avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; - int newValue = targetPosition + (avgPosition - targetPosition); //this is the possible new value for the neighbor SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ - int topValue = avgPosition; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %d", topValue); - this->enterData(k, i, topValue); - }else if(!(this->testNeighbors(k, i, avgPosition).allNeighborsPassed)) { - this->tableRow[k].tableEntry[i].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right with Avg position (%d)(%d)(%d), readings (%d)", k, i, - avgPosition, this->tableRow[k].tableEntry[i].readings); - } if(this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, newValue).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "New Value is valid, %d", newValue); - this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, newValue); - }else if(!(this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, newValue).allNeighborsPassed)){ - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top with new Value (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, newValue, - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + + if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed){ + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %d", targetPosition); + this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); + } + + if(this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); + this->enterData(k, i, avgPosition); } - } - else{ + + if(this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed){ + SS2K_LOG(POWERTABLE_LOG_TAG, "Top Neighbors position was valid with Bottom Neighbors cadence and watts! Top Neighbor Position: %d", testResults.topNeighbor.targetPosition); + this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); + } + + return; + } else { this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); @@ -888,127 +885,34 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (!testResults.bottomNeighbor.passedTest) { if(testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition+30 && testResults.bottomNeighbor.targetPosition >= targetPosition)){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and target pos is within range"); + int avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; - int newValue = targetPosition - (avgPosition - targetPosition); //this is the possible new value for the neighbor SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ - int bottomValue = avgPosition; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg Position was successfull! New targetPosition: %d", bottomValue); - this->enterData(k, i, bottomValue); - }else if(!(this->testNeighbors(k, i, avgPosition).allNeighborsPassed)) { - this->tableRow[k].tableEntry[i].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right with Avg position (%d)(%d)(%d), readings (%d)", k, i, - avgPosition, this->tableRow[k].tableEntry[i].readings); - } if(this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, newValue).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "New Value is valid, %d", newValue); - this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, newValue); - }else if(!(this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, newValue).allNeighborsPassed)){ - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom with new Value (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, - newValue, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); - } - } - else { - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, - testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); - } - } - return; - } - - /* - // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table - TestResults testResults = this->testNeighbors(k, i, targetPosition); - if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { - // test which bit fields didn't match - if (!testResults.leftNeighbor.passedTest) { - if(testResults.leftNeighbor.i == k && (testResults.leftNeighbor.targetPosition <= targetPosition+30 && testResults.leftNeighbor.targetPosition >= targetPosition)){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and target pos is within range"); - SS2K_LOG(POWERTABLE_LOG_TAG, "Range: %f to %d", targetPosition, testResults.leftNeighbor.targetPosition); - int avgValue = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; - int newValue = targetPosition - (avgValue - targetPosition); //this is the possible new value for the neighbor - if(this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, newValue).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "New Value is valid, %d", newValue); - this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, newValue); - }else { - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed with new Value (%d)(%d)(%f), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, newValue, - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); - } - }else{ - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); - } - } - - if (!testResults.rightNeighbor.passedTest) { - if(testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition-30 && testResults.rightNeighbor.targetPosition <= targetPosition)){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and target pos is within range"); - SS2K_LOG(POWERTABLE_LOG_TAG, "Range: %f to %d", targetPosition, testResults.rightNeighbor.targetPosition); - int avgValue = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; - int newValue = targetPosition + (avgValue - targetPosition); //this is the possible new value for the neighbor - if(this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, newValue).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "New Value is valid, %d", newValue); - this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, newValue); - } else { - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right with new value(%d)(%d)(%f), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, - newValue, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); - } - }else { - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, - testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); - } - } - - if (!testResults.topNeighbor.passedTest) { - if(testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition-30 && testResults.topNeighbor.targetPosition <= targetPosition)){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and target pos is within range"); - SS2K_LOG(POWERTABLE_LOG_TAG, "Range: %f to %d", targetPosition, testResults.topNeighbor.targetPosition); - int avgValue = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; - int newValue = targetPosition + (avgValue - targetPosition); //this is the possible new value for the neighbor - if(this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, newValue).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "New Value is valid, %d", newValue); - this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, newValue); - }else { - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top with new Value (%d)(%d)(%f), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, newValue, - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - } - }else{ - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - } - } - if (!testResults.bottomNeighbor.passedTest) { - if(testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition+30 && testResults.bottomNeighbor.targetPosition >= targetPosition)){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and target pos is within range"); - SS2K_LOG(POWERTABLE_LOG_TAG, "Range: %f to %d", targetPosition, testResults.bottomNeighbor.targetPosition); - int avgValue = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; - int newValue = targetPosition + (avgValue - targetPosition); //this is the possible new value for the neighbor - if(this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, newValue).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "New Value is valid, %d", newValue); - this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, newValue); - }else { - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom with new Value (%d)(%d)(%f), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, - newValue, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed){ + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %d", targetPosition); + this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); + } + + if(this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); + this->enterData(k, i, avgPosition); + } + + if(this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed){ + SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom Neighbors position was valid with Top Neighbors cadence and watts! Bottom Neighbor Position: %d", testResults.topNeighbor.targetPosition); + this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition); } - }else{ + + return; + } else { this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, - testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, + testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); } } return; } - */ // Update or create a new entry if (this->tableRow[k].tableEntry[i].readings == 0) { // if first reading in this entry @@ -1025,6 +929,9 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } this->tableRow[k].tableEntry[i].readings++; + //or + //this->enterData(k, i, (int)targetPosition); + // Attempt to fill the table with calculated data... if (this->getNumEntries() > 4) { int entries = 0; @@ -1043,7 +950,6 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } void PowerTable::enterData(int i, int j, int pos){ - // Update or create a new entry if (this->tableRow[i].tableEntry[j].readings == 0) { // if first reading in this entry this->tableRow[i].tableEntry[j].targetPosition = pos; SS2K_LOG(POWERTABLE_LOG_TAG, "New entry recorded (%d)(%d)(%d)", i, j, this->tableRow[i].tableEntry[j].targetPosition); From 589f5fc79d3e6e50dcdb8947d25b7970e6cfeebf Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Thu, 13 Feb 2025 15:41:35 -0600 Subject: [PATCH 054/451] fixed logging error --- src/ERG_Mode.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index d2dc13db..120f3943 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -803,7 +803,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); if(this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed){ //check if the current position moved left is valid - SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %d", targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %f", targetPosition); this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); //enter the data } @@ -832,7 +832,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved right was valid! Current position: %d", targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved right was valid! Current position: %f", targetPosition); this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); } @@ -861,7 +861,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %d", targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); } @@ -890,7 +890,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %d", targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); } From ccfb22a484548d04acbc89e211a1efdb7bbd73d2 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Fri, 14 Feb 2025 10:01:35 -0600 Subject: [PATCH 055/451] working --- src/BLE_Fitness_Machine_Service.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BLE_Fitness_Machine_Service.cpp b/src/BLE_Fitness_Machine_Service.cpp index 2131caca..a062f4e5 100644 --- a/src/BLE_Fitness_Machine_Service.cpp +++ b/src/BLE_Fitness_Machine_Service.cpp @@ -281,12 +281,12 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { fitnessMachineControlPoint->setValue(returnValue, 3); fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); fitnessMachineControlPoint->indicate(); - // only notify if the value has changed + /* only notify if the value has changed static uint8_t _lastTrainingStatus[2] = {0x00, 0x00}; if (memcmp(_lastTrainingStatus, ftmsTrainingStatus, 2) != 0) { memcpy(_lastTrainingStatus, ftmsTrainingStatus, 2); fitnessMachineTrainingStatus->notify(); - } + } */ fitnessMachineStatusCharacteristic->notify(); } } From 2478651cf7818aead02a0b0b13c3116f970813fd Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sat, 15 Feb 2025 13:55:11 -0600 Subject: [PATCH 056/451] wip --- src/ERG_Mode.cpp | 281 +++++++++++++++++++++-------------------------- 1 file changed, 127 insertions(+), 154 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index c5010f60..6fefb86b 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -70,7 +70,7 @@ void PowerTable::runERG() { // only run _manageSaveState every 5 seconds static unsigned long int saveStateTimer = millis(); if ((millis() - saveStateTimer) > 5000) { - //load the power table, true to skip checks. + // load the power table, true to skip checks. this->_manageSaveState(true); saveStateTimer = millis(); } @@ -148,30 +148,31 @@ int PowerBuffer::getReadings() { return ret; } -void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, Measurement watts) { //this basically checks the constaraints and if everything is good it adds it into the powerbuffer. no need to change - static int calcStep; //calcStep is the percentage range of the stepper motor +void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, + Measurement watts) { // this basically checks the constaraints and if everything is good it adds it into the powerbuffer. no need to change + static int calcStep; // calcStep is the percentage range of the stepper motor if ((cadence >= (MINIMUM_TABLE_CAD - (POWERTABLE_CAD_INCREMENT / 2))) && - (cadence <= (MINIMUM_TABLE_CAD + (POWERTABLE_CAD_INCREMENT * POWERTABLE_CAD_SIZE) - (POWERTABLE_CAD_SIZE / 2))) && (watts.getValue() > 10) && //adding constraints + (cadence <= (MINIMUM_TABLE_CAD + (POWERTABLE_CAD_INCREMENT * POWERTABLE_CAD_SIZE) - (POWERTABLE_CAD_SIZE / 2))) && (watts.getValue() > 10) && // adding constraints (watts.getValue() < (POWERTABLE_WATT_SIZE * POWERTABLE_WATT_INCREMENT))) { + if (rtConfig->getMaxStep() == DEFAULT_STEPPER_TRAVEL && rtConfig->getMinStep() == -DEFAULT_STEPPER_TRAVEL) { + int totalStep = ((rtConfig->getMaxStep() - rtConfig->getMaxStep() / 2000000)); // stepper distance is 400,000,000 so dividing it by 2,000,000 gives us 200 + calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range + } else if (rtConfig->getHomed()) { + int totalStep = (rtConfig->getMaxStep() / 100); // maxStep should be around 22000 / 100 gives us 200ish + calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range + } - if(rtConfig->getMaxStep() == DEFAULT_STEPPER_TRAVEL && rtConfig->getMinStep() == -DEFAULT_STEPPER_TRAVEL){ - int totalStep = ((rtConfig->getMaxStep() - rtConfig->getMaxStep() / 2000000)); //stepper distance is 400,000,000 so dividing it by 2,000,000 gives us 200 - calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range - } else if (rtConfig->getHomed()){ - int totalStep = (rtConfig->getMaxStep() / 100); //maxStep should be around 22000 / 100 gives us 200ish - calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range - } - - if (powerBuffer.powerEntry[0].readings == 0) { //we need to make sure stepper position is not negative so it only takes positive resistance values + if (powerBuffer.powerEntry[0].readings == 0) { // we need to make sure stepper position is not negative so it only takes positive resistance values // Take Initial reading powerBuffer.set(0); // Check if the current stepper posistion is within a 5% range of the previous stepper position and that the current position is not negative - } if (((ss2k->getCurrentPosition()/100) >= ((powerBuffer.powerEntry[0].targetPosition) - calcStep)) && - ((ss2k->getCurrentPosition()/100) <= ((powerBuffer.powerEntry[0].targetPosition) + calcStep))) { + } + if (((ss2k->getCurrentPosition() / 100) >= ((powerBuffer.powerEntry[0].targetPosition) - calcStep)) && + ((ss2k->getCurrentPosition() / 100) <= ((powerBuffer.powerEntry[0].targetPosition) + calcStep))) { for (int i = 1; i < POWER_SAMPLES; i++) { if (powerBuffer.powerEntry[i].readings == 0) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Success!"); + SS2K_LOG(POWERTABLE_LOG_TAG, "Success!"); powerBuffer.set(i); // Add additional readings to the buffer. break; } @@ -181,8 +182,8 @@ void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, Measur this->toLog(); this->_manageSaveState(); powerBuffer.reset(); - } - } else { // Reading was outside the range - clear the buffer and start over. + } + } else { // Reading was outside the range - clear the buffer and start over. powerBuffer.reset(); } } @@ -380,7 +381,7 @@ TestResults PowerTable::testNeighbors(int i, int j, int testValue) { returnResult.leftNeighbor.i = i; returnResult.leftNeighbor.j = left; returnResult.leftNeighbor.found = 1; - break; + break; } } } @@ -803,8 +804,8 @@ int downVote(int targetValue, int neighborValue) { // penalty = penaltyFactor * log(delta + 1); // max penalty is 10 - if (penalty > 10) { - penalty = 10; + if (penalty > MAX_NEIGHBOR_WEIGHT) { + penalty = MAX_NEIGHBOR_WEIGHT; } // round up penalty to make it an int @@ -868,165 +869,153 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { // test which bit fields didn't match if (!testResults.leftNeighbor.passedTest) { - if(testResults.leftNeighbor.i == k && (testResults.leftNeighbor.targetPosition <= targetPosition+30 && testResults.leftNeighbor.targetPosition >= targetPosition)){ //check if the cadence is the same and positions are within a set range in this case its 30. - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and targetPosition is within range"); + if (testResults.leftNeighbor.i == k && + (testResults.leftNeighbor.targetPosition <= targetPosition + 30 && + testResults.leftNeighbor.targetPosition >= targetPosition)) { // check if the cadence is the same and positions are within a set range in this case its 30. + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and targetPosition is within range"); - int avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; //calculate the average + int avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - if(this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed){ //check if the current position moved left is valid - SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %f", targetPosition); - this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); //enter the data - } - - if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ //checks if the avg position with the current watts and cadence is valid - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - this->enterData(k, i, avgPosition); //enter the data - } - - if(this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition).allNeighborsPassed){ //checks if the failed nighbor is valid with the right neighbors cadence and watts - SS2K_LOG(POWERTABLE_LOG_TAG, "Left Neighbors position was valid with Right Neighbors cadence and watts! Left Neighbor Position: %d", testResults.leftNeighbor.targetPosition); - this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition); + if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) { // check if the current position moved left is valid + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %f", targetPosition); + this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); // enter the data } - return; - } else { //if not we still get rid of the reading - // determine penalty amount before applying to failed neighbor - int penalty = downVote(targetPosition, testResults.leftNeighbor.targetPosition); - - // make sure downvotes isn't at max - if (this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; - penalty = 0; - } + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { // checks if the avg position with the current watts and cadence is valid + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); + this->enterData(k, i, avgPosition); // enter the data + } - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings -= penalty; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%f), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition) + .allNeighborsPassed) { // checks if the failed nighbor is valid with the right neighbors cadence and watts + SS2K_LOG(POWERTABLE_LOG_TAG, "Left Neighbors position was valid with Right Neighbors cadence and watts! Left Neighbor Position: %d", + testResults.leftNeighbor.targetPosition); + this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition); + } + return; + } else { // if not we still get rid of the reading + // determine penalty amount before applying to failed neighbor + int penalty = downVote(targetPosition, testResults.leftNeighbor.targetPosition); + // make sure downvotes isn't at max + if (this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; + penalty = 0; + } + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings -= penalty; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%f), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); } } - if (!testResults.rightNeighbor.passedTest) { - if(testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition-30 && testResults.rightNeighbor.targetPosition <= targetPosition)){ - - int avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; + if (testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition - 30 && testResults.rightNeighbor.targetPosition <= targetPosition)) { + int avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - - if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved right was valid! Current position: %f", targetPosition); - this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); - } - - if(this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - this->enterData(k, i, avgPosition); - } - - if(this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Right Neighbors position was valid with Left Neighbors cadence and watts! Right Neighbor Position: %d", testResults.rightNeighbor.targetPosition); - this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition); + + if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved right was valid! Current position: %f", targetPosition); + this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); + } + + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); + this->enterData(k, i, avgPosition); } - return; + if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Right Neighbors position was valid with Left Neighbors cadence and watts! Right Neighbor Position: %d", + testResults.rightNeighbor.targetPosition); + this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition); + } + return; } else { // determine penalty amount before applying to failed neighbor - int penalty = downVote(targetPosition, testResults.rightNeighbor.targetPosition); - - // make sure downvotes isn't at max - if (this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; - penalty = 0; - } - - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings -= penalty; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, - testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + int penalty = downVote(targetPosition, testResults.rightNeighbor.targetPosition); + // make sure downvotes isn't at max + if (this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; + penalty = 0; + } + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings -= penalty; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, + testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); } } - if (!testResults.topNeighbor.passedTest) { - if(testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition-30 && testResults.topNeighbor.targetPosition <= targetPosition)){ - - int avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; + if (testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition - 30 && testResults.topNeighbor.targetPosition <= targetPosition)) { + int avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); - this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); - } + if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); + this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); + } - if(this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); this->enterData(k, i, avgPosition); } - if(this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Top Neighbors position was valid with Bottom Neighbors cadence and watts! Top Neighbor Position: %d", testResults.topNeighbor.targetPosition); - this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); + if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Top Neighbors position was valid with Bottom Neighbors cadence and watts! Top Neighbor Position: %d", + testResults.topNeighbor.targetPosition); + this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); } - return; + return; } else { - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, - testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); - } - } - - // determine penalty amount before applying to failed neighbor - int penalty = downVote(targetPosition, testResults.topNeighbor.targetPosition); + // determine penalty amount before applying to failed neighbor + int penalty = downVote(targetPosition, testResults.topNeighbor.targetPosition); + // make sure downvotes isn't at max + if (this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; + penalty = 0; + } - // make sure downvotes isn't at max - if (this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; - penalty = 0; + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings -= penalty; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); } - - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings -= penalty; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); } if (!testResults.bottomNeighbor.passedTest) { - if(testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition+30 && testResults.bottomNeighbor.targetPosition >= targetPosition)){ - - int avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; + if (testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition + 30 && testResults.bottomNeighbor.targetPosition >= targetPosition)) { + int avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); - this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); - } - - if(this->testNeighbors(k, i, avgPosition).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); + if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); + this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); + } + + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); this->enterData(k, i, avgPosition); - } + } - if(this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed){ - SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom Neighbors position was valid with Top Neighbors cadence and watts! Bottom Neighbor Position: %d", testResults.topNeighbor.targetPosition); + if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom Neighbors position was valid with Top Neighbors cadence and watts! Bottom Neighbor Position: %d", + testResults.topNeighbor.targetPosition); this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition); } - - return; + + return; } else { // determine penalty amount before applying to failed neighbor - int penalty = downVote(targetPosition, testResults.bottomNeighbor.targetPosition); - - // make sure downvotes isn't at max - if (this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; - penalty = 0; - } + int penalty = downVote(targetPosition, testResults.bottomNeighbor.targetPosition); - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings -= penalty; + // make sure downvotes isn't at max + if (this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; + penalty = 0; + } + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings -= penalty; SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, - testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); } } - return; } @@ -1045,8 +1034,8 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } this->tableRow[k].tableEntry[i].readings++; - //or - //this->enterData(k, i, (int)targetPosition); + // or + // this->enterData(k, i, (int)targetPosition); // Attempt to fill the table with calculated data... if (this->getNumEntries() > 4) { @@ -1065,23 +1054,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { BLE_ss2kCustomCharacteristic::notify(0x27, k); } -void PowerTable::enterData(int i, int j, int pos){ - if (this->tableRow[i].tableEntry[j].readings == 0) { // if first reading in this entry - this->tableRow[i].tableEntry[j].targetPosition = pos; - SS2K_LOG(POWERTABLE_LOG_TAG, "New entry recorded (%d)(%d)(%d)", i, j, this->tableRow[i].tableEntry[j].targetPosition); - } else { // Average and update the readings. - this->tableRow[i].tableEntry[j].targetPosition = - (pos + (this->tableRow[i].tableEntry[j].targetPosition * this->tableRow[i].tableEntry[j].readings)) / (this->tableRow[i].tableEntry[j].readings + 1.0); - SS2K_LOG(POWERTABLE_LOG_TAG, "Existing entry averaged (%d)(%d)(%d), readings(%d)", i, j, this->tableRow[i].tableEntry[j].targetPosition, - this->tableRow[i].tableEntry[j].readings); - if (this->tableRow[i].tableEntry[j].readings > POWER_SAMPLES * 2) { - this->tableRow[i].tableEntry[j].readings = POWER_SAMPLES * 2; // keep from diluting recent readings too far. - } - } - this->tableRow[i].tableEntry[j].readings++; -} - -void PowerTable::enterData(int i, int j, int pos){ +void PowerTable::enterData(int i, int j, int pos) { if (this->tableRow[i].tableEntry[j].readings == 0) { // if first reading in this entry this->tableRow[i].tableEntry[j].targetPosition = pos; SS2K_LOG(POWERTABLE_LOG_TAG, "New entry recorded (%d)(%d)(%d)", i, j, this->tableRow[i].tableEntry[j].targetPosition); From a777c8881f9b33b893672f90916f11c401207159 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sat, 15 Feb 2025 14:04:21 -0600 Subject: [PATCH 057/451] wip --- src/ERG_Mode.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index ed3d6768..c7b7d122 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -159,7 +159,7 @@ void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, int totalStep = ((rtConfig->getMaxStep() - rtConfig->getMaxStep() / 2000000)); // stepper distance is 400,000,000 so dividing it by 2,000,000 gives us 200 calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range } else if (rtConfig->getHomed()) { - int totalStep = (rtConfig->getMaxStep() / 100); // maxStep should be around 22000 / 100 gives us 200ish + int totalStep = (rtConfig->getMaxStep() / TABLE_DIVISOR); // maxStep should be around 22000 / TABLE_DIVISOR gives us 200ish calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range } @@ -168,8 +168,8 @@ void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, powerBuffer.set(0); // Check if the current stepper posistion is within a 5% range of the previous stepper position and that the current position is not negative } - if (((ss2k->getCurrentPosition() / 100) >= ((powerBuffer.powerEntry[0].targetPosition) - calcStep)) && - ((ss2k->getCurrentPosition() / 100) <= ((powerBuffer.powerEntry[0].targetPosition) + calcStep))) { + if (((ss2k->getCurrentPosition() / TABLE_DIVISOR) >= ((powerBuffer.powerEntry[0].targetPosition) - calcStep)) && + ((ss2k->getCurrentPosition() / TABLE_DIVISOR) <= ((powerBuffer.powerEntry[0].targetPosition) + calcStep))) { for (int i = 1; i < POWER_SAMPLES; i++) { if (powerBuffer.powerEntry[i].readings == 0) { SS2K_LOG(POWERTABLE_LOG_TAG, "Success!"); @@ -1256,8 +1256,8 @@ bool PowerTable::_save() { } int32_t PowerTable::lookupWatts(int cad, int32_t targetPosition) { - // Convert targetPosition from external format (x100) to internal format - int16_t internalPosition = targetPosition / 100; + // Convert targetPosition from external format (xTABLE_DIVISOR) to internal format + int16_t internalPosition = targetPosition / TABLE_DIVISOR; // Calculate cadence index int cadIndex = round(((float)cad - (float)MINIMUM_TABLE_CAD) / (float)POWERTABLE_CAD_INCREMENT); From 9f90379343c56dbc9fb045023704627db7880b90 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sat, 15 Feb 2025 14:42:25 -0600 Subject: [PATCH 058/451] Created Power_Table.cpp and .h --- include/ERG_Mode.h | 135 +-- include/Power_Table.h | 140 ++++ include/settings.h | 2 +- src/BLE_Custom_Characteristic.cpp | 2 +- src/ERG_Mode.cpp | 1295 +---------------------------- src/Main.cpp | 5 +- src/Power_Table.cpp | 1295 +++++++++++++++++++++++++++++ 7 files changed, 1453 insertions(+), 1421 deletions(-) create mode 100644 include/Power_Table.h create mode 100644 src/Power_Table.cpp diff --git a/include/ERG_Mode.h b/include/ERG_Mode.h index 84085a49..4244f802 100644 --- a/include/ERG_Mode.h +++ b/include/ERG_Mode.h @@ -10,141 +10,14 @@ #include "settings.h" #include "SmartSpin_parameters.h" -#define ERG_MODE_LOG_TAG "ERG_Mode" #define ERG_MODE_LOG_CSV_TAG "ERG_Mode_CSV" -#define POWERTABLE_LOG_TAG "PTable" +#define ERG_MODE_LOG_TAG "ERG_Mode" #define ERG_MODE_DELAY 700 -#define RETURN_ERROR INT32_MIN - -class PowerEntry { - public: - int watts; - int resistance; - int32_t targetPosition; - int cad; - int readings; - - PowerEntry() { - this->watts = 0; - this->targetPosition = 0; - this->cad = 0; - this->readings = 0; - this->resistance = 0; - } -}; - -class PowerBuffer { - public: - PowerEntry powerEntry[POWER_SAMPLES]; - void set(int); - void reset(); - int getReadings(); -}; - -// Simplifying the table to save memory since we no longer need watts and cad. -class TableEntry { - public: - int16_t targetPosition; - int8_t readings; - - TableEntry() { - this->targetPosition = INT16_MIN; - this->readings = 0; - } -}; - -// Combine Entries to make a row. -class TableRow { - public: - TableEntry tableEntry[POWERTABLE_WATT_SIZE]; -}; - -class TestResults { - struct Neighbor { - unsigned int found : 1; - unsigned int passedTest : 1; - int8_t i; - int8_t j; - int16_t targetPosition; - - Neighbor() { - found = false; - passedTest = false; - i = INT8_MIN; - j = INT8_MIN; - targetPosition = INT16_MIN; - } - }; - - public: - Neighbor leftNeighbor; - Neighbor rightNeighbor; - Neighbor topNeighbor; - Neighbor bottomNeighbor; - unsigned int allNeighborsFound : 1; - unsigned int allNeighborsPassed : 1; - - TestResults() { - allNeighborsFound = false; - allNeighborsPassed = false; - } -}; - -class PowerTable { - public: - bool saveFlag = false; - TableRow tableRow[POWERTABLE_CAD_SIZE]; - - // What used to be in the ERGTaskLoop(). This is the main control function for ERG Mode and the powertable operations. - void runERG(); - - // Pick up new power value and put them into the power table - void processPowerValue(PowerBuffer& powerBuffer, int cadence, Measurement power); - - // Sets stepper min/max value from power table - void setStepperMinMax(); - - // Catalogs a new entry into the power table. - void newEntry(PowerBuffer& powerBuffer); - - // enters data into power table - void enterData(int i, int j, int pos); - - // returns incline for wattTarget. Null if not found. - int32_t lookup(int watts, int cad); - - // returns watts for given cadence and target position. Returns RETURN_ERROR if not found. - int32_t lookupWatts(int cad, int32_t targetPosition); - - // automatically load or save the Power Table - bool _manageSaveState(bool canSkipReliabilityChecks = false); - - // save powertable from littlefs - bool _save(); - - // Reset the active power table and delete the saved power table. - bool reset(); - - // return number of readings in the table. - int getNumReadings(); - - // Display power table in log - void toLog(); - - private: - unsigned long lastSaveTime = millis(); - bool _hasBeenLoadedThisSession = false; - TestResults testNeighbors(int i, int j, int value); - void fillTable(); - void extrapFillTable(); - void extrapolateDiagonal(); - int getNumEntries(); - // remove entries with < 1 readings - void clean(); -}; class ErgMode { public: + // What used to be in the ERGTaskLoop(). This is the main control function for ERG Mode and the powertable operations. + void runERG(); void computeErg(); void computeResistance(); void _writeLogHeader(); @@ -173,4 +46,4 @@ class ErgMode { void _updateValues(int newCadence, Measurement& newWatts, float newIncline); }; -extern PowerTable* powerTable; +extern ErgMode* ergMode; diff --git a/include/Power_Table.h b/include/Power_Table.h new file mode 100644 index 00000000..a7fa3579 --- /dev/null +++ b/include/Power_Table.h @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2020 Anthony Doud & Joel Baranick + * All rights reserved + * + * SPDX-License-Identifier: GPL-2.0-only + */ + +#pragma once + +#include "settings.h" +#include "SmartSpin_parameters.h" + +#define POWERTABLE_LOG_TAG "PTable" +#define RETURN_ERROR INT32_MIN + +class PowerEntry { + public: + int watts; + int resistance; + int32_t targetPosition; + int cad; + int readings; + + PowerEntry() { + this->watts = 0; + this->targetPosition = 0; + this->cad = 0; + this->readings = 0; + this->resistance = 0; + } +}; + +class PowerBuffer { + public: + PowerEntry powerEntry[POWER_SAMPLES]; + void set(int); + void reset(); + int getReadings(); +}; + +// Simplifying the table to save memory since we no longer need watts and cad. +class TableEntry { + public: + int16_t targetPosition; + int8_t readings; + + TableEntry() { + this->targetPosition = INT16_MIN; + this->readings = 0; + } +}; + +// Combine Entries to make a row. +class TableRow { + public: + TableEntry tableEntry[POWERTABLE_WATT_SIZE]; +}; + +class TestResults { + struct Neighbor { + unsigned int found : 1; + unsigned int passedTest : 1; + int8_t i; + int8_t j; + int16_t targetPosition; + + Neighbor() { + found = false; + passedTest = false; + i = INT8_MIN; + j = INT8_MIN; + targetPosition = INT16_MIN; + } + }; + + public: + Neighbor leftNeighbor; + Neighbor rightNeighbor; + Neighbor topNeighbor; + Neighbor bottomNeighbor; + unsigned int allNeighborsFound : 1; + unsigned int allNeighborsPassed : 1; + + TestResults() { + allNeighborsFound = false; + allNeighborsPassed = false; + } +}; + +class PowerTable { + public: + bool saveFlag = false; + bool _hasBeenLoadedThisSession = false; + TableRow tableRow[POWERTABLE_CAD_SIZE]; + + // Pick up new power value and put them into the power table + void processPowerValue(PowerBuffer& powerBuffer, int cadence, Measurement power); + + // Sets stepper min/max value from power table + void setStepperMinMax(); + + // Catalogs a new entry into the power table. + void newEntry(PowerBuffer& powerBuffer); + + // enters data into power table + void enterData(int i, int j, int pos); + + // returns incline for wattTarget. Null if not found. + int32_t lookup(int watts, int cad); + + // returns watts for given cadence and target position. Returns RETURN_ERROR if not found. + int32_t lookupWatts(int cad, int32_t targetPosition); + + // automatically load or save the Power Table + bool _manageSaveState(bool canSkipReliabilityChecks = false); + + // save powertable from littlefs + bool _save(); + + // Reset the active power table and delete the saved power table. + bool reset(); + + // return number of readings in the table. + int getNumReadings(); + + // Display power table in log + void toLog(); + + private: + unsigned long lastSaveTime = millis(); + TestResults testNeighbors(int i, int j, int value); + void fillTable(); + void extrapFillTable(); + void extrapolateDiagonal(); + int getNumEntries(); + // remove entries with < 1 readings + void clean(); +}; + +extern PowerTable* powerTable; \ No newline at end of file diff --git a/include/settings.h b/include/settings.h index db02900e..417b4785 100644 --- a/include/settings.h +++ b/include/settings.h @@ -257,7 +257,7 @@ const char* const DEFAULT_PASSWORD = "password"; // #define ERG_GUARDRAILS //Uncomment to enable the use of the power table for ERG mode. -//#define ERG_MODE_USE_POWER_TABLE +#define ERG_MODE_USE_POWER_TABLE // Uncomment to use the PID controller for ERG mode. #define ERG_MODE_USE_PID diff --git a/src/BLE_Custom_Characteristic.cpp b/src/BLE_Custom_Characteristic.cpp index 07c8a389..41499910 100644 --- a/src/BLE_Custom_Characteristic.cpp +++ b/src/BLE_Custom_Characteristic.cpp @@ -84,7 +84,7 @@ This characteristic allows for reading and writing various user configuration pa */ #include -#include +#include #include #include diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index c7b7d122..0eb026d6 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -9,6 +9,7 @@ #include "SS2KLog.h" #include "Main.h" #include "BLE_Custom_Characteristic.h" +#include "Power_Table.h" #include #include #include @@ -17,14 +18,12 @@ #include #include -PowerTable* powerTable = new PowerTable; - // Create a torque table representing 0w-1000w in 50w increments. // i.e. powerTable[1] corresponds to the incline required for 50w. powerTable[2] is the incline required for 100w and so on. static unsigned long int ergTimer = millis(); -void PowerTable::runERG() { +void ErgMode::runERG() { static ErgMode ergMode; static PowerBuffer powerBuffer; static bool hasConnectedPowerMeter = false; @@ -46,14 +45,14 @@ void PowerTable::runERG() { static unsigned long int saveFlagCooldown = 0; // save powertable if saveFlag has been set for 10 seconds using a saveFlagCooldown timer // this is to provide enough time to transmit a new powerTable using BLE. - if (this->saveFlag) { + if (powerTable->saveFlag) { if (saveFlagCooldown == 0) { saveFlagCooldown = millis(); } if ((millis() - saveFlagCooldown) > 10000) { - this->_save(); + powerTable->_save(); saveFlagCooldown = 0; - saveFlag = false; + powerTable->saveFlag = false; } } @@ -64,14 +63,14 @@ void PowerTable::runERG() { if ((!spinBLEClient.connectedPM || userConfig->getPTab4Pwr()) && rtConfig->cad.getValue() && rtConfig->getHomed()) { // Lookup watts using the Power Table. pTabUsed4Pwr = true; - if (this->_hasBeenLoadedThisSession) { - rtConfig->watts.setValue(lookupWatts(rtConfig->cad.getValue(), ss2k->getCurrentPosition())); + if (powerTable->_hasBeenLoadedThisSession) { + rtConfig->watts.setValue(powerTable->lookupWatts(rtConfig->cad.getValue(), ss2k->getCurrentPosition())); } else { // only run _manageSaveState every 5 seconds static unsigned long int saveStateTimer = millis(); if ((millis() - saveStateTimer) > 5000) { // load the power table, true to skip checks. - this->_manageSaveState(true); + powerTable->_manageSaveState(true); saveStateTimer = millis(); } } @@ -121,1284 +120,6 @@ void PowerTable::runERG() { } } -void PowerBuffer::set(int i) { - this->powerEntry[i].readings++; - this->powerEntry[i].watts = rtConfig->watts.getValue(); - this->powerEntry[i].cad = rtConfig->cad.getValue(); - this->powerEntry[i].targetPosition = ss2k->getCurrentPosition() / TABLE_DIVISOR; // dividing by 10 to save memory. -} - -void PowerBuffer::reset() { - for (int i = 0; i < POWER_SAMPLES; i++) { - this->powerEntry[i].readings = 0; - this->powerEntry[i].cad = 0; - this->powerEntry[i].watts = 0; - this->powerEntry[i].targetPosition = 0; - } -} - -// return the number of entries with readings. -int PowerBuffer::getReadings() { - int ret = 0; - for (int i = 0; i < POWER_SAMPLES; i++) { - if (this->powerEntry[i].readings != 0) { - ret++; - } - } - return ret; -} - -void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, - Measurement watts) { // this basically checks the constaraints and if everything is good it adds it into the powerbuffer. no need to change - static int calcStep; // calcStep is the percentage range of the stepper motor - - if ((cadence >= (MINIMUM_TABLE_CAD - (POWERTABLE_CAD_INCREMENT / 2))) && - (cadence <= (MINIMUM_TABLE_CAD + (POWERTABLE_CAD_INCREMENT * POWERTABLE_CAD_SIZE) - (POWERTABLE_CAD_SIZE / 2))) && (watts.getValue() > 10) && // adding constraints - (watts.getValue() < (POWERTABLE_WATT_SIZE * POWERTABLE_WATT_INCREMENT))) { - if (rtConfig->getMaxStep() == DEFAULT_STEPPER_TRAVEL && rtConfig->getMinStep() == -DEFAULT_STEPPER_TRAVEL) { - int totalStep = ((rtConfig->getMaxStep() - rtConfig->getMaxStep() / 2000000)); // stepper distance is 400,000,000 so dividing it by 2,000,000 gives us 200 - calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range - } else if (rtConfig->getHomed()) { - int totalStep = (rtConfig->getMaxStep() / TABLE_DIVISOR); // maxStep should be around 22000 / TABLE_DIVISOR gives us 200ish - calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range - } - - if (powerBuffer.powerEntry[0].readings == 0) { // we need to make sure stepper position is not negative so it only takes positive resistance values - // Take Initial reading - powerBuffer.set(0); - // Check if the current stepper posistion is within a 5% range of the previous stepper position and that the current position is not negative - } - if (((ss2k->getCurrentPosition() / TABLE_DIVISOR) >= ((powerBuffer.powerEntry[0].targetPosition) - calcStep)) && - ((ss2k->getCurrentPosition() / TABLE_DIVISOR) <= ((powerBuffer.powerEntry[0].targetPosition) + calcStep))) { - for (int i = 1; i < POWER_SAMPLES; i++) { - if (powerBuffer.powerEntry[i].readings == 0) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Success!"); - powerBuffer.set(i); // Add additional readings to the buffer. - break; - } - } - if (powerBuffer.powerEntry[POWER_SAMPLES - 1].readings == 1) { // If buffer is full, create a new table entry and clear the buffer. - this->newEntry(powerBuffer); - this->toLog(); - this->_manageSaveState(); - powerBuffer.reset(); - } - } else { // Reading was outside the range - clear the buffer and start over. - powerBuffer.reset(); - } - } -} - -// Set min / max stepper position -void PowerTable::setStepperMinMax() { - int32_t _return = RETURN_ERROR; - - // if Homing was preformed, skip estimating min_max - if (rtConfig->getHomed()) { - SS2K_LOG(ERG_MODE_LOG_TAG, "Using detected travel limits during homing"); - return; - } - - // if the FTMS device reports resistance feedback, skip estimating min_max - if (rtConfig->resistance.getValue() > 0) { - rtConfig->setMinStep(-DEFAULT_STEPPER_TRAVEL); - rtConfig->setMaxStep(DEFAULT_STEPPER_TRAVEL); - SS2K_LOG(ERG_MODE_LOG_TAG, "Using Resistance Travel Limits"); - return; - } - - int minBreakWatts = userConfig->getMinWatts(); - if (minBreakWatts > 1) { - _return = this->lookup(minBreakWatts, NORMAL_CAD); - if (_return != RETURN_ERROR) { - // never set less than one shift below current incline. - if ((_return >= ss2k->getCurrentPosition()) && (rtConfig->watts.getValue() > userConfig->getMinWatts())) { - _return = ss2k->getCurrentPosition() - userConfig->getShiftStep(); - SS2K_LOG(ERG_MODE_LOG_TAG, "Min Position too close to current incline: %d", _return); - } - // never set above max step. - if (_return >= rtConfig->getMaxStep()) { - _return = ss2k->getCurrentPosition() - userConfig->getShiftStep() * 2; - SS2K_LOG(ERG_MODE_LOG_TAG, "Min Position above max!: %d", _return); - } - rtConfig->setMinStep(_return); - SS2K_LOG(ERG_MODE_LOG_TAG, "Min Position Set: %d", _return); - } - } - - int maxBreakWatts = userConfig->getMaxWatts(); - if (maxBreakWatts > 1) { - _return = this->lookup(maxBreakWatts, NORMAL_CAD); - if (_return != RETURN_ERROR) { - // never set less than one shift above current incline. - if ((_return <= ss2k->getCurrentPosition()) && (rtConfig->watts.getValue() < userConfig->getMaxWatts())) { - _return = ss2k->getCurrentPosition() + userConfig->getShiftStep(); - SS2K_LOG(ERG_MODE_LOG_TAG, "Max Position too close to current incline: %d", _return); - } - // never set below min step. - if (_return <= rtConfig->getMinStep()) { - _return = ss2k->getCurrentPosition() + userConfig->getShiftStep() * 2; - SS2K_LOG(ERG_MODE_LOG_TAG, "Max Position below min!: %d", _return); - } - rtConfig->setMaxStep(_return); - SS2K_LOG(ERG_MODE_LOG_TAG, "Max Position Set: %d", _return); - } - } -} - -int32_t PowerTable::lookup(int watts, int cad) { - int cadIndex = round(((float)cad - (float)MINIMUM_TABLE_CAD) / (float)POWERTABLE_CAD_INCREMENT); - int wattIndex = round((float)watts / (float)POWERTABLE_WATT_INCREMENT); - - // If request is outside table limits, perform linear extrapolation - if (cad < MINIMUM_TABLE_CAD || cad > (MINIMUM_TABLE_CAD + (POWERTABLE_CAD_SIZE - 1) * POWERTABLE_CAD_INCREMENT) || - watts > (POWERTABLE_WATT_SIZE - 1) * POWERTABLE_WATT_INCREMENT) { - // Perform linear extrapolation based on existing data - int extrapolatedValue = INT16_MIN; - - // Extrapolation for cadence out of bounds - if (cad < MINIMUM_TABLE_CAD || cad > (MINIMUM_TABLE_CAD + (POWERTABLE_CAD_SIZE - 1) * POWERTABLE_CAD_INCREMENT)) { - int extrapRow1 = -1, extrapRow2 = -1; - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[wattIndex].targetPosition != INT16_MIN) { - extrapRow1 = i; - break; - } - } - for (int i = POWERTABLE_CAD_SIZE - 1; i >= 0; --i) { - if (this->tableRow[i].tableEntry[wattIndex].targetPosition != INT16_MIN) { - extrapRow2 = i; - break; - } - } - if (extrapRow1 != -1 && extrapRow2 != -1) { - int cad1 = extrapRow1 * POWERTABLE_CAD_INCREMENT + MINIMUM_TABLE_CAD; - int cad2 = extrapRow2 * POWERTABLE_CAD_INCREMENT + MINIMUM_TABLE_CAD; - int val1 = this->tableRow[extrapRow1].tableEntry[wattIndex].targetPosition; - int val2 = this->tableRow[extrapRow2].tableEntry[wattIndex].targetPosition; - extrapolatedValue = val1 + (val2 - val1) * (cad - cad1) / (cad2 - cad1); - SS2K_LOG(ERG_MODE_LOG_TAG, "Lookup Extrapolated %d from %d, %d, for %dw %dcad", extrapolatedValue, val2, val1, watts, cad); - return extrapolatedValue * TABLE_DIVISOR; - } - } - - // Extrapolation for watts out of bounds - if (watts > (POWERTABLE_WATT_SIZE - 1) * POWERTABLE_WATT_INCREMENT) { - int extrapCol1 = -1, extrapCol2 = -1; - for (int j = POWERTABLE_WATT_SIZE - 1; j >= 0; j--) { - if (this->tableRow[cadIndex].tableEntry[j].targetPosition != INT16_MIN) { - if (extrapCol2 == -1) { - extrapCol2 = j; - } else { - extrapCol1 = j; - break; - } - } - } - if (extrapCol1 != -1 && extrapCol2 != -1) { - int watts1 = extrapCol1 * POWERTABLE_WATT_INCREMENT; - int watts2 = extrapCol2 * POWERTABLE_WATT_INCREMENT; - int val1 = this->tableRow[cadIndex].tableEntry[extrapCol1].targetPosition; - int val2 = this->tableRow[cadIndex].tableEntry[extrapCol2].targetPosition; - extrapolatedValue = val1 + (val2 - val1) * (watts - watts1) / (watts2 - watts1); - SS2K_LOG(ERG_MODE_LOG_TAG, "Lookup Extrapolated %d from %d, %d, for %dw %dcad", extrapolatedValue, val2, val1, watts, cad); - return extrapolatedValue * TABLE_DIVISOR; - } - } - // Not enough data. - return INT32_MIN; - } - - // Edge cases out of the way, we should be able to interpolate. - TestResults neighbors = testNeighbors(cadIndex, wattIndex, INT16_MIN); - double x1 = neighbors.leftNeighbor.j * POWERTABLE_WATT_INCREMENT; - double x2 = neighbors.rightNeighbor.j * POWERTABLE_WATT_INCREMENT; - double y1 = neighbors.topNeighbor.i * POWERTABLE_CAD_INCREMENT + MINIMUM_TABLE_CAD; - double y2 = neighbors.bottomNeighbor.i * POWERTABLE_CAD_INCREMENT + MINIMUM_TABLE_CAD; - - double Q11 = neighbors.leftNeighbor.targetPosition; - double Q12 = neighbors.rightNeighbor.targetPosition; - double Q21 = neighbors.topNeighbor.targetPosition; - double Q22 = neighbors.bottomNeighbor.targetPosition; - - double R1 = INT16_MIN; - double R2 = INT16_MIN; - double R3 = INT16_MIN; - - SS2K_LOG(ERG_MODE_LOG_TAG, "Lookup debug %.0f X1 %.0f X2 %.0f Y1 %.0f Y2 %.0f", x1, x2, y1, y2); - - if (neighbors.leftNeighbor.found && neighbors.rightNeighbor.found) { - // Watt result - R1 = Q11 + (((watts - x1) / (x2 - x1)) * (Q12 - Q11)); - SS2K_LOG(ERG_MODE_LOG_TAG, "Lookup used neighbors L %.0f R %.0f R1 %.0f", Q11, Q12, R1); - } - if (neighbors.topNeighbor.found && neighbors.bottomNeighbor.found) { - // CAD result - R2 = Q21 + (((cad - y1) / (y2 - y1)) * (Q22 - Q21)); - SS2K_LOG(ERG_MODE_LOG_TAG, "Lookup used neighbors U %.0f D %.0f R2 %.0f", Q21, Q22, R2); - } - // Do we have a position at this entry? - if (this->tableRow[cadIndex].tableEntry[wattIndex].targetPosition != INT16_MIN) { - R3 = this->tableRow[cadIndex].tableEntry[wattIndex].targetPosition; - SS2K_LOG(ERG_MODE_LOG_TAG, "Lookup used actual %d R3 %.0f", this->tableRow[cadIndex].tableEntry[wattIndex].targetPosition, R3); - } - - int sum = 0; - int count = 0; - - if (R1 != INT16_MIN) { - sum += R1; - count++; - } - if (R2 != INT16_MIN) { - sum += R2; - count++; - } - if (R3 != INT16_MIN) { - sum += R3; - count++; - } - - if (count == 0) { - // Handle the case where all values are invalid. - return INT16_MIN; - } - - int ret = (sum / count) * TABLE_DIVISOR; - SS2K_LOG(ERG_MODE_LOG_TAG, "Lookup result: %dw %dcad %d", watts, cad, ret); - return ret; -} - -// returns class of all neighbors that are found and within expected values. -TestResults PowerTable::testNeighbors(int i, int j, int testValue) { - TestResults returnResult; - // Get the neighbors - // Check left neighbor - if (j > 0) { - for (int left = j - 1; left >= 0; --left) { - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN) { - returnResult.leftNeighbor.targetPosition = this->tableRow[i].tableEntry[left].targetPosition; - returnResult.leftNeighbor.i = i; - returnResult.leftNeighbor.j = left; - returnResult.leftNeighbor.found = 1; - break; - } - } - } - - if (returnResult.leftNeighbor.targetPosition < testValue || returnResult.leftNeighbor.targetPosition == INT16_MIN) { - returnResult.leftNeighbor.passedTest = 1; - } - - // Check right neighbor - if (j < POWERTABLE_WATT_SIZE - 1) { - for (int right = j + 1; right < POWERTABLE_WATT_SIZE; ++right) { - if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - returnResult.rightNeighbor.targetPosition = this->tableRow[i].tableEntry[right].targetPosition; - returnResult.rightNeighbor.i = i; - returnResult.rightNeighbor.j = right; - returnResult.rightNeighbor.found = 1; - break; - } - } - } - - if (returnResult.rightNeighbor.targetPosition > testValue || returnResult.rightNeighbor.targetPosition == INT16_MIN) { - returnResult.rightNeighbor.passedTest = 1; - } - - // Check top neighbor - if (i > 0) { - for (int up = i - 1; up >= 0; --up) { - if (this->tableRow[up].tableEntry[j].targetPosition != INT16_MIN) { - returnResult.topNeighbor.targetPosition = this->tableRow[up].tableEntry[j].targetPosition; - returnResult.topNeighbor.i = up; - returnResult.topNeighbor.j = j; - returnResult.topNeighbor.found = 1; - break; - } - } - } - - if (returnResult.topNeighbor.targetPosition > testValue || returnResult.topNeighbor.targetPosition == INT16_MIN) { - returnResult.topNeighbor.passedTest = 1; - } - - // Check bottom neighbor - if (i < POWERTABLE_CAD_SIZE - 1) { - for (int down = i + 1; down < POWERTABLE_CAD_SIZE; ++down) { - if (this->tableRow[down].tableEntry[j].targetPosition != INT16_MIN) { - returnResult.bottomNeighbor.targetPosition = this->tableRow[down].tableEntry[j].targetPosition; - returnResult.bottomNeighbor.i = down; - returnResult.bottomNeighbor.j = j; - returnResult.bottomNeighbor.found = 1; - break; - } - } - } - - if (returnResult.bottomNeighbor.targetPosition < testValue || returnResult.bottomNeighbor.targetPosition == INT16_MIN) { - returnResult.bottomNeighbor.passedTest = 1; - } - - if (returnResult.bottomNeighbor.found && returnResult.topNeighbor.found && returnResult.rightNeighbor.found && returnResult.leftNeighbor.found) { - returnResult.allNeighborsFound = 1; - } - if (returnResult.bottomNeighbor.passedTest && returnResult.topNeighbor.passedTest && returnResult.rightNeighbor.passedTest && returnResult.leftNeighbor.passedTest) { - returnResult.allNeighborsPassed = 1; - } - return returnResult; -} - -void PowerTable::fillTable() { - int tempValue = INT16_MIN; - - // Fill each empty cell by linear interpolation - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - // Interpolate horizontally - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest left and right non-empty cells - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear interpolation - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) * (j - left) / (right - left); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } - } - - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - // Interpolate vertically - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top and bottom non-empty cells - int top = i - 1; - while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; - int bottom = i + 1; - while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; - - if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { - // Linear interpolation - tempValue = this->tableRow[top].tableEntry[j].targetPosition + - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) * (i - top) / (bottom - top); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } - } -} - -void PowerTable::extrapFillTable() { - // Find the center of the known data - int sumRow = 0, sumCol = 0, count = 0; - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - sumRow += i; - sumCol += j; - count++; - } - } - } - - // prevent divide by zero - if (count == 0) { - return; - } - - int centerRow = sumRow / count; - int centerCol = sumCol / count; - int tempValue = INT16_MIN; - - // Function to extrapolate a single cell based on its neighbors - auto extrapolateCell = [&](int i, int j) { - // Find nearest left non-empty cell - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - - // Find nearest right non-empty cell - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear extrapolation - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - if (j < left) { - // Extrapolate to the left - tempValue = this->tableRow[i].tableEntry[left].targetPosition - - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } else if (j > right) { - // Extrapolate to the right - tempValue = this->tableRow[i].tableEntry[right].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } else if (left - 1 >= 0) { - // Only left value available, extrapolate to the right - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (right + 1 < POWERTABLE_WATT_SIZE) { - // Only right value available, extrapolate to the left - if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - tempValue = - this->tableRow[i].tableEntry[right].targetPosition - - (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - }; - - // Extrapolate horizontally and vertically starting from the center - for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { - for (int i = centerRow - distance; i <= centerRow + distance; ++i) { - for (int j = centerCol - distance; j <= centerCol + distance; ++j) { - if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - extrapolateCell(i, j); - } - } - } - } - // Extrapolate each empty cell - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - // Extrapolate horizontally - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest left non-empty cell - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - - // Find nearest right non-empty cell - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear extrapolation - if (j < left) { - // Extrapolate to the left - tempValue = this->tableRow[i].tableEntry[left].targetPosition - - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - - } else if (j > right) { - // Extrapolate to the right - tempValue = this->tableRow[i].tableEntry[right].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (left >= 1) { - // Only left value available, extrapolate to the right - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (right + 1 < POWERTABLE_WATT_SIZE) { - // Only right value available, extrapolate to the left - if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[right].targetPosition - - (right - j) * - (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } - } - } - } - - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - // Extrapolate vertically - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top non-empty cell - int top = i - 1; - while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; - - // Find nearest bottom non-empty cell - int bottom = i + 1; - while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; - - if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { - // Linear extrapolation - if (i < top) { - // Extrapolate upwards - tempValue = this->tableRow[top].tableEntry[j].targetPosition - - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } else if (i > bottom) { - // Extrapolate downwards - tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (top >= 1) { - // Only top value available, extrapolate downwards - if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { - tempValue = this->tableRow[top].tableEntry[j].targetPosition + - (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } else { - } - } - } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { - // Only bottom value available, extrapolate upwards - if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { - tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - - (bottom - i) * - (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } - } - } -} - -void PowerTable::extrapolateDiagonal() { - int tempValue = INT16_MIN; - - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top-left non-empty cell - int topLeftRow = i - 1, topLeftCol = j - 1; - while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { - topLeftRow--; - topLeftCol--; - } - - // Find nearest bottom-right non-empty cell - int bottomRightRow = i + 1, bottomRightCol = j + 1; - while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && - this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { - bottomRightRow++; - bottomRightCol++; - } - - // Perform diagonal extrapolation (top-left to bottom-right) - if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { - tempValue = - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + - ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / - (bottomRightCol - topLeftCol); - - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - - // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left - if (tempValue == INT16_MIN) { - // Find nearest top-right non-empty cell - int topRightRow = i - 1, topRightCol = j + 1; - while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { - topRightRow--; - topRightCol++; - } - - // Find nearest bottom-left non-empty cell - int bottomLeftRow = i + 1, bottomLeftCol = j - 1; - while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { - bottomLeftRow++; - bottomLeftCol--; - } - - // Perform diagonal extrapolation (top-right to bottom-left) - if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { - tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + - ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * - (j - bottomLeftCol)) / - (topRightCol - bottomLeftCol); - - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } - } - } -} - -int PowerTable::getNumEntries() { - int ret = 0; - for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - ret++; - } - } - } - return ret; -} - -void PowerTable::clean() { - int ret = 0; - for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - if (this->tableRow[i].tableEntry[j].readings < 1) { - this->tableRow[i].tableEntry[j].targetPosition = INT16_MIN; - } - } - } -} - -// function for weighted downvoting -int downVote(int targetValue, int neighborValue) { - // calculate diff between target and neighbor - int delta = abs(targetValue - neighborValue); - float penalty; - float penaltyFactor = 0.2; - - // currently consistently getting a 0 for neighbor value... - SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Target Value: (%d), NeighborValue: (%f)", targetValue, neighborValue); - - // we have a few different options for penalty calculations here, will need to test which works best: - - // linear function, low agression - penalty = delta * penaltyFactor; - - // quadratic function, high aggression - // penalty = penaltyFactor * (delta * delta) - - // log function, medium aggression - // penalty = penaltyFactor * log(delta + 1); - - // max penalty is 10 - if (penalty > MAX_NEIGHBOR_WEIGHT) { - penalty = MAX_NEIGHBOR_WEIGHT; - } - - // round up penalty to make it an int - penalty = round(penalty); - - SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Delta: (%d), Penalty: (%f)", delta, penalty); - return penalty; -} - -void PowerTable::newEntry(PowerBuffer& powerBuffer) { - // these are floats so that we make sure division works correctly. - float watts = 0; - float cad = 0; - float targetPosition = 0; - - // First, take the power buffer and average all of the samples together. - int validEntries = 0; - for (int i = 0; i < POWER_SAMPLES; i++) { - if (powerBuffer.powerEntry[i].readings == 0) { - // Stop when buffer is empty - break; - } - - // Accumulate values - watts += powerBuffer.powerEntry[i].watts; - cad += powerBuffer.powerEntry[i].cad; - targetPosition += powerBuffer.powerEntry[i].targetPosition; - validEntries++; - } - - // Calculate the average if there are valid entries - if (validEntries > 0) { - watts /= validEntries; - cad /= validEntries; - targetPosition /= validEntries; - } else { - SS2K_LOG(POWERTABLE_LOG_TAG, "No valid entries in the power buffer."); - return; - } - - // clean previously extrapolated data so we don't fill with trash. - this->clean(); - // To start working on the PowerTable, we need to calculate position in the table for the new entry - int i = round(watts / (float)POWERTABLE_WATT_INCREMENT); - int k = round((cad - (float)MINIMUM_TABLE_CAD) / (float)POWERTABLE_CAD_INCREMENT); - SS2K_LOG(POWERTABLE_LOG_TAG, "Averaged Entry: watts=%f, cad=%f, targetPosition=%f, (%d)(%d)", watts, cad, targetPosition, k, i); - - // Ensure k is within valid range - if ((k < 0) || (k > (POWERTABLE_CAD_SIZE - 1))) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Cad index was out of range %d", k); - return; - } - // Ensure i is within valid range - if (i < 0 || i > (POWERTABLE_WATT_SIZE - 1)) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Watt index was out of range %d max %d", i, POWERTABLE_WATT_SIZE - 1); - return; - } - - // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table - TestResults testResults = this->testNeighbors(k, i, targetPosition); - if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { - // test which bit fields didn't match - if (!testResults.leftNeighbor.passedTest) { - if (testResults.leftNeighbor.i == k && - (testResults.leftNeighbor.targetPosition <= targetPosition + 30 && - testResults.leftNeighbor.targetPosition >= targetPosition)) { // check if the cadence is the same and positions are within a set range in this case its 30. - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and targetPosition is within range"); - - int avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - - if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) { // check if the current position moved left is valid - SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %f", targetPosition); - this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); // enter the data - } - - if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { // checks if the avg position with the current watts and cadence is valid - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - this->enterData(k, i, avgPosition); // enter the data - } - - if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition) - .allNeighborsPassed) { // checks if the failed nighbor is valid with the right neighbors cadence and watts - SS2K_LOG(POWERTABLE_LOG_TAG, "Left Neighbors position was valid with Right Neighbors cadence and watts! Left Neighbor Position: %d", - testResults.leftNeighbor.targetPosition); - this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition); - } - return; - } else { // if not we still get rid of the reading - // determine penalty amount before applying to failed neighbor - int penalty = downVote(targetPosition, testResults.leftNeighbor.targetPosition); - // make sure downvotes isn't at max - if (this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; - penalty = 0; - } - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings -= penalty; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%f), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); - } - } - - if (!testResults.rightNeighbor.passedTest) { - if (testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition - 30 && testResults.rightNeighbor.targetPosition <= targetPosition)) { - int avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - - if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved right was valid! Current position: %f", targetPosition); - this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); - } - - if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - this->enterData(k, i, avgPosition); - } - - if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Right Neighbors position was valid with Left Neighbors cadence and watts! Right Neighbor Position: %d", - testResults.rightNeighbor.targetPosition); - this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition); - } - return; - } else { - // determine penalty amount before applying to failed neighbor - int penalty = downVote(targetPosition, testResults.rightNeighbor.targetPosition); - // make sure downvotes isn't at max - if (this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; - penalty = 0; - } - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings -= penalty; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, - testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); - } - } - - if (!testResults.topNeighbor.passedTest) { - if (testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition - 30 && testResults.topNeighbor.targetPosition <= targetPosition)) { - int avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - - if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); - this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); - } - - if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - this->enterData(k, i, avgPosition); - } - - if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Top Neighbors position was valid with Bottom Neighbors cadence and watts! Top Neighbor Position: %d", - testResults.topNeighbor.targetPosition); - this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); - } - - return; - } else { - // determine penalty amount before applying to failed neighbor - int penalty = downVote(targetPosition, testResults.topNeighbor.targetPosition); - // make sure downvotes isn't at max - if (this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; - penalty = 0; - } - - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings -= penalty; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - } - } - - if (!testResults.bottomNeighbor.passedTest) { - if (testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition + 30 && testResults.bottomNeighbor.targetPosition >= targetPosition)) { - int avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - - if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); - this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); - } - - if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - this->enterData(k, i, avgPosition); - } - - if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom Neighbors position was valid with Top Neighbors cadence and watts! Bottom Neighbor Position: %d", - testResults.topNeighbor.targetPosition); - this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition); - } - - return; - } else { - // determine penalty amount before applying to failed neighbor - int penalty = downVote(targetPosition, testResults.bottomNeighbor.targetPosition); - - // make sure downvotes isn't at max - if (this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; - penalty = 0; - } - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings -= penalty; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, - testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); - } - } - return; - } - - // Update or create a new entry - if (this->tableRow[k].tableEntry[i].readings == 0) { // if first reading in this entry - this->tableRow[k].tableEntry[i].targetPosition = targetPosition; - SS2K_LOG(POWERTABLE_LOG_TAG, "New entry recorded (%d)(%d)(%d)", k, i, this->tableRow[k].tableEntry[i].targetPosition); - } else { // Average and update the readings. - this->tableRow[k].tableEntry[i].targetPosition = - (targetPosition + (this->tableRow[k].tableEntry[i].targetPosition * this->tableRow[k].tableEntry[i].readings)) / (this->tableRow[k].tableEntry[i].readings + 1.0); - SS2K_LOG(POWERTABLE_LOG_TAG, "Existing entry averaged (%d)(%d)(%d), readings(%d)", k, i, this->tableRow[k].tableEntry[i].targetPosition, - this->tableRow[k].tableEntry[i].readings); - if (this->tableRow[k].tableEntry[i].readings > MAX_NEIGHBOR_WEIGHT) { - this->tableRow[k].tableEntry[i].readings = MAX_NEIGHBOR_WEIGHT; // keep from diluting recent readings too far. - } - } - this->tableRow[k].tableEntry[i].readings++; - - // or - // this->enterData(k, i, (int)targetPosition); - - // Attempt to fill the table with calculated data... - if (this->getNumEntries() > 4) { - int entries = 0; - int newEntries = 1; - // loop until we can't calculate any new data - while (entries < newEntries) { - entries = newEntries; - this->fillTable(); - this->extrapFillTable(); - this->extrapolateDiagonal(); - newEntries = getNumEntries(); - } - } - // Notify connected client of new data - BLE_ss2kCustomCharacteristic::notify(0x27, k); -} - -void PowerTable::enterData(int i, int j, int pos) { - if (this->tableRow[i].tableEntry[j].readings == 0) { // if first reading in this entry - this->tableRow[i].tableEntry[j].targetPosition = pos; - SS2K_LOG(POWERTABLE_LOG_TAG, "New entry recorded (%d)(%d)(%d)", i, j, this->tableRow[i].tableEntry[j].targetPosition); - } else { // Average and update the readings. - this->tableRow[i].tableEntry[j].targetPosition = - (pos + (this->tableRow[i].tableEntry[j].targetPosition * this->tableRow[i].tableEntry[j].readings)) / (this->tableRow[i].tableEntry[j].readings + 1.0); - SS2K_LOG(POWERTABLE_LOG_TAG, "Existing entry averaged (%d)(%d)(%d), readings(%d)", i, j, this->tableRow[i].tableEntry[j].targetPosition, - this->tableRow[i].tableEntry[j].readings); - if (this->tableRow[i].tableEntry[j].readings > POWER_SAMPLES * 2) { - this->tableRow[i].tableEntry[j].readings = POWER_SAMPLES * 2; // keep from diluting recent readings too far. - } - } - this->tableRow[i].tableEntry[j].readings++; -} - -bool PowerTable::_manageSaveState(bool canSkipReliabilityChecks) { - // Check if the table has been loaded in this session - if (!this->_hasBeenLoadedThisSession) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Loading Power Table...."); - File file = LittleFS.open(POWER_TABLE_FILENAME, FILE_READ); - if (!file) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Failed to Load Power Table."); - file.close(); - this->_save(); - return false; - } - - // Read version and size - int version; - file.read((uint8_t*)&version, sizeof(version)); - int savedQuality; - file.read((uint8_t*)&savedQuality, sizeof(savedQuality)); - bool savedHomed; - file.read((uint8_t*)&savedHomed, sizeof(savedHomed)); - - // If both current and saved tables were created with homing, we can skip position reliability checks - if (!canSkipReliabilityChecks) { - canSkipReliabilityChecks = savedHomed && rtConfig->getHomed(); - } - - if (version != TABLE_VERSION) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Expected power table version %d, found version %d", TABLE_VERSION, version); - file.close(); - this->_save(); - return false; - } - - // Is the data we are working with better than the saved file? - int activeReadings = this->getNumReadings(); - if (activeReadings > savedQuality) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Active table had a reliability of %d, vs %d for the saved file. Overwriting save.", activeReadings, savedQuality); - file.close(); - this->_save(); - } - - SS2K_LOG(POWERTABLE_LOG_TAG, "Loading power table version %d, Size %d, Homed %d", version, savedQuality, savedHomed); - - if (!canSkipReliabilityChecks) { - // Initialize a counter for reliable positions - int reliablePositions = 0; - - // Check if we have at least 3 reliable positions in the active table in order to determine a reliable offset to load the saved table - for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - int16_t savedTargetPosition = INT16_MIN; - int8_t savedReadings = 0; - file.read((uint8_t*)&savedTargetPosition, sizeof(savedTargetPosition)); - file.read((uint8_t*)&savedReadings, sizeof(savedReadings)); - // Does the saved file have a position that the active session has also recorded? - // We start comparing at watt position 3 (j>2) because low resistance positions are notoriously unreliable. - if ((j > 2) && (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) && (this->tableRow[i].tableEntry[j].readings > MINIMUM_RELIABLE_POSITIONS) && - (savedReadings > 0)) { - reliablePositions++; - } - } - } - if (reliablePositions < MINIMUM_RELIABLE_POSITIONS) { // Do we have enough active data in order to calculate a (good) offset when we load the new table? - SS2K_LOG(POWERTABLE_LOG_TAG, "Not enough matching positions to load the Power Table. %d of %d needed.", reliablePositions, MINIMUM_RELIABLE_POSITIONS); - file.close(); - return false; - } - } - file.close(); - - // We passed our checks to load, lets load the saved table into active memory - file = LittleFS.open(POWER_TABLE_FILENAME, FILE_READ); - if (!file) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Failed to Load Power Table. Resetting the save."); - file.close(); - this->_save(); - return false; - } - - // get these reads done, so that we're in the right position to read the data from the file. - file.read((uint8_t*)&version, sizeof(version)); - file.read((uint8_t*)&savedQuality, sizeof(savedQuality)); - file.read((uint8_t*)&savedHomed, sizeof(savedHomed)); - - float averageOffset = 0; - if (!canSkipReliabilityChecks) { - std::vector offsetDifferences; - int reliablePositions = 0; - // Read table entries and calculate offsets - for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - int16_t savedTargetPosition = INT16_MIN; - int8_t savedReadings = 0; - file.read((uint8_t*)&savedTargetPosition, sizeof(savedTargetPosition)); - file.read((uint8_t*)&savedReadings, sizeof(savedReadings)); - if ((this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) && (savedTargetPosition != INT16_MIN) && (savedReadings > 0) && - (this->tableRow[i].tableEntry[j].readings > MINIMUM_RELIABLE_POSITIONS)) { - int offset = this->tableRow[i].tableEntry[j].targetPosition - savedTargetPosition; - offsetDifferences.push_back(offset); - SS2K_LOG(POWERTABLE_LOG_TAG, "offset %d", offset); - reliablePositions++; - } - this->tableRow[i].tableEntry[j].targetPosition = savedTargetPosition; - this->tableRow[i].tableEntry[j].readings = savedReadings; - } - } - averageOffset = std::accumulate(offsetDifferences.begin(), offsetDifferences.end(), 0.0) / offsetDifferences.size(); - } else { - // If both tables were created with homing, just load the values directly - for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - int16_t savedTargetPosition = INT16_MIN; - int8_t savedReadings = 0; - file.read((uint8_t*)&savedTargetPosition, sizeof(savedTargetPosition)); - file.read((uint8_t*)&savedReadings, sizeof(savedReadings)); - this->tableRow[i].tableEntry[j].targetPosition = savedTargetPosition; - this->tableRow[i].tableEntry[j].readings = savedReadings; - } - } - SS2K_LOG(POWERTABLE_LOG_TAG, "Both tables were created with homing, loaded values directly"); - } - - file.close(); - - // Apply the offset if needed - if (!canSkipReliabilityChecks) { - for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - this->tableRow[i].tableEntry[j].targetPosition += averageOffset; - } - } - } - SS2K_LOG(POWERTABLE_LOG_TAG, "Power Table loaded with an offset of %d.", averageOffset); - } - - // set the flag so it isn't loaded again this session. - this->_hasBeenLoadedThisSession = true; - } - - // Implement saving on a timer - if ((millis() - lastSaveTime) > POWER_TABLE_SAVE_INTERVAL) { - this->_save(); - lastSaveTime = millis(); - } - return true; -} - -bool PowerTable::_save() { - // Delete existing file to avoid appending - LittleFS.remove(POWER_TABLE_FILENAME); - - // Open file for writing - SS2K_LOG(POWERTABLE_LOG_TAG, "Writing File: %s", POWER_TABLE_FILENAME); - File file = LittleFS.open(POWER_TABLE_FILENAME, FILE_WRITE); - if (!file) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Failed to create file"); - return false; - } - - // Write version and size - int version = TABLE_VERSION; - file.write((uint8_t*)&version, sizeof(version)); - - int size = getNumReadings(); - file.write((uint8_t*)&size, sizeof(size)); - - // Write homing state - bool isHomed = rtConfig->getHomed(); - file.write((uint8_t*)&isHomed, sizeof(isHomed)); - - // Write table entries - for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - file.write((uint8_t*)&this->tableRow[i].tableEntry[j].targetPosition, sizeof(this->tableRow[i].tableEntry[j].targetPosition)); - file.write((uint8_t*)&this->tableRow[i].tableEntry[j].readings, sizeof(this->tableRow[i].tableEntry[j].readings)); - } - } - - // Close the file - file.close(); - lastSaveTime = millis(); - this->_hasBeenLoadedThisSession = true; - return true; // return successful -} - -int32_t PowerTable::lookupWatts(int cad, int32_t targetPosition) { - // Convert targetPosition from external format (xTABLE_DIVISOR) to internal format - int16_t internalPosition = targetPosition / TABLE_DIVISOR; - - // Calculate cadence index - int cadIndex = round(((float)cad - (float)MINIMUM_TABLE_CAD) / (float)POWERTABLE_CAD_INCREMENT); - - // Clamp cadence index to table limits - if (cadIndex < 0) { - cadIndex = 0; - } else if (cadIndex >= POWERTABLE_CAD_SIZE) { - cadIndex = POWERTABLE_CAD_SIZE - 1; - } - - // Find closest positions and corresponding watts in the row - int leftWattIndex = -1; - int rightWattIndex = -1; - - // Search for closest positions - for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - if (this->tableRow[cadIndex].tableEntry[j].targetPosition != INT16_MIN) { - if (this->tableRow[cadIndex].tableEntry[j].targetPosition <= internalPosition) { - leftWattIndex = j; - } else { - rightWattIndex = j; - break; - } - } - } - - // If we found valid positions on both sides, interpolate - if (leftWattIndex != -1 && rightWattIndex != -1) { - int leftPos = this->tableRow[cadIndex].tableEntry[leftWattIndex].targetPosition; - int rightPos = this->tableRow[cadIndex].tableEntry[rightWattIndex].targetPosition; - int leftWatts = leftWattIndex * POWERTABLE_WATT_INCREMENT; - int rightWatts = rightWattIndex * POWERTABLE_WATT_INCREMENT; - - // Linear interpolation - int watts = leftWatts + (rightWatts - leftWatts) * (internalPosition - leftPos) / (rightPos - leftPos); - SS2K_LOG(ERG_MODE_LOG_TAG, "LookupWatts interpolated %dw from pos %d, cad %d", watts, targetPosition, cad); - return watts; - } - - // If we only found positions on one side, extrapolate - if (leftWattIndex != -1 && leftWattIndex > 0) { - // Extrapolate using two leftmost points - int pos1 = this->tableRow[cadIndex].tableEntry[leftWattIndex - 1].targetPosition; - int pos2 = this->tableRow[cadIndex].tableEntry[leftWattIndex].targetPosition; - int watts1 = (leftWattIndex - 1) * POWERTABLE_WATT_INCREMENT; - int watts2 = leftWattIndex * POWERTABLE_WATT_INCREMENT; - - int watts = watts2 + (watts2 - watts1) * (internalPosition - pos2) / (pos2 - pos1); - SS2K_LOG(ERG_MODE_LOG_TAG, "LookupWatts extrapolated high %dw from pos %d, cad %d", watts, targetPosition, cad); - return watts; - } - - if (rightWattIndex != -1 && rightWattIndex < POWERTABLE_WATT_SIZE - 1) { - // Extrapolate using two rightmost points - int pos1 = this->tableRow[cadIndex].tableEntry[rightWattIndex].targetPosition; - int pos2 = this->tableRow[cadIndex].tableEntry[rightWattIndex + 1].targetPosition; - int watts1 = rightWattIndex * POWERTABLE_WATT_INCREMENT; - int watts2 = (rightWattIndex + 1) * POWERTABLE_WATT_INCREMENT; - - int watts = watts1 + (watts1 - watts2) * (pos1 - internalPosition) / (pos1 - pos2); - SS2K_LOG(ERG_MODE_LOG_TAG, "LookupWatts extrapolated low %dw from pos %d, cad %d", watts, targetPosition, cad); - return watts; - } - SS2K_LOG(ERG_MODE_LOG_TAG, "LookupWatts failed to find a value for pos %d, cad %d", targetPosition, cad); - return RETURN_ERROR; -} - -// Reset the PowerTable to 0; -bool PowerTable::reset() { - ss2k->resetPowerTableFlag = false; - for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - this->tableRow[i].tableEntry[j].targetPosition = INT16_MIN; - this->tableRow[i].tableEntry[j].readings = 0; - } - } - File file = LittleFS.open(POWER_TABLE_FILENAME, FILE_READ); - if (!file) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Failed to Load Power Table."); - file.close(); - this->_save(); - return false; - } - file.close(); - this->_save(); - return true; -} - -void PowerTable::toLog() { - int maxLen = 4; - // Find the longest integer to dynamically size the table - for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - continue; - } - int len = snprintf(nullptr, 0, "%d", this->tableRow[i].tableEntry[j].targetPosition); - if (maxLen < len) { - maxLen = len; - } - } - } - - char buffer[maxLen + 2]; // Buffer for formatting - // Print header row - String headerRow = "CAD\\W "; - for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - snprintf(buffer, sizeof(buffer), "%*d", maxLen, j * POWERTABLE_WATT_INCREMENT); - headerRow += String(" | ") + buffer; - } - SS2K_LOG(POWERTABLE_LOG_TAG, "%s", headerRow.c_str()); - - // Print each row of the table - for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { - String logString = String(i * POWERTABLE_CAD_INCREMENT + MINIMUM_TABLE_CAD) + " rpm"; - for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - int targetPosition = this->tableRow[i].tableEntry[j].targetPosition; - if (targetPosition == INT16_MIN) { - snprintf(buffer, sizeof(buffer), "%*s", maxLen, " "); - } else { - snprintf(buffer, sizeof(buffer), "%*d", maxLen, targetPosition); - } - logString += String(" | ") + buffer; - } - SS2K_LOG(POWERTABLE_LOG_TAG, "%s", logString.c_str()); - } -} - -int PowerTable::getNumReadings() { - int ret = 0; - for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - if (this->tableRow[i].tableEntry[j].readings > 0) { - ret++; - } - } - } - return ret; -} - // compute position for resistance control mode void ErgMode::computeResistance() { static int stepChangePerResistance = userConfig->getShiftStep(); diff --git a/src/Main.cpp b/src/Main.cpp index f4728022..0e0a49c3 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -13,6 +13,7 @@ #include #include "FastAccelStepper.h" #include "ERG_Mode.h" +#include "Power_Table.h" #include "UdpAppender.h" #include "WebsocketAppender.h" #include "BLE_Custom_Characteristic.h" @@ -38,6 +39,8 @@ Boards boards; Board currentBoard; ///////////// Initialize the Config ///////////// +ErgMode* ergMode = new ErgMode; +PowerTable* powerTable = new PowerTable; SS2K *ss2k = new SS2K; userParameters *userConfig = new userParameters; RuntimeParameters *rtConfig = new RuntimeParameters; @@ -190,7 +193,7 @@ void SS2K::maintenanceLoop(void *pvParameters) { // Run What used to be in the Stepper Task. ss2k->moveStepper(); // Run what used to be in the ERG Mode Task. - powerTable->runERG(); + ergMode->runERG(); // Run what used to be in the WebClient Task. httpServer.webClientUpdate(); // If we're in ERG mode, modify shift commands to inc/dec the target watts instead. diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp new file mode 100644 index 00000000..ff65b867 --- /dev/null +++ b/src/Power_Table.cpp @@ -0,0 +1,1295 @@ +/* + * Copyright (C) 2020 Anthony Doud & Joel Baranick + * All rights reserved + * + * SPDX-License-Identifier: GPL-2.0-only + */ + +#include "Power_Table.h" +#include "SS2KLog.h" +#include "BLE_Custom_Characteristic.h" +#include +#include +#include +#include +#include +#include +#include + +void PowerBuffer::set(int i) { + this->powerEntry[i].readings++; + this->powerEntry[i].watts = rtConfig->watts.getValue(); + this->powerEntry[i].cad = rtConfig->cad.getValue(); + this->powerEntry[i].targetPosition = ss2k->getCurrentPosition() / TABLE_DIVISOR; // dividing by 10 to save memory. +} + +void PowerBuffer::reset() { + for (int i = 0; i < POWER_SAMPLES; i++) { + this->powerEntry[i].readings = 0; + this->powerEntry[i].cad = 0; + this->powerEntry[i].watts = 0; + this->powerEntry[i].targetPosition = 0; + } +} + +// return the number of entries with readings. +int PowerBuffer::getReadings() { + int ret = 0; + for (int i = 0; i < POWER_SAMPLES; i++) { + if (this->powerEntry[i].readings != 0) { + ret++; + } + } + return ret; +} + +void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, + Measurement watts) { // this basically checks the constaraints and if everything is good it adds it into the powerbuffer. no need to change + static int calcStep; // calcStep is the percentage range of the stepper motor + + if ((cadence >= (MINIMUM_TABLE_CAD - (POWERTABLE_CAD_INCREMENT / 2))) && + (cadence <= (MINIMUM_TABLE_CAD + (POWERTABLE_CAD_INCREMENT * POWERTABLE_CAD_SIZE) - (POWERTABLE_CAD_SIZE / 2))) && (watts.getValue() > 10) && // adding constraints + (watts.getValue() < (POWERTABLE_WATT_SIZE * POWERTABLE_WATT_INCREMENT))) { + if (rtConfig->getMaxStep() == DEFAULT_STEPPER_TRAVEL && rtConfig->getMinStep() == -DEFAULT_STEPPER_TRAVEL) { + int totalStep = ((rtConfig->getMaxStep() - rtConfig->getMaxStep() / 2000000)); // stepper distance is 400,000,000 so dividing it by 2,000,000 gives us 200 + calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range + } else if (rtConfig->getHomed()) { + int totalStep = (rtConfig->getMaxStep() / TABLE_DIVISOR); // maxStep should be around 22000 / TABLE_DIVISOR gives us 200ish + calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range + } + + if (powerBuffer.powerEntry[0].readings == 0) { // we need to make sure stepper position is not negative so it only takes positive resistance values + // Take Initial reading + powerBuffer.set(0); + // Check if the current stepper posistion is within a 5% range of the previous stepper position and that the current position is not negative + } + if (((ss2k->getCurrentPosition() / TABLE_DIVISOR) >= ((powerBuffer.powerEntry[0].targetPosition) - calcStep)) && + ((ss2k->getCurrentPosition() / TABLE_DIVISOR) <= ((powerBuffer.powerEntry[0].targetPosition) + calcStep))) { + for (int i = 1; i < POWER_SAMPLES; i++) { + if (powerBuffer.powerEntry[i].readings == 0) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Success!"); + powerBuffer.set(i); // Add additional readings to the buffer. + break; + } + } + if (powerBuffer.powerEntry[POWER_SAMPLES - 1].readings == 1) { // If buffer is full, create a new table entry and clear the buffer. + this->newEntry(powerBuffer); + this->toLog(); + this->_manageSaveState(); + powerBuffer.reset(); + } + } else { // Reading was outside the range - clear the buffer and start over. + powerBuffer.reset(); + } + } +} + +// Set min / max stepper position +void PowerTable::setStepperMinMax() { + int32_t _return = RETURN_ERROR; + + // if Homing was preformed, skip estimating min_max + if (rtConfig->getHomed()) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Using detected travel limits during homing"); + return; + } + + // if the FTMS device reports resistance feedback, skip estimating min_max + if (rtConfig->resistance.getValue() > 0) { + rtConfig->setMinStep(-DEFAULT_STEPPER_TRAVEL); + rtConfig->setMaxStep(DEFAULT_STEPPER_TRAVEL); + SS2K_LOG(POWERTABLE_LOG_TAG, "Using Resistance Travel Limits"); + return; + } + + int minBreakWatts = userConfig->getMinWatts(); + if (minBreakWatts > 1) { + _return = this->lookup(minBreakWatts, NORMAL_CAD); + if (_return != RETURN_ERROR) { + // never set less than one shift below current incline. + if ((_return >= ss2k->getCurrentPosition()) && (rtConfig->watts.getValue() > userConfig->getMinWatts())) { + _return = ss2k->getCurrentPosition() - userConfig->getShiftStep(); + SS2K_LOG(POWERTABLE_LOG_TAG, "Min Position too close to current incline: %d", _return); + } + // never set above max step. + if (_return >= rtConfig->getMaxStep()) { + _return = ss2k->getCurrentPosition() - userConfig->getShiftStep() * 2; + SS2K_LOG(POWERTABLE_LOG_TAG, "Min Position above max!: %d", _return); + } + rtConfig->setMinStep(_return); + SS2K_LOG(POWERTABLE_LOG_TAG, "Min Position Set: %d", _return); + } + } + + int maxBreakWatts = userConfig->getMaxWatts(); + if (maxBreakWatts > 1) { + _return = this->lookup(maxBreakWatts, NORMAL_CAD); + if (_return != RETURN_ERROR) { + // never set less than one shift above current incline. + if ((_return <= ss2k->getCurrentPosition()) && (rtConfig->watts.getValue() < userConfig->getMaxWatts())) { + _return = ss2k->getCurrentPosition() + userConfig->getShiftStep(); + SS2K_LOG(POWERTABLE_LOG_TAG, "Max Position too close to current incline: %d", _return); + } + // never set below min step. + if (_return <= rtConfig->getMinStep()) { + _return = ss2k->getCurrentPosition() + userConfig->getShiftStep() * 2; + SS2K_LOG(POWERTABLE_LOG_TAG, "Max Position below min!: %d", _return); + } + rtConfig->setMaxStep(_return); + SS2K_LOG(POWERTABLE_LOG_TAG, "Max Position Set: %d", _return); + } + } +} + +int32_t PowerTable::lookup(int watts, int cad) { + int cadIndex = round(((float)cad - (float)MINIMUM_TABLE_CAD) / (float)POWERTABLE_CAD_INCREMENT); + int wattIndex = round((float)watts / (float)POWERTABLE_WATT_INCREMENT); + + // If request is outside table limits, perform linear extrapolation + if (cad < MINIMUM_TABLE_CAD || cad > (MINIMUM_TABLE_CAD + (POWERTABLE_CAD_SIZE - 1) * POWERTABLE_CAD_INCREMENT) || + watts > (POWERTABLE_WATT_SIZE - 1) * POWERTABLE_WATT_INCREMENT) { + // Perform linear extrapolation based on existing data + int extrapolatedValue = INT16_MIN; + + // Extrapolation for cadence out of bounds + if (cad < MINIMUM_TABLE_CAD || cad > (MINIMUM_TABLE_CAD + (POWERTABLE_CAD_SIZE - 1) * POWERTABLE_CAD_INCREMENT)) { + int extrapRow1 = -1, extrapRow2 = -1; + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[wattIndex].targetPosition != INT16_MIN) { + extrapRow1 = i; + break; + } + } + for (int i = POWERTABLE_CAD_SIZE - 1; i >= 0; --i) { + if (this->tableRow[i].tableEntry[wattIndex].targetPosition != INT16_MIN) { + extrapRow2 = i; + break; + } + } + if (extrapRow1 != -1 && extrapRow2 != -1) { + int cad1 = extrapRow1 * POWERTABLE_CAD_INCREMENT + MINIMUM_TABLE_CAD; + int cad2 = extrapRow2 * POWERTABLE_CAD_INCREMENT + MINIMUM_TABLE_CAD; + int val1 = this->tableRow[extrapRow1].tableEntry[wattIndex].targetPosition; + int val2 = this->tableRow[extrapRow2].tableEntry[wattIndex].targetPosition; + extrapolatedValue = val1 + (val2 - val1) * (cad - cad1) / (cad2 - cad1); + SS2K_LOG(POWERTABLE_LOG_TAG, "Lookup Extrapolated %d from %d, %d, for %dw %dcad", extrapolatedValue, val2, val1, watts, cad); + return extrapolatedValue * TABLE_DIVISOR; + } + } + + // Extrapolation for watts out of bounds + if (watts > (POWERTABLE_WATT_SIZE - 1) * POWERTABLE_WATT_INCREMENT) { + int extrapCol1 = -1, extrapCol2 = -1; + for (int j = POWERTABLE_WATT_SIZE - 1; j >= 0; j--) { + if (this->tableRow[cadIndex].tableEntry[j].targetPosition != INT16_MIN) { + if (extrapCol2 == -1) { + extrapCol2 = j; + } else { + extrapCol1 = j; + break; + } + } + } + if (extrapCol1 != -1 && extrapCol2 != -1) { + int watts1 = extrapCol1 * POWERTABLE_WATT_INCREMENT; + int watts2 = extrapCol2 * POWERTABLE_WATT_INCREMENT; + int val1 = this->tableRow[cadIndex].tableEntry[extrapCol1].targetPosition; + int val2 = this->tableRow[cadIndex].tableEntry[extrapCol2].targetPosition; + extrapolatedValue = val1 + (val2 - val1) * (watts - watts1) / (watts2 - watts1); + SS2K_LOG(POWERTABLE_LOG_TAG, "Lookup Extrapolated %d from %d, %d, for %dw %dcad", extrapolatedValue, val2, val1, watts, cad); + return extrapolatedValue * TABLE_DIVISOR; + } + } + // Not enough data. + return INT32_MIN; + } + + // Edge cases out of the way, we should be able to interpolate. + TestResults neighbors = testNeighbors(cadIndex, wattIndex, INT16_MIN); + double x1 = neighbors.leftNeighbor.j * POWERTABLE_WATT_INCREMENT; + double x2 = neighbors.rightNeighbor.j * POWERTABLE_WATT_INCREMENT; + double y1 = neighbors.topNeighbor.i * POWERTABLE_CAD_INCREMENT + MINIMUM_TABLE_CAD; + double y2 = neighbors.bottomNeighbor.i * POWERTABLE_CAD_INCREMENT + MINIMUM_TABLE_CAD; + + double Q11 = neighbors.leftNeighbor.targetPosition; + double Q12 = neighbors.rightNeighbor.targetPosition; + double Q21 = neighbors.topNeighbor.targetPosition; + double Q22 = neighbors.bottomNeighbor.targetPosition; + + double R1 = INT16_MIN; + double R2 = INT16_MIN; + double R3 = INT16_MIN; + + SS2K_LOG(POWERTABLE_LOG_TAG, "Lookup debug %.0f X1 %.0f X2 %.0f Y1 %.0f Y2 %.0f", x1, x2, y1, y2); + + if (neighbors.leftNeighbor.found && neighbors.rightNeighbor.found) { + // Watt result + R1 = Q11 + (((watts - x1) / (x2 - x1)) * (Q12 - Q11)); + SS2K_LOG(POWERTABLE_LOG_TAG, "Lookup used neighbors L %.0f R %.0f R1 %.0f", Q11, Q12, R1); + } + if (neighbors.topNeighbor.found && neighbors.bottomNeighbor.found) { + // CAD result + R2 = Q21 + (((cad - y1) / (y2 - y1)) * (Q22 - Q21)); + SS2K_LOG(POWERTABLE_LOG_TAG, "Lookup used neighbors U %.0f D %.0f R2 %.0f", Q21, Q22, R2); + } + // Do we have a position at this entry? + if (this->tableRow[cadIndex].tableEntry[wattIndex].targetPosition != INT16_MIN) { + R3 = this->tableRow[cadIndex].tableEntry[wattIndex].targetPosition; + SS2K_LOG(POWERTABLE_LOG_TAG, "Lookup used actual %d R3 %.0f", this->tableRow[cadIndex].tableEntry[wattIndex].targetPosition, R3); + } + + int sum = 0; + int count = 0; + + if (R1 != INT16_MIN) { + sum += R1; + count++; + } + if (R2 != INT16_MIN) { + sum += R2; + count++; + } + if (R3 != INT16_MIN) { + sum += R3; + count++; + } + + if (count == 0) { + // Handle the case where all values are invalid. + return INT16_MIN; + } + + int ret = (sum / count) * TABLE_DIVISOR; + SS2K_LOG(POWERTABLE_LOG_TAG, "Lookup result: %dw %dcad %d", watts, cad, ret); + return ret; +} + +// returns class of all neighbors that are found and within expected values. +TestResults PowerTable::testNeighbors(int i, int j, int testValue) { + TestResults returnResult; + // Get the neighbors + // Check left neighbor + if (j > 0) { + for (int left = j - 1; left >= 0; --left) { + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN) { + returnResult.leftNeighbor.targetPosition = this->tableRow[i].tableEntry[left].targetPosition; + returnResult.leftNeighbor.i = i; + returnResult.leftNeighbor.j = left; + returnResult.leftNeighbor.found = 1; + break; + } + } + } + + if (returnResult.leftNeighbor.targetPosition < testValue || returnResult.leftNeighbor.targetPosition == INT16_MIN) { + returnResult.leftNeighbor.passedTest = 1; + } + + // Check right neighbor + if (j < POWERTABLE_WATT_SIZE - 1) { + for (int right = j + 1; right < POWERTABLE_WATT_SIZE; ++right) { + if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + returnResult.rightNeighbor.targetPosition = this->tableRow[i].tableEntry[right].targetPosition; + returnResult.rightNeighbor.i = i; + returnResult.rightNeighbor.j = right; + returnResult.rightNeighbor.found = 1; + break; + } + } + } + + if (returnResult.rightNeighbor.targetPosition > testValue || returnResult.rightNeighbor.targetPosition == INT16_MIN) { + returnResult.rightNeighbor.passedTest = 1; + } + + // Check top neighbor + if (i > 0) { + for (int up = i - 1; up >= 0; --up) { + if (this->tableRow[up].tableEntry[j].targetPosition != INT16_MIN) { + returnResult.topNeighbor.targetPosition = this->tableRow[up].tableEntry[j].targetPosition; + returnResult.topNeighbor.i = up; + returnResult.topNeighbor.j = j; + returnResult.topNeighbor.found = 1; + break; + } + } + } + + if (returnResult.topNeighbor.targetPosition > testValue || returnResult.topNeighbor.targetPosition == INT16_MIN) { + returnResult.topNeighbor.passedTest = 1; + } + + // Check bottom neighbor + if (i < POWERTABLE_CAD_SIZE - 1) { + for (int down = i + 1; down < POWERTABLE_CAD_SIZE; ++down) { + if (this->tableRow[down].tableEntry[j].targetPosition != INT16_MIN) { + returnResult.bottomNeighbor.targetPosition = this->tableRow[down].tableEntry[j].targetPosition; + returnResult.bottomNeighbor.i = down; + returnResult.bottomNeighbor.j = j; + returnResult.bottomNeighbor.found = 1; + break; + } + } + } + + if (returnResult.bottomNeighbor.targetPosition < testValue || returnResult.bottomNeighbor.targetPosition == INT16_MIN) { + returnResult.bottomNeighbor.passedTest = 1; + } + + if (returnResult.bottomNeighbor.found && returnResult.topNeighbor.found && returnResult.rightNeighbor.found && returnResult.leftNeighbor.found) { + returnResult.allNeighborsFound = 1; + } + if (returnResult.bottomNeighbor.passedTest && returnResult.topNeighbor.passedTest && returnResult.rightNeighbor.passedTest && returnResult.leftNeighbor.passedTest) { + returnResult.allNeighborsPassed = 1; + } + return returnResult; +} + +void PowerTable::fillTable() { + int tempValue = INT16_MIN; + + // Fill each empty cell by linear interpolation + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + // Interpolate horizontally + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest left and right non-empty cells + int left = j - 1; + while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + int right = j + 1; + while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + + if (left >= 0 && right < POWERTABLE_WATT_SIZE) { + // Linear interpolation + tempValue = this->tableRow[i].tableEntry[left].targetPosition + + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) * (j - left) / (right - left); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } + } + + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + // Interpolate vertically + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest top and bottom non-empty cells + int top = i - 1; + while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; + int bottom = i + 1; + while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; + + if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { + // Linear interpolation + tempValue = this->tableRow[top].tableEntry[j].targetPosition + + (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) * (i - top) / (bottom - top); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } + } +} + +void PowerTable::extrapFillTable() { + // Find the center of the known data + int sumRow = 0, sumCol = 0, count = 0; + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + sumRow += i; + sumCol += j; + count++; + } + } + } + + // prevent divide by zero + if (count == 0) { + return; + } + + int centerRow = sumRow / count; + int centerCol = sumCol / count; + int tempValue = INT16_MIN; + + // Function to extrapolate a single cell based on its neighbors + auto extrapolateCell = [&](int i, int j) { + // Find nearest left non-empty cell + int left = j - 1; + while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + + // Find nearest right non-empty cell + int right = j + 1; + while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + + if (left >= 0 && right < POWERTABLE_WATT_SIZE) { + // Linear extrapolation + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + if (j < left) { + // Extrapolate to the left + tempValue = this->tableRow[i].tableEntry[left].targetPosition - + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } else if (j > right) { + // Extrapolate to the right + tempValue = this->tableRow[i].tableEntry[right].targetPosition + + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } else if (left - 1 >= 0) { + // Only left value available, extrapolate to the right + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { + tempValue = this->tableRow[i].tableEntry[left].targetPosition + + (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (right + 1 < POWERTABLE_WATT_SIZE) { + // Only right value available, extrapolate to the left + if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + tempValue = + this->tableRow[i].tableEntry[right].targetPosition - + (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + }; + + // Extrapolate horizontally and vertically starting from the center + for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { + for (int i = centerRow - distance; i <= centerRow + distance; ++i) { + for (int j = centerCol - distance; j <= centerCol + distance; ++j) { + if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + extrapolateCell(i, j); + } + } + } + } + // Extrapolate each empty cell + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + // Extrapolate horizontally + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest left non-empty cell + int left = j - 1; + while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + + // Find nearest right non-empty cell + int right = j + 1; + while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + if (left >= 0 && right < POWERTABLE_WATT_SIZE) { + // Linear extrapolation + if (j < left) { + // Extrapolate to the left + tempValue = this->tableRow[i].tableEntry[left].targetPosition - + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + + } else if (j > right) { + // Extrapolate to the right + tempValue = this->tableRow[i].tableEntry[right].targetPosition + + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (left >= 1) { + // Only left value available, extrapolate to the right + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { + tempValue = this->tableRow[i].tableEntry[left].targetPosition + + (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (right + 1 < POWERTABLE_WATT_SIZE) { + // Only right value available, extrapolate to the left + if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { + tempValue = this->tableRow[i].tableEntry[right].targetPosition - + (right - j) * + (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } + } + } + } + + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + // Extrapolate vertically + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest top non-empty cell + int top = i - 1; + while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; + + // Find nearest bottom non-empty cell + int bottom = i + 1; + while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; + + if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { + // Linear extrapolation + if (i < top) { + // Extrapolate upwards + tempValue = this->tableRow[top].tableEntry[j].targetPosition - + (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } else if (i > bottom) { + // Extrapolate downwards + tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + + (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (top >= 1) { + // Only top value available, extrapolate downwards + if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { + tempValue = this->tableRow[top].tableEntry[j].targetPosition + + (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } else { + } + } + } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { + // Only bottom value available, extrapolate upwards + if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { + tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - + (bottom - i) * + (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } + } + } +} + +void PowerTable::extrapolateDiagonal() { + int tempValue = INT16_MIN; + + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest top-left non-empty cell + int topLeftRow = i - 1, topLeftCol = j - 1; + while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { + topLeftRow--; + topLeftCol--; + } + + // Find nearest bottom-right non-empty cell + int bottomRightRow = i + 1, bottomRightCol = j + 1; + while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && + this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { + bottomRightRow++; + bottomRightCol++; + } + + // Perform diagonal extrapolation (top-left to bottom-right) + if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { + tempValue = + this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + + ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / + (bottomRightCol - topLeftCol); + + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + + // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left + if (tempValue == INT16_MIN) { + // Find nearest top-right non-empty cell + int topRightRow = i - 1, topRightCol = j + 1; + while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { + topRightRow--; + topRightCol++; + } + + // Find nearest bottom-left non-empty cell + int bottomLeftRow = i + 1, bottomLeftCol = j - 1; + while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { + bottomLeftRow++; + bottomLeftCol--; + } + + // Perform diagonal extrapolation (top-right to bottom-left) + if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { + tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + + ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * + (j - bottomLeftCol)) / + (topRightCol - bottomLeftCol); + + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } + } + } +} + +int PowerTable::getNumEntries() { + int ret = 0; + for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + ret++; + } + } + } + return ret; +} + +void PowerTable::clean() { + int ret = 0; + for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + if (this->tableRow[i].tableEntry[j].readings < 1) { + this->tableRow[i].tableEntry[j].targetPosition = INT16_MIN; + } + } + } +} + +// function for weighted downvoting +int downVote(int targetValue, int neighborValue) { + // calculate diff between target and neighbor + int delta = abs(targetValue - neighborValue); + float penalty; + float penaltyFactor = 0.2; + + // currently consistently getting a 0 for neighbor value... + SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Target Value: (%d), NeighborValue: (%f)", targetValue, neighborValue); + + // we have a few different options for penalty calculations here, will need to test which works best: + + // linear function, low agression + penalty = delta * penaltyFactor; + + // quadratic function, high aggression + // penalty = penaltyFactor * (delta * delta) + + // log function, medium aggression + // penalty = penaltyFactor * log(delta + 1); + + // max penalty is 10 + if (penalty > MAX_NEIGHBOR_WEIGHT) { + penalty = MAX_NEIGHBOR_WEIGHT; + } + + // round up penalty to make it an int + penalty = round(penalty); + + SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Delta: (%d), Penalty: (%f)", delta, penalty); + return penalty; +} + +void PowerTable::newEntry(PowerBuffer& powerBuffer) { + // these are floats so that we make sure division works correctly. + float watts = 0; + float cad = 0; + float targetPosition = 0; + + // First, take the power buffer and average all of the samples together. + int validEntries = 0; + for (int i = 0; i < POWER_SAMPLES; i++) { + if (powerBuffer.powerEntry[i].readings == 0) { + // Stop when buffer is empty + break; + } + + // Accumulate values + watts += powerBuffer.powerEntry[i].watts; + cad += powerBuffer.powerEntry[i].cad; + targetPosition += powerBuffer.powerEntry[i].targetPosition; + validEntries++; + } + + // Calculate the average if there are valid entries + if (validEntries > 0) { + watts /= validEntries; + cad /= validEntries; + targetPosition /= validEntries; + } else { + SS2K_LOG(POWERTABLE_LOG_TAG, "No valid entries in the power buffer."); + return; + } + + // clean previously extrapolated data so we don't fill with trash. + this->clean(); + // To start working on the PowerTable, we need to calculate position in the table for the new entry + int i = round(watts / (float)POWERTABLE_WATT_INCREMENT); + int k = round((cad - (float)MINIMUM_TABLE_CAD) / (float)POWERTABLE_CAD_INCREMENT); + SS2K_LOG(POWERTABLE_LOG_TAG, "Averaged Entry: watts=%f, cad=%f, targetPosition=%f, (%d)(%d)", watts, cad, targetPosition, k, i); + + // Ensure k is within valid range + if ((k < 0) || (k > (POWERTABLE_CAD_SIZE - 1))) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Cad index was out of range %d", k); + return; + } + // Ensure i is within valid range + if (i < 0 || i > (POWERTABLE_WATT_SIZE - 1)) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Watt index was out of range %d max %d", i, POWERTABLE_WATT_SIZE - 1); + return; + } + + // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table + TestResults testResults = this->testNeighbors(k, i, targetPosition); + if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { + // test which bit fields didn't match + if (!testResults.leftNeighbor.passedTest) { + if (testResults.leftNeighbor.i == k && + (testResults.leftNeighbor.targetPosition <= targetPosition + 30 && + testResults.leftNeighbor.targetPosition >= targetPosition)) { // check if the cadence is the same and positions are within a set range in this case its 30. + SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and targetPosition is within range"); + + int avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); + + if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) { // check if the current position moved left is valid + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %f", targetPosition); + this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); // enter the data + } + + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { // checks if the avg position with the current watts and cadence is valid + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); + this->enterData(k, i, avgPosition); // enter the data + } + + if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition) + .allNeighborsPassed) { // checks if the failed nighbor is valid with the right neighbors cadence and watts + SS2K_LOG(POWERTABLE_LOG_TAG, "Left Neighbors position was valid with Right Neighbors cadence and watts! Left Neighbor Position: %d", + testResults.leftNeighbor.targetPosition); + this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition); + } + return; + } else { // if not we still get rid of the reading + // determine penalty amount before applying to failed neighbor + int penalty = downVote(targetPosition, testResults.leftNeighbor.targetPosition); + // make sure downvotes isn't at max + if (this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; + penalty = 0; + } + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings -= penalty; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%f), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + } + } + + if (!testResults.rightNeighbor.passedTest) { + if (testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition - 30 && testResults.rightNeighbor.targetPosition <= targetPosition)) { + int avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); + + if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved right was valid! Current position: %f", targetPosition); + this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); + } + + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); + this->enterData(k, i, avgPosition); + } + + if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Right Neighbors position was valid with Left Neighbors cadence and watts! Right Neighbor Position: %d", + testResults.rightNeighbor.targetPosition); + this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition); + } + return; + } else { + // determine penalty amount before applying to failed neighbor + int penalty = downVote(targetPosition, testResults.rightNeighbor.targetPosition); + // make sure downvotes isn't at max + if (this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; + penalty = 0; + } + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings -= penalty; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, + testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + } + } + + if (!testResults.topNeighbor.passedTest) { + if (testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition - 30 && testResults.topNeighbor.targetPosition <= targetPosition)) { + int avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); + + if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); + this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); + } + + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); + this->enterData(k, i, avgPosition); + } + + if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Top Neighbors position was valid with Bottom Neighbors cadence and watts! Top Neighbor Position: %d", + testResults.topNeighbor.targetPosition); + this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); + } + + return; + } else { + // determine penalty amount before applying to failed neighbor + int penalty = downVote(targetPosition, testResults.topNeighbor.targetPosition); + // make sure downvotes isn't at max + if (this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; + penalty = 0; + } + + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings -= penalty; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + } + } + + if (!testResults.bottomNeighbor.passedTest) { + if (testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition + 30 && testResults.bottomNeighbor.targetPosition >= targetPosition)) { + int avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); + + if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); + this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); + } + + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); + this->enterData(k, i, avgPosition); + } + + if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom Neighbors position was valid with Top Neighbors cadence and watts! Bottom Neighbor Position: %d", + testResults.topNeighbor.targetPosition); + this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition); + } + + return; + } else { + // determine penalty amount before applying to failed neighbor + int penalty = downVote(targetPosition, testResults.bottomNeighbor.targetPosition); + + // make sure downvotes isn't at max + if (this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; + penalty = 0; + } + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings -= penalty; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, + testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + } + } + return; + } + + // Update or create a new entry + if (this->tableRow[k].tableEntry[i].readings == 0) { // if first reading in this entry + this->tableRow[k].tableEntry[i].targetPosition = targetPosition; + SS2K_LOG(POWERTABLE_LOG_TAG, "New entry recorded (%d)(%d)(%d)", k, i, this->tableRow[k].tableEntry[i].targetPosition); + } else { // Average and update the readings. + this->tableRow[k].tableEntry[i].targetPosition = + (targetPosition + (this->tableRow[k].tableEntry[i].targetPosition * this->tableRow[k].tableEntry[i].readings)) / (this->tableRow[k].tableEntry[i].readings + 1.0); + SS2K_LOG(POWERTABLE_LOG_TAG, "Existing entry averaged (%d)(%d)(%d), readings(%d)", k, i, this->tableRow[k].tableEntry[i].targetPosition, + this->tableRow[k].tableEntry[i].readings); + if (this->tableRow[k].tableEntry[i].readings > MAX_NEIGHBOR_WEIGHT) { + this->tableRow[k].tableEntry[i].readings = MAX_NEIGHBOR_WEIGHT; // keep from diluting recent readings too far. + } + } + this->tableRow[k].tableEntry[i].readings++; + + // or + // this->enterData(k, i, (int)targetPosition); + + // Attempt to fill the table with calculated data... + if (this->getNumEntries() > 4) { + int entries = 0; + int newEntries = 1; + // loop until we can't calculate any new data + while (entries < newEntries) { + entries = newEntries; + this->fillTable(); + this->extrapFillTable(); + this->extrapolateDiagonal(); + newEntries = getNumEntries(); + } + } + // Notify connected client of new data + BLE_ss2kCustomCharacteristic::notify(0x27, k); +} + +void PowerTable::enterData(int i, int j, int pos) { + if (this->tableRow[i].tableEntry[j].readings == 0) { // if first reading in this entry + this->tableRow[i].tableEntry[j].targetPosition = pos; + SS2K_LOG(POWERTABLE_LOG_TAG, "New entry recorded (%d)(%d)(%d)", i, j, this->tableRow[i].tableEntry[j].targetPosition); + } else { // Average and update the readings. + this->tableRow[i].tableEntry[j].targetPosition = + (pos + (this->tableRow[i].tableEntry[j].targetPosition * this->tableRow[i].tableEntry[j].readings)) / (this->tableRow[i].tableEntry[j].readings + 1.0); + SS2K_LOG(POWERTABLE_LOG_TAG, "Existing entry averaged (%d)(%d)(%d), readings(%d)", i, j, this->tableRow[i].tableEntry[j].targetPosition, + this->tableRow[i].tableEntry[j].readings); + if (this->tableRow[i].tableEntry[j].readings > POWER_SAMPLES * 2) { + this->tableRow[i].tableEntry[j].readings = POWER_SAMPLES * 2; // keep from diluting recent readings too far. + } + } + this->tableRow[i].tableEntry[j].readings++; +} + +bool PowerTable::_manageSaveState(bool canSkipReliabilityChecks) { + // Check if the table has been loaded in this session + if (!this->_hasBeenLoadedThisSession) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Loading Power Table...."); + File file = LittleFS.open(POWER_TABLE_FILENAME, FILE_READ); + if (!file) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Failed to Load Power Table."); + file.close(); + this->_save(); + return false; + } + + // Read version and size + int version; + file.read((uint8_t*)&version, sizeof(version)); + int savedQuality; + file.read((uint8_t*)&savedQuality, sizeof(savedQuality)); + bool savedHomed; + file.read((uint8_t*)&savedHomed, sizeof(savedHomed)); + + // If both current and saved tables were created with homing, we can skip position reliability checks + if (!canSkipReliabilityChecks) { + canSkipReliabilityChecks = savedHomed && rtConfig->getHomed(); + } + + if (version != TABLE_VERSION) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Expected power table version %d, found version %d", TABLE_VERSION, version); + file.close(); + this->_save(); + return false; + } + + // Is the data we are working with better than the saved file? + int activeReadings = this->getNumReadings(); + if (activeReadings > savedQuality) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Active table had a reliability of %d, vs %d for the saved file. Overwriting save.", activeReadings, savedQuality); + file.close(); + this->_save(); + } + + SS2K_LOG(POWERTABLE_LOG_TAG, "Loading power table version %d, Size %d, Homed %d", version, savedQuality, savedHomed); + + if (!canSkipReliabilityChecks) { + // Initialize a counter for reliable positions + int reliablePositions = 0; + + // Check if we have at least 3 reliable positions in the active table in order to determine a reliable offset to load the saved table + for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + int16_t savedTargetPosition = INT16_MIN; + int8_t savedReadings = 0; + file.read((uint8_t*)&savedTargetPosition, sizeof(savedTargetPosition)); + file.read((uint8_t*)&savedReadings, sizeof(savedReadings)); + // Does the saved file have a position that the active session has also recorded? + // We start comparing at watt position 3 (j>2) because low resistance positions are notoriously unreliable. + if ((j > 2) && (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) && (this->tableRow[i].tableEntry[j].readings > MINIMUM_RELIABLE_POSITIONS) && + (savedReadings > 0)) { + reliablePositions++; + } + } + } + if (reliablePositions < MINIMUM_RELIABLE_POSITIONS) { // Do we have enough active data in order to calculate a (good) offset when we load the new table? + SS2K_LOG(POWERTABLE_LOG_TAG, "Not enough matching positions to load the Power Table. %d of %d needed.", reliablePositions, MINIMUM_RELIABLE_POSITIONS); + file.close(); + return false; + } + } + file.close(); + + // We passed our checks to load, lets load the saved table into active memory + file = LittleFS.open(POWER_TABLE_FILENAME, FILE_READ); + if (!file) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Failed to Load Power Table. Resetting the save."); + file.close(); + this->_save(); + return false; + } + + // get these reads done, so that we're in the right position to read the data from the file. + file.read((uint8_t*)&version, sizeof(version)); + file.read((uint8_t*)&savedQuality, sizeof(savedQuality)); + file.read((uint8_t*)&savedHomed, sizeof(savedHomed)); + + float averageOffset = 0; + if (!canSkipReliabilityChecks) { + std::vector offsetDifferences; + int reliablePositions = 0; + // Read table entries and calculate offsets + for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + int16_t savedTargetPosition = INT16_MIN; + int8_t savedReadings = 0; + file.read((uint8_t*)&savedTargetPosition, sizeof(savedTargetPosition)); + file.read((uint8_t*)&savedReadings, sizeof(savedReadings)); + if ((this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) && (savedTargetPosition != INT16_MIN) && (savedReadings > 0) && + (this->tableRow[i].tableEntry[j].readings > MINIMUM_RELIABLE_POSITIONS)) { + int offset = this->tableRow[i].tableEntry[j].targetPosition - savedTargetPosition; + offsetDifferences.push_back(offset); + SS2K_LOG(POWERTABLE_LOG_TAG, "offset %d", offset); + reliablePositions++; + } + this->tableRow[i].tableEntry[j].targetPosition = savedTargetPosition; + this->tableRow[i].tableEntry[j].readings = savedReadings; + } + } + averageOffset = std::accumulate(offsetDifferences.begin(), offsetDifferences.end(), 0.0) / offsetDifferences.size(); + } else { + // If both tables were created with homing, just load the values directly + for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + int16_t savedTargetPosition = INT16_MIN; + int8_t savedReadings = 0; + file.read((uint8_t*)&savedTargetPosition, sizeof(savedTargetPosition)); + file.read((uint8_t*)&savedReadings, sizeof(savedReadings)); + this->tableRow[i].tableEntry[j].targetPosition = savedTargetPosition; + this->tableRow[i].tableEntry[j].readings = savedReadings; + } + } + SS2K_LOG(POWERTABLE_LOG_TAG, "Both tables were created with homing, loaded values directly"); + } + + file.close(); + + // Apply the offset if needed + if (!canSkipReliabilityChecks) { + for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + this->tableRow[i].tableEntry[j].targetPosition += averageOffset; + } + } + } + SS2K_LOG(POWERTABLE_LOG_TAG, "Power Table loaded with an offset of %d.", averageOffset); + } + + // set the flag so it isn't loaded again this session. + this->_hasBeenLoadedThisSession = true; + } + + // Implement saving on a timer + if ((millis() - lastSaveTime) > POWER_TABLE_SAVE_INTERVAL) { + this->_save(); + lastSaveTime = millis(); + } + return true; +} + +bool PowerTable::_save() { + // Delete existing file to avoid appending + LittleFS.remove(POWER_TABLE_FILENAME); + + // Open file for writing + SS2K_LOG(POWERTABLE_LOG_TAG, "Writing File: %s", POWER_TABLE_FILENAME); + File file = LittleFS.open(POWER_TABLE_FILENAME, FILE_WRITE); + if (!file) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Failed to create file"); + return false; + } + + // Write version and size + int version = TABLE_VERSION; + file.write((uint8_t*)&version, sizeof(version)); + + int size = getNumReadings(); + file.write((uint8_t*)&size, sizeof(size)); + + // Write homing state + bool isHomed = rtConfig->getHomed(); + file.write((uint8_t*)&isHomed, sizeof(isHomed)); + + // Write table entries + for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + file.write((uint8_t*)&this->tableRow[i].tableEntry[j].targetPosition, sizeof(this->tableRow[i].tableEntry[j].targetPosition)); + file.write((uint8_t*)&this->tableRow[i].tableEntry[j].readings, sizeof(this->tableRow[i].tableEntry[j].readings)); + } + } + + // Close the file + file.close(); + lastSaveTime = millis(); + this->_hasBeenLoadedThisSession = true; + return true; // return successful +} + +int32_t PowerTable::lookupWatts(int cad, int32_t targetPosition) { + // Convert targetPosition from external format (xTABLE_DIVISOR) to internal format + int16_t internalPosition = targetPosition / TABLE_DIVISOR; + + // Calculate cadence index + int cadIndex = round(((float)cad - (float)MINIMUM_TABLE_CAD) / (float)POWERTABLE_CAD_INCREMENT); + + // Clamp cadence index to table limits + if (cadIndex < 0) { + cadIndex = 0; + } else if (cadIndex >= POWERTABLE_CAD_SIZE) { + cadIndex = POWERTABLE_CAD_SIZE - 1; + } + + // Find closest positions and corresponding watts in the row + int leftWattIndex = -1; + int rightWattIndex = -1; + + // Search for closest positions + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + if (this->tableRow[cadIndex].tableEntry[j].targetPosition != INT16_MIN) { + if (this->tableRow[cadIndex].tableEntry[j].targetPosition <= internalPosition) { + leftWattIndex = j; + } else { + rightWattIndex = j; + break; + } + } + } + + // If we found valid positions on both sides, interpolate + if (leftWattIndex != -1 && rightWattIndex != -1) { + int leftPos = this->tableRow[cadIndex].tableEntry[leftWattIndex].targetPosition; + int rightPos = this->tableRow[cadIndex].tableEntry[rightWattIndex].targetPosition; + int leftWatts = leftWattIndex * POWERTABLE_WATT_INCREMENT; + int rightWatts = rightWattIndex * POWERTABLE_WATT_INCREMENT; + + // Linear interpolation + int watts = leftWatts + (rightWatts - leftWatts) * (internalPosition - leftPos) / (rightPos - leftPos); + SS2K_LOG(POWERTABLE_LOG_TAG, "LookupWatts interpolated %dw from pos %d, cad %d", watts, targetPosition, cad); + return watts; + } + + // If we only found positions on one side, extrapolate + if (leftWattIndex != -1 && leftWattIndex > 0) { + // Extrapolate using two leftmost points + int pos1 = this->tableRow[cadIndex].tableEntry[leftWattIndex - 1].targetPosition; + int pos2 = this->tableRow[cadIndex].tableEntry[leftWattIndex].targetPosition; + int watts1 = (leftWattIndex - 1) * POWERTABLE_WATT_INCREMENT; + int watts2 = leftWattIndex * POWERTABLE_WATT_INCREMENT; + + int watts = watts2 + (watts2 - watts1) * (internalPosition - pos2) / (pos2 - pos1); + SS2K_LOG(POWERTABLE_LOG_TAG, "LookupWatts extrapolated high %dw from pos %d, cad %d", watts, targetPosition, cad); + return watts; + } + + if (rightWattIndex != -1 && rightWattIndex < POWERTABLE_WATT_SIZE - 1) { + // Extrapolate using two rightmost points + int pos1 = this->tableRow[cadIndex].tableEntry[rightWattIndex].targetPosition; + int pos2 = this->tableRow[cadIndex].tableEntry[rightWattIndex + 1].targetPosition; + int watts1 = rightWattIndex * POWERTABLE_WATT_INCREMENT; + int watts2 = (rightWattIndex + 1) * POWERTABLE_WATT_INCREMENT; + + int watts = watts1 + (watts1 - watts2) * (pos1 - internalPosition) / (pos1 - pos2); + SS2K_LOG(POWERTABLE_LOG_TAG, "LookupWatts extrapolated low %dw from pos %d, cad %d", watts, targetPosition, cad); + return watts; + } + SS2K_LOG(POWERTABLE_LOG_TAG, "LookupWatts failed to find a value for pos %d, cad %d", targetPosition, cad); + return RETURN_ERROR; +} + +// Reset the PowerTable to 0; +bool PowerTable::reset() { + ss2k->resetPowerTableFlag = false; + for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + this->tableRow[i].tableEntry[j].targetPosition = INT16_MIN; + this->tableRow[i].tableEntry[j].readings = 0; + } + } + File file = LittleFS.open(POWER_TABLE_FILENAME, FILE_READ); + if (!file) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Failed to Load Power Table."); + file.close(); + this->_save(); + return false; + } + file.close(); + this->_save(); + return true; +} + +void PowerTable::toLog() { + int maxLen = 4; + // Find the longest integer to dynamically size the table + for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + continue; + } + int len = snprintf(nullptr, 0, "%d", this->tableRow[i].tableEntry[j].targetPosition); + if (maxLen < len) { + maxLen = len; + } + } + } + + char buffer[maxLen + 2]; // Buffer for formatting + // Print header row + String headerRow = "CAD\\W "; + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + snprintf(buffer, sizeof(buffer), "%*d", maxLen, j * POWERTABLE_WATT_INCREMENT); + headerRow += String(" | ") + buffer; + } + SS2K_LOG(POWERTABLE_LOG_TAG, "%s", headerRow.c_str()); + + // Print each row of the table + for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { + String logString = String(i * POWERTABLE_CAD_INCREMENT + MINIMUM_TABLE_CAD) + " rpm"; + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + int targetPosition = this->tableRow[i].tableEntry[j].targetPosition; + if (targetPosition == INT16_MIN) { + snprintf(buffer, sizeof(buffer), "%*s", maxLen, " "); + } else { + snprintf(buffer, sizeof(buffer), "%*d", maxLen, targetPosition); + } + logString += String(" | ") + buffer; + } + SS2K_LOG(POWERTABLE_LOG_TAG, "%s", logString.c_str()); + } +} + +int PowerTable::getNumReadings() { + int ret = 0; + for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + if (this->tableRow[i].tableEntry[j].readings > 0) { + ret++; + } + } + } + return ret; +} \ No newline at end of file From c7e7a2def678576c01a8f3c5fd4976bd507543b0 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sat, 15 Feb 2025 14:46:09 -0600 Subject: [PATCH 059/451] testing --- include/settings.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/settings.h b/include/settings.h index 417b4785..c7b3a4d2 100644 --- a/include/settings.h +++ b/include/settings.h @@ -302,6 +302,9 @@ const char* const DEFAULT_PASSWORD = "password"; // Increase this value if the offset for the loaded table is inaccurate. #define MINIMUM_RELIABLE_POSITIONS 3 +// Limit power table size to save memory +#define TABLE_DIVISOR 100.0 + // Temperature of the ESP32 at which to start reducing the power output of the stepper motor driver. #define THROTTLE_TEMP 90 @@ -333,9 +336,6 @@ const char* const DEFAULT_PASSWORD = "password"; #define MAIN_STACK 6500 #define BLE_CLIENT_STACK 6000 -// Limit table size to save memory -#define TABLE_DIVISOR 10 - // Uncomment to enable stack size debugging info // #define DEBUG_STACK From 8ff2197e8ec002b130b5ff49baed1d1d9b4933dd Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sun, 16 Feb 2025 17:06:10 -0600 Subject: [PATCH 060/451] less ble logging --- include/settings.h | 3 +++ src/BLE_Server.cpp | 50 ++++++++++++++++++++--------------------- src/Power_Table.cpp | 7 ++---- src/SensorCollector.cpp | 4 +++- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/include/settings.h b/include/settings.h index c7b3a4d2..26d74fd7 100644 --- a/include/settings.h +++ b/include/settings.h @@ -350,6 +350,9 @@ const char* const DEFAULT_PASSWORD = "password"; // Uncomment to enable HR->PWR enhanced torquetable debugging. // #define DEBUG_TORQUETABLE +// Uncomment to enable BLE_TX_RX Logging +// #define DEBUG_BLE_TX_RX + #ifdef USE_TELEGRAM // Max number of telegram messages to send per session #define MAX_TELEGRAM_MESSAGES 1 diff --git a/src/BLE_Server.cpp b/src/BLE_Server.cpp index a352cf3e..fb26da00 100644 --- a/src/BLE_Server.cpp +++ b/src/BLE_Server.cpp @@ -35,7 +35,7 @@ BLE_Fitness_Machine_Service fitnessMachineService; BLE_ss2kCustomCharacteristic ss2kCustomCharacteristic; BLE_Device_Information_Service deviceInformationService; BLE_Wattbike_Service wattbikeService; -//BLE_SB20_Service sb20Service; +// BLE_SB20_Service sb20Service; void startBLEServer() { // Server Setup @@ -53,12 +53,12 @@ void startBLEServer() { ss2kCustomCharacteristic.setupService(spinBLEServer.pServer); deviceInformationService.setupService(spinBLEServer.pServer); wattbikeService.setupService(spinBLEServer.pServer); // No callback needed - //sb20Service.begin(); + // sb20Service.begin(); BLEFirmwareSetup(); - + // const std::string fitnessData = {0b00000001, 0b00100000, 0b00000000}; // pAdvertising->setServiceData(FITNESSMACHINESERVICE_UUID, fitnessData); - pAdvertising->setName(static_cast(userConfig->getDeviceName())); + pAdvertising->setName(static_cast(userConfig->getDeviceName())); pAdvertising->setMaxInterval(250); pAdvertising->setMinInterval(160); @@ -76,7 +76,7 @@ void SpinBLEServer::update() { cyclingSpeedCadenceService.update(); fitnessMachineService.update(); wattbikeService.parseNemit(); // Changed from update() to parseNemit() - ///sb20Service.notify(); + /// sb20Service.notify(); } double SpinBLEServer::calculateSpeed() { @@ -126,8 +126,7 @@ void SpinBLEServer::updateWheelAndCrankRev() { // Creating Server Connection Callbacks void MyServerCallbacks::onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) { - SS2K_LOG(BLE_SERVER_LOG_TAG, "Bluetooth Remote Client Connected: %s Connected Clients: %d", - connInfo.getAddress().toString().c_str(), pServer->getConnectedCount()); + SS2K_LOG(BLE_SERVER_LOG_TAG, "Bluetooth Remote Client Connected: %s Connected Clients: %d", connInfo.getAddress().toString().c_str(), pServer->getConnectedCount()); if (pServer->getConnectedCount() < CONFIG_BT_NIMBLE_MAX_CONNECTIONS - NUM_BLE_DEVICES) { BLEDevice::startAdvertising(); @@ -152,7 +151,7 @@ void MyServerCallbacks::onMTUChange(uint16_t MTU, NimBLEConnInfo& connInfo) { } uint32_t MyServerCallbacks::onPassKeyDisplay() { - uint32_t passkey = 123456; // Static passkey for demonstration + uint32_t passkey = 123456; // Static passkey for demonstration SS2K_LOG(BLE_SERVER_LOG_TAG, "Server Passkey Display: %u", passkey); return passkey; } @@ -166,7 +165,7 @@ void MyServerCallbacks::onAuthenticationComplete(NimBLEConnInfo& connInfo) { SS2K_LOG(BLE_SERVER_LOG_TAG, "Secured connection to: %s", connInfo.getAddress().toString().c_str()); } -bool MyServerCallbacks::onConnParamsUpdateRequest(uint16_t handle, const ble_gap_upd_params *params) { +bool MyServerCallbacks::onConnParamsUpdateRequest(uint16_t handle, const ble_gap_upd_params* params) { SS2K_LOG(BLE_SERVER_LOG_TAG, "Updated Server Connection Parameters for handle: %d", handle); return true; } @@ -174,9 +173,7 @@ bool MyServerCallbacks::onConnParamsUpdateRequest(uint16_t handle, const ble_gap // END SERVER CALLBACKS void MyCharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) { - SS2K_LOG(BLE_SERVER_LOG_TAG, "Read from %s by client: %s", - pCharacteristic->getUUID().toString().c_str(), - connInfo.getAddress().toString().c_str()); + SS2K_LOG(BLE_SERVER_LOG_TAG, "Read from %s by client: %s", pCharacteristic->getUUID().toString().c_str(), connInfo.getAddress().toString().c_str()); } void MyCharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) { @@ -188,20 +185,19 @@ void MyCharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, N } void MyCharacteristicCallbacks::onStatus(NimBLECharacteristic* pCharacteristic, int code) { - //loop through and accumulate the data into a C++ string - std::string characteristicValue = pCharacteristic->getValue(); - std::string logValue; - for (size_t i = 0; i < characteristicValue.length(); ++i) { - char buf[4]; - snprintf(buf, sizeof(buf), "%02x ", (unsigned char)characteristicValue[i]); - logValue += buf; - } - - SS2K_LOGW(BLE_SERVER_LOG_TAG, "Notification/Indication status code: %d for char: %s Data: %s", - code, pCharacteristic->getUUID().toString().c_str(), logValue.c_str()); + // loop through and accumulate the data into a C++ string + std::string characteristicValue = pCharacteristic->getValue(); + std::string logValue; + for (size_t i = 0; i < characteristicValue.length(); ++i) { + char buf[4]; + snprintf(buf, sizeof(buf), "%02x ", (unsigned char)characteristicValue[i]); + logValue += buf; + } + + SS2K_LOGW(BLE_SERVER_LOG_TAG, "Notification/Indication status code: %d for char: %s Data: %s", code, pCharacteristic->getUUID().toString().c_str(), logValue.c_str()); } -void MyCharacteristicCallbacks::onSubscribe(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) { +void MyCharacteristicCallbacks::onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) { String str = "Client ID: "; NimBLEUUID pUUID = pCharacteristic->getUUID(); str += connInfo.getConnHandle(); @@ -280,8 +276,9 @@ void calculateInstPwrFromHR() { SS2K_LOG(BLE_SERVER_LOG_TAG, "Power From HR: %d", avgP); } -void logCharacteristic(char *buffer, const size_t bufferCapacity, const byte *data, const size_t dataLength, const NimBLEUUID serviceUUID, const NimBLEUUID charUUID, - const char *format, ...) { +void logCharacteristic(char* buffer, const size_t bufferCapacity, const byte* data, const size_t dataLength, const NimBLEUUID serviceUUID, const NimBLEUUID charUUID, + const char* format, ...) { +#ifdef DEBUG_BLE_TX_RX int bufferLength = ss2k_log_hex_to_buffer(data, dataLength, buffer, 0, bufferCapacity); bufferLength += snprintf(buffer + bufferLength, bufferCapacity - bufferLength, "-> %s | %s | ", serviceUUID.toString().c_str(), charUUID.toString().c_str()); va_list args; @@ -293,4 +290,5 @@ void logCharacteristic(char *buffer, const size_t bufferCapacity, const byte *da #ifdef USE_TELEGRAM SEND_TO_TELEGRAM(String(buffer)); #endif +#endif } diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index ff65b867..b98cd75e 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -681,7 +681,7 @@ void PowerTable::clean() { int downVote(int targetValue, int neighborValue) { // calculate diff between target and neighbor int delta = abs(targetValue - neighborValue); - float penalty; + int penalty; float penaltyFactor = 0.2; // currently consistently getting a 0 for neighbor value... @@ -690,7 +690,7 @@ int downVote(int targetValue, int neighborValue) { // we have a few different options for penalty calculations here, will need to test which works best: // linear function, low agression - penalty = delta * penaltyFactor; + penalty = round(delta * penaltyFactor); // quadratic function, high aggression // penalty = penaltyFactor * (delta * delta) @@ -703,9 +703,6 @@ int downVote(int targetValue, int neighborValue) { penalty = MAX_NEIGHBOR_WEIGHT; } - // round up penalty to make it an int - penalty = round(penalty); - SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Delta: (%d), Penalty: (%f)", delta, penalty); return penalty; } diff --git a/src/SensorCollector.cpp b/src/SensorCollector.cpp index 79c206cb..1efbe7db 100644 --- a/src/SensorCollector.cpp +++ b/src/SensorCollector.cpp @@ -75,13 +75,15 @@ void collectAndSet(NimBLEUUID charUUID, NimBLEUUID serviceUUID, NimBLEAddress ad logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " POS(%d)", ss2k->getCurrentPosition()); strncat(logBuf + logBufLength, " ]", kLogBufMaxLength - logBufLength); - // Peloton data screams, so only log one per second. +// Peloton data screams, so only log one per second. +#ifdef DEBUG_BLE_TX_RX static long int lastTime = millis(); if ((charUUID == PELOTON_DATA_UUID) && (millis() - lastTime < 1000)) return; SS2K_LOG(BLE_COMMON_LOG_TAG, "%s", logBuf); if (charUUID == PELOTON_DATA_UUID) lastTime = millis(); +#endif #ifdef USE_TELEGRAM SEND_TO_TELEGRAM(String(logBuf)); From 60ac609caa241047b50435dceb076924ef6e5e09 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Sun, 16 Feb 2025 18:43:42 -0600 Subject: [PATCH 061/451] added counting constraint and made downVoteData function. --- include/Power_Table.h | 2 + src/Power_Table.cpp | 129 ++++++++++++++++++++++-------------------- 2 files changed, 69 insertions(+), 62 deletions(-) diff --git a/include/Power_Table.h b/include/Power_Table.h index a7fa3579..12c0361d 100644 --- a/include/Power_Table.h +++ b/include/Power_Table.h @@ -105,6 +105,8 @@ class PowerTable { // enters data into power table void enterData(int i, int j, int pos); + void downVoteData(int i, int j, float target, int neighbor); + // returns incline for wattTarget. Null if not found. int32_t lookup(int watts, int cad); diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index b98cd75e..4c4811ad 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -678,7 +678,7 @@ void PowerTable::clean() { } // function for weighted downvoting -int downVote(int targetValue, int neighborValue) { +int weightedDownVote(int targetValue, int neighborValue) { // calculate diff between target and neighbor int delta = abs(targetValue - neighborValue); int penalty; @@ -768,15 +768,18 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { int avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); + int count = 0; if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) { // check if the current position moved left is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %f", targetPosition); this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); // enter the data + count++; } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { // checks if the avg position with the current watts and cadence is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); this->enterData(k, i, avgPosition); // enter the data + count++; } if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition) @@ -784,19 +787,19 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "Left Neighbors position was valid with Right Neighbors cadence and watts! Left Neighbor Position: %d", testResults.leftNeighbor.targetPosition); this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition); + count++; } - return; - } else { // if not we still get rid of the reading - // determine penalty amount before applying to failed neighbor - int penalty = downVote(targetPosition, testResults.leftNeighbor.targetPosition); - // make sure downvotes isn't at max - if (this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; - penalty = 0; + + if(count==0){ + + this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); + } - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings -= penalty; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Left (%d)(%d)(%f), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + + } else { + + this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); + } } @@ -804,34 +807,37 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition - 30 && testResults.rightNeighbor.targetPosition <= targetPosition)) { int avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); + int count = 0; if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved right was valid! Current position: %f", targetPosition); this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); + count++; } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); this->enterData(k, i, avgPosition); + count++; } if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Right Neighbors position was valid with Left Neighbors cadence and watts! Right Neighbor Position: %d", testResults.rightNeighbor.targetPosition); this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition); + count++; } - return; - } else { - // determine penalty amount before applying to failed neighbor - int penalty = downVote(targetPosition, testResults.rightNeighbor.targetPosition); - // make sure downvotes isn't at max - if (this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; - penalty = 0; + + if(count==0){ + + this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); + } - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings -= penalty; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, - testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + + } else { + + this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); + } } @@ -839,36 +845,36 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition - 30 && testResults.topNeighbor.targetPosition <= targetPosition)) { int avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); + int count = 0; if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); + count++; } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); this->enterData(k, i, avgPosition); + count++; } if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Top Neighbors position was valid with Bottom Neighbors cadence and watts! Top Neighbor Position: %d", testResults.topNeighbor.targetPosition); this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); + count++; } - return; - } else { - // determine penalty amount before applying to failed neighbor - int penalty = downVote(targetPosition, testResults.topNeighbor.targetPosition); - // make sure downvotes isn't at max - if (this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; - penalty = 0; + if(count==0){ + + this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); + } + } else { + + this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings -= penalty; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); } } @@ -876,58 +882,43 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition + 30 && testResults.bottomNeighbor.targetPosition >= targetPosition)) { int avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); + int count = 0; if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); + count++; } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); this->enterData(k, i, avgPosition); + count++; } if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom Neighbors position was valid with Top Neighbors cadence and watts! Bottom Neighbor Position: %d", testResults.topNeighbor.targetPosition); this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition); + count++; } - return; - } else { - // determine penalty amount before applying to failed neighbor - int penalty = downVote(targetPosition, testResults.bottomNeighbor.targetPosition); + if(count==0){ + + this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); - // make sure downvotes isn't at max - if (this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings > MAX_NEIGHBOR_WEIGHT) { - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings = MAX_NEIGHBOR_WEIGHT; - penalty = 0; } - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings -= penalty; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, - testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + + } else { + + this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); + } } return; } - // Update or create a new entry - if (this->tableRow[k].tableEntry[i].readings == 0) { // if first reading in this entry - this->tableRow[k].tableEntry[i].targetPosition = targetPosition; - SS2K_LOG(POWERTABLE_LOG_TAG, "New entry recorded (%d)(%d)(%d)", k, i, this->tableRow[k].tableEntry[i].targetPosition); - } else { // Average and update the readings. - this->tableRow[k].tableEntry[i].targetPosition = - (targetPosition + (this->tableRow[k].tableEntry[i].targetPosition * this->tableRow[k].tableEntry[i].readings)) / (this->tableRow[k].tableEntry[i].readings + 1.0); - SS2K_LOG(POWERTABLE_LOG_TAG, "Existing entry averaged (%d)(%d)(%d), readings(%d)", k, i, this->tableRow[k].tableEntry[i].targetPosition, - this->tableRow[k].tableEntry[i].readings); - if (this->tableRow[k].tableEntry[i].readings > MAX_NEIGHBOR_WEIGHT) { - this->tableRow[k].tableEntry[i].readings = MAX_NEIGHBOR_WEIGHT; // keep from diluting recent readings too far. - } - } - this->tableRow[k].tableEntry[i].readings++; - - // or - // this->enterData(k, i, (int)targetPosition); + this->enterData(k, i, (int)targetPosition); // Attempt to fill the table with calculated data... if (this->getNumEntries() > 4) { @@ -962,6 +953,20 @@ void PowerTable::enterData(int i, int j, int pos) { this->tableRow[i].tableEntry[j].readings++; } +void PowerTable::downVoteData(int i, int j, float target, int neighbor){ + // determine penalty amount before applying to failed neighbor + int penalty = weightedDownVote(target, neighbor); + + // make sure downvotes isn't at max + if (this->tableRow[i].tableEntry[j].readings > MAX_NEIGHBOR_WEIGHT) { + this->tableRow[i].tableEntry[j].readings = MAX_NEIGHBOR_WEIGHT; + penalty = 0; + } + this->tableRow[i].tableEntry[j].readings -= penalty; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", i, j, + neighbor, this->tableRow[i].tableEntry[j].readings); +} + bool PowerTable::_manageSaveState(bool canSkipReliabilityChecks) { // Check if the table has been loaded in this session if (!this->_hasBeenLoadedThisSession) { From b5726f3364848f0376a76e4acbba075af1062945 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Mon, 17 Feb 2025 01:02:38 +0000 Subject: [PATCH 062/451] Update changelog for version 25.1.28 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c19e664..a4303084 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +### Changed + +### Hardware + + +## [25.1.28] + +### Added + ### Changed -PID loop for ERG mode instead of P loop. From 06d3fe7f67370b88aad883cd357a55436d6ee63b Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Mon, 17 Feb 2025 12:36:05 -0600 Subject: [PATCH 063/451] scan fixes for NimBLE 2.0 --- include/BLE_Custom_Characteristic.h | 1 + include/settings.h | 3 + .../BLE_Client-checkpoint.cpp | 942 ------------------ src/BLE_Client.cpp | 5 +- src/BLE_Custom_Characteristic.cpp | 27 +- src/BLE_Fitness_Machine_Service.cpp | 28 +- src/BLE_Server.cpp | 2 +- 7 files changed, 32 insertions(+), 976 deletions(-) delete mode 100644 src/.ipynb_checkpoints/BLE_Client-checkpoint.cpp diff --git a/include/BLE_Custom_Characteristic.h b/include/BLE_Custom_Characteristic.h index 76b8899d..20d0d3ad 100644 --- a/include/BLE_Custom_Characteristic.h +++ b/include/BLE_Custom_Characteristic.h @@ -83,4 +83,5 @@ class BLE_ss2kCustomCharacteristic { class ss2kCustomCharacteristicCallbacks : public NimBLECharacteristicCallbacks { void onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) override; void onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) override; + void onStatus(NimBLECharacteristic* pCharacteristic, int code) override; }; diff --git a/include/settings.h b/include/settings.h index 26d74fd7..b688dc4b 100644 --- a/include/settings.h +++ b/include/settings.h @@ -353,6 +353,9 @@ const char* const DEFAULT_PASSWORD = "password"; // Uncomment to enable BLE_TX_RX Logging // #define DEBUG_BLE_TX_RX +// UNcomment to enable Custom Characteristic Logging +// #define CUSTOM_CHAR_DEBUG + #ifdef USE_TELEGRAM // Max number of telegram messages to send per session #define MAX_TELEGRAM_MESSAGES 1 diff --git a/src/.ipynb_checkpoints/BLE_Client-checkpoint.cpp b/src/.ipynb_checkpoints/BLE_Client-checkpoint.cpp deleted file mode 100644 index 74f53167..00000000 --- a/src/.ipynb_checkpoints/BLE_Client-checkpoint.cpp +++ /dev/null @@ -1,942 +0,0 @@ -/* - * Copyright (C) 2020 Anthony Doud & Joel Baranick - * All rights reserved - * - * SPDX-License-Identifier: GPL-2.0-only - */ - -/* Assioma Pedal Information for later -BLE Advertised Device found: Name: ASSIOMA17287L, Address: e8:fe:6e:91:9f:16, -appearance: 1156, manufacturer data: 640302018743, serviceUUID: -00001818-0000-1000-8000-00805f9b34fb -*/ - -#include "Main.h" -#include "BLE_Common.h" -#include "BLE_Fitness_Machine_Service.h" -#include "SS2KLog.h" - -#include -#include -#include -#include - -TaskHandle_t BLEClientTask; - -SpinBLEClient spinBLEClient; - -static MyClientCallback myClientCallback; -static MyAdvertisedDeviceCallback myAdvertisedDeviceCallbacks; - -void SpinBLEClient::start() { - // Create the task for the BLE Client loop - xTaskCreatePinnedToCore(bleClientTask, /* Task function. */ - "BLEClientTask", /* name of task. */ - BLE_CLIENT_STACK, /* Stack size of task */ - NULL, /* parameter of the task */ - 1, /* priority of the task */ - &BLEClientTask, /* Task handle to keep track of created task */ - 1); /* pin task to core */ -} - -static void onNotify(BLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t *pData, size_t length, bool isNotify) { - // Parse BLE shifter info. - if (pBLERemoteCharacteristic->getRemoteService()->getUUID() == HID_SERVICE_UUID) { - Serial.print(pData[0], HEX); - if (pData[0] == 0x04) { - rtConfig->setShifterPosition(rtConfig->getShifterPosition() + 1); - } - if (pData[0] == 0x08) { - rtConfig->setShifterPosition(rtConfig->getShifterPosition() - 1); - } - } - - // enqueue sensor data - for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { - if (pBLERemoteCharacteristic->getUUID() == spinBLEClient.myBLEDevices[i].charUUID) { - spinBLEClient.myBLEDevices[i].enqueueData(pData, length); - } - } -} - -// BLE Client loop task. -// Manages device connections and scanning. -void bleClientTask(void *pvParameters) { - long int scanDelay = millis(); - for (;;) { - vTaskDelay(BLE_CLIENT_DELAY / portTICK_PERIOD_MS); // Delay between loops. - - // disconnect all connected servers if we're updating via BLE - if (ss2k->isUpdating) { - for (auto &_BLEd : spinBLEClient.myBLEDevices) { // loop through discovered devices - if (_BLEd.connectedClientID != BLE_HS_CONN_HANDLE_NONE) { - if (_BLEd.advertisedDevice) { // is device registered? - if ((_BLEd.connectedClientID != BLE_HS_CONN_HANDLE_NONE) && (_BLEd.doConnect == false)) { // client must not be in connection process - if (BLEDevice::getClientByPeerAddress(_BLEd.peerAddress)) { // nullptr check - NimBLEClient *pClient = NimBLEDevice::getClientByPeerAddress(_BLEd.peerAddress); - pClient->disconnect(); - } - } - } - } - } - } - - // Scan for BLE devices that we should connect to this client - if ((millis() - scanDelay) > ((BLE_RECONNECT_SCAN_DURATION * 1000) * 2)) { - spinBLEClient.checkBLEReconnect(); - scanDelay = millis(); -#ifdef DEBUG_STACK - Serial.printf("BLEClient: %d \n", uxTaskGetStackHighWaterMark(BLEClientTask)); -#endif // DEBUG_STACK - } - - if (spinBLEClient.doScan && (!ss2k->isUpdating)) { - spinBLEClient.scanProcess(); - } - - // Connect BLE Servers to this client - for (int x = 0; x < NUM_BLE_DEVICES; x++) { - if (spinBLEClient.myBLEDevices[x].doConnect == true && !ss2k->isUpdating) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Connecting device on slot %d ...", x); - if (spinBLEClient.connectToServer()) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "We are now connected to the BLE Server."); - } else { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "slot %d connection failed", x); - } - } - } - // Spin Down process for the Server. It's here because it needs to be non-blocking for the maintenance loop. - // Checking for cadence also so that we don't home when nobody is around. - if (spinBLEServer.spinDownFlag && rtConfig->cad.getValue()) { - if (spinBLEServer.spinDownFlag >= 2) { // Home Both Directions - ss2k->goHome(true); - } else { // Startup Homing - ss2k->goHome(false); - } - spinBLEServer.spinDownFlag = 0; - } - } -} - -bool SpinBLEClient::connectToServer() { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Initiating Server Connection"); - NimBLEUUID serviceUUID; - NimBLEUUID charUUID; - - int successful = 0; - BLEAdvertisedDevice *myDevice = nullptr; - int device_number = -1; - - for (int i = 0; i < NUM_BLE_DEVICES; i++) { - if (spinBLEClient.myBLEDevices[i].doConnect == true) { // Client wants to be connected - if (spinBLEClient.myBLEDevices[i].advertisedDevice) { // Client is assigned - // If this device is advertising HR service AND not advertising FTMS service AND there is no connected PM AND the next slot is set to connect, connect that one first - // and connect the HRM last. if (spinBLEClient.myBLEDevices[i].advertisedDevice->isAdvertisingService(HEARTSERVICE_UUID) && - // (!spinBLEClient.myBLEDevices[i].advertisedDevice->isAdvertisingService(FITNESSMACHINESERVICE_UUID)) && (!connectedPM) && - // (spinBLEClient.myBLEDevices[i + 1].doConnect == true)) { - // myDevice = spinBLEClient.myBLEDevices[i + 1].advertisedDevice; - // device_number = i + 1; - // SS2K_LOG(BLE_CLIENT_LOG_TAG, "Connecting HRM last."); - // } else { - myDevice = spinBLEClient.myBLEDevices[i].advertisedDevice; - device_number = i; - // } - break; - } else { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "doConnect and client out of alignment. Resetting device slot."); - spinBLEClient.myBLEDevices[i].reset(); - return false; - } - } else { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "doConnect on slot %d not set", i); - } - } - if (myDevice == nullptr) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "No Device Found to Connect"); - return false; - } - // FUTURE - Iterate through an array of UUID's we support instead of all the if checks. - if (myDevice->getServiceUUIDCount() > 0) { - if (myDevice->isAdvertisingService(FLYWHEEL_UART_SERVICE_UUID) && (myDevice->getName() == FLYWHEEL_BLE_NAME)) { - serviceUUID = FLYWHEEL_UART_SERVICE_UUID; - charUUID = FLYWHEEL_UART_TX_UUID; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "trying to connect to Flywheel Bike"); - } else if (myDevice->isAdvertisingService(FITNESSMACHINESERVICE_UUID)) { - serviceUUID = FITNESSMACHINESERVICE_UUID; - charUUID = FITNESSMACHINEINDOORBIKEDATA_UUID; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "trying to connect to Fitness Machine Service"); - } else if (myDevice->isAdvertisingService(CYCLINGPOWERSERVICE_UUID)) { - serviceUUID = CYCLINGPOWERSERVICE_UUID; - charUUID = CYCLINGPOWERMEASUREMENT_UUID; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "trying to connect to Cycling Power Service"); - } else if (myDevice->isAdvertisingService(ECHELON_DEVICE_UUID)) { - serviceUUID = ECHELON_SERVICE_UUID; - charUUID = ECHELON_DATA_UUID; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Trying to connect to Echelon Bike"); - } else if (myDevice->isAdvertisingService(HEARTSERVICE_UUID)) { - serviceUUID = HEARTSERVICE_UUID; - charUUID = HEARTCHARACTERISTIC_UUID; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Trying to connect to HRM"); - } else if (myDevice->isAdvertisingService(HID_SERVICE_UUID)) { - serviceUUID = HID_SERVICE_UUID; - charUUID = HID_REPORT_DATA_UUID; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Trying to connect to BLE HID remote"); - } else { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "No advertised UUID found"); - spinBLEClient.myBLEDevices[device_number].reset(); - return false; - } - } else { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Device has no Service UUID"); - spinBLEClient.myBLEDevices[device_number].reset(); - // spinBLEClient.serverScan(true); - return false; - } - - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Forming a connection to: %s", this->adevName2UniqueName(myDevice).c_str()); - - NimBLEClient *pClient = nullptr; - - /** Check if we have a client we should reuse first **/ - if (NimBLEDevice::getClientListSize()) { - /** Special case when we already know this device, we send false as the - * second argument in connect() to prevent refreshing the service database. - * This saves considerable time and power. - */ - pClient = NimBLEDevice::getClientByPeerAddress(myDevice->getAddress()); - if (pClient) { - pClient->setConnectTimeout(2); - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Reusing Client"); - if (!pClient->connect(myDevice, false)) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Reconnect failed "); - this->reconnectTries--; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "%d left.", reconnectTries); - if (reconnectTries < 1) { - spinBLEClient.myBLEDevices[device_number].reset(); - spinBLEClient.resetDevices(pClient); - pClient->deleteServices(); - NimBLEDevice::getScan()->erase(pClient->getPeerAddress()); - NimBLEDevice::deleteClient(pClient); - } - return false; - } - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Reconnected client"); - } - /** We don't already have a client that knows this device, - * we will check for a client that is disconnected that we can use. - */ - else { - pClient = NimBLEDevice::getDisconnectedClient(); - } - } - - /** No client to reuse? Create a new one. */ - if (!pClient) { - if (NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS) { - Serial.println("Max clients reached - no more connections available"); - return false; - } - - pClient = NimBLEDevice::createClient(); - - SS2K_LOG(BLE_CLIENT_LOG_TAG, " - Created client"); - - pClient->setClientCallbacks(&myClientCallback, false); - /** Set initial connection parameters: These settings are 15ms interval, 0 latency, 120ms timout. - * These settings are safe for 3 clients to connect reliably, can go faster if you have less - * connections. Timeout should be a multiple of the interval, minimum is 100ms. - * Min interval: 12 * 1.25ms = 15, Max interval: 12 * 1.25ms = 15, 0 latency, 51 * 10ms = 510ms timeout - */ - pClient->setConnectionParams(6, 6, 0, 200); - /** Set how long we are willing to wait for the connection to complete (seconds), default is 30. */ - pClient->setConnectTimeout(5); // 5 - - if (!pClient->connect(myDevice->getAddress())) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, " - Failed to connect client"); - /** Created a client but failed to connect, don't need to keep it as it has no data */ - spinBLEClient.myBLEDevices[device_number].reset(); - pClient->deleteServices(); - NimBLEDevice::getScan()->erase(pClient->getPeerAddress()); - NimBLEDevice::deleteClient(pClient); - return false; - } - } - - if (!pClient->isConnected()) { - if (!pClient->connect(myDevice)) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to connect"); - return false; - } - } - - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Connected to: %s - %s RSSI %d", this->adevName2UniqueName(myDevice).c_str(), pClient->getPeerAddress().toString().c_str(), pClient->getRssi()); - - if (serviceUUID == HID_SERVICE_UUID) { - connectBLE_HID(pClient); - this->reconnectTries = MAX_RECONNECT_TRIES; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Successful remote subscription."); - spinBLEClient.myBLEDevices[device_number].doConnect = false; - this->reconnectTries = MAX_RECONNECT_TRIES; - spinBLEClient.myBLEDevices[device_number].set(myDevice, pClient->getConnId(), serviceUUID, charUUID); - spinBLEClient.myBLEDevices[device_number].peerAddress = pClient->getPeerAddress(); - removeDuplicates(pClient); - return true; - } - - /** Now we can read/write/subscribe the characteristics of the services we are interested in */ - NimBLERemoteService *pSvc = nullptr; - NimBLERemoteCharacteristic *pChr = nullptr; - NimBLERemoteDescriptor *pDsc = nullptr; - - pSvc = pClient->getService(serviceUUID); - if (pSvc) { /** make sure it's not null */ - pChr = pSvc->getCharacteristic(charUUID); - - if (pChr) { /** make sure it's not null */ - if (pChr->canRead()) { - NimBLEAttValue value = pChr->readValue(); - const int kLogBufMaxLength = 250; - char logBuf[kLogBufMaxLength]; - int logBufLength = ss2k_log_hex_to_buffer(value.data(), value.length(), logBuf, 0, kLogBufMaxLength); - logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " <-initial Value"); - SS2K_LOG(BLE_COMMON_LOG_TAG, "%s", logBuf); - } - if (pChr->canNotify()) { - if (!pChr->subscribe(true, onNotify)) { - /** Disconnect if subscribe failed */ - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Notifications Failed for %s", pClient->getPeerAddress().toString().c_str()); - spinBLEClient.myBLEDevices[device_number].reset(); - pClient->deleteServices(); - NimBLEDevice::getScan()->erase(pClient->getPeerAddress()); - NimBLEDevice::deleteClient(pClient); - return false; - } - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Notifications Subscribed for %s", pClient->getPeerAddress().toString().c_str()); - } else if (pChr->canIndicate()) { - /** Send false as first argument to subscribe to indications instead of notifications */ - if (!pChr->subscribe(false, onNotify)) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Indications Failed for %s", pClient->getPeerAddress().toString().c_str()); - /** Disconnect if subscribe failed */ - spinBLEClient.myBLEDevices[device_number].reset(); - pClient->deleteServices(); - NimBLEDevice::getScan()->erase(pClient->getPeerAddress()); - NimBLEDevice::deleteClient(pClient); - return false; - } - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Indications Subscribed for %s", pClient->getPeerAddress().toString().c_str()); - } - this->reconnectTries = MAX_RECONNECT_TRIES; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Successful %s subscription.", pChr->getUUID().toString().c_str()); - spinBLEClient.myBLEDevices[device_number].doConnect = false; - this->reconnectTries = MAX_RECONNECT_TRIES; - spinBLEClient.myBLEDevices[device_number].set(myDevice, pClient->getConnId(), serviceUUID, charUUID); - spinBLEClient.myBLEDevices[device_number].peerAddress = pClient->getPeerAddress(); - removeDuplicates(pClient); - } - - } else { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to find service: %s", serviceUUID.toString().c_str()); - } - - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Device Connected"); - return true; -} - -/** None of these are required as they will be handled by the library with defaults. ** - ** Remove as you see fit for your needs */ - -void MyClientCallback::onConnect(NimBLEClient *pClient) { - // additional characteristic subscriptions. -} - -void MyClientCallback::onDisconnect(NimBLEClient *pClient) { - if (!pClient->isConnected()) { - NimBLEAddress addr = pClient->getPeerAddress(); - SS2K_LOG(BLE_CLIENT_LOG_TAG, "This disconnected client Address %s", addr.toString().c_str()); - for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { - if (addr == spinBLEClient.myBLEDevices[i].peerAddress) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Detected %s Disconnect", spinBLEClient.myBLEDevices[i].serviceUUID.toString().c_str()); - // did another task disconnect this device? - if (!spinBLEClient.intentionalDisconnect) { - spinBLEClient.myBLEDevices[i].doConnect = true; - } else { - spinBLEClient.intentionalDisconnect--; - } - 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) || - (spinBLEClient.myBLEDevices[i].charUUID == CYCLINGPOWERSERVICE_UUID)) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Deregistered PM on Disconnect"); - rtConfig->pm_batt.setValue(0); - } - if ((spinBLEClient.myBLEDevices[i].charUUID == HEARTCHARACTERISTIC_UUID)) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Deregistered HR on Disconnect"); - rtConfig->hr_batt.setValue(0); - } - if ((spinBLEClient.myBLEDevices[i].charUUID == HID_REPORT_DATA_UUID)) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Deregistered Remote on Disconnect"); - } - spinBLEClient.myBLEDevices[i].reset(); - } - } - return; - } -} - -/***************** New - Security handled here ******************** -****** Note: these are the same return values as defaults ********/ -uint32_t MyClientCallback::onPassKeyRequest() { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Client PassKeyRequest"); - return 123456; -} -bool MyClientCallback::onConfirmPIN(uint32_t pass_key) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "The passkey YES/NO number: %ud", pass_key); - return true; -} - -void MyClientCallback::onAuthenticationComplete(ble_gap_conn_desc desc) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Starting BLE work!"); } -/*******************************************************************/ - -/** - * Scan for BLE servers and find the first one that advertises the service we are looking for. - */ - -void MyAdvertisedDeviceCallback::onResult(BLEAdvertisedDevice *advertisedDevice) { - // Define granular constants for maximal reuse during logging - const char *const MATCHED = "Matched "; - const char *const DIDNT_MATCH_THE_SAVED = " didn't match the saved: "; - const char *const STRING_MATCHED_ANY = " String Matched Any"; - const char *const THIS = "This "; - const char *const NAME = "Name "; - const char *const ADDRESS = "Address "; - const char *const REMOTE = "Remote"; - const char *const HRM = "HRM"; - const char *const PM = "PM"; - String aDevName = spinBLEClient.adevName2UniqueName(advertisedDevice); - const char *aDevAddr = advertisedDevice->getAddress().toString().c_str(); - - if ((advertisedDevice->haveServiceUUID()) && (advertisedDevice->isAdvertisingService(CYCLINGPOWERSERVICE_UUID) || - (advertisedDevice->isAdvertisingService(FLYWHEEL_UART_SERVICE_UUID) && aDevName == String(FLYWHEEL_BLE_NAME)) || - advertisedDevice->isAdvertisingService(FITNESSMACHINESERVICE_UUID) || advertisedDevice->isAdvertisingService(HEARTSERVICE_UUID) || - advertisedDevice->isAdvertisingService(ECHELON_DEVICE_UUID) || advertisedDevice->isAdvertisingService(HID_SERVICE_UUID))) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Trying to match found device name: %s", aDevName.c_str()); - - // Handling for BLE connected remotes - if (advertisedDevice->getServiceUUID() == HID_SERVICE_UUID) { - if (strcmp(userConfig->getConnectedRemote(), "any") == 0) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s", REMOTE, STRING_MATCHED_ANY); - } else { - bool nameMatched = (aDevName = userConfig->getConnectedRemote()) ? true : false; - bool addrMatched = strcmp(aDevAddr, userConfig->getConnectedRemote()) == 0; - if (!nameMatched && !addrMatched || strcmp(userConfig->getConnectedRemote(), "none") == 0) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s%s%s", THIS, REMOTE, DIDNT_MATCH_THE_SAVED, userConfig->getConnectedRemote()); - return; // Ignore this device; - } else { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s %s%s", REMOTE, NAME, MATCHED, aDevName); - } - } - } else if (advertisedDevice->getServiceUUID() == HEARTSERVICE_UUID) { - if (strcmp(userConfig->getConnectedHeartMonitor(), "any") == 0) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s", HRM, STRING_MATCHED_ANY); - } else { - bool nameMatched = (aDevName == userConfig->getConnectedHeartMonitor()) ? true : false; - bool addrMatched = strcmp(aDevAddr, userConfig->getConnectedHeartMonitor()) == 0; - if (!nameMatched && !addrMatched || strcmp(userConfig->getConnectedHeartMonitor(), "none") == 0) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s%s%s", THIS, HRM, DIDNT_MATCH_THE_SAVED, userConfig->getConnectedHeartMonitor()); - return; // Ignore this device; - } else { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s %s%s", HRM, NAME, MATCHED, aDevName); - } - } - } else { - // Power Meter - if (strcmp(userConfig->getConnectedPowerMeter(), "any") == 0) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s", PM, STRING_MATCHED_ANY); - } else { - bool nameMatched = (aDevName == userConfig->getConnectedPowerMeter()) ? true : false; - if (!nameMatched || strcmp(userConfig->getConnectedPowerMeter(), "none") == 0) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s%s%s", THIS, PM, DIDNT_MATCH_THE_SAVED, userConfig->getConnectedPowerMeter()); - return; // Ignore this device; - } else { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s %s%s", PM, NAME, MATCHED, aDevName); - } - } - } - - for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { - if ((spinBLEClient.myBLEDevices[i].advertisedDevice == nullptr) || (advertisedDevice->getAddress() == spinBLEClient.myBLEDevices[i].peerAddress)) { - spinBLEClient.myBLEDevices[i].set(advertisedDevice, BLE_HS_CONN_HANDLE_NONE, advertisedDevice->getServiceUUID()); - spinBLEClient.myBLEDevices[i].doConnect = true; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "doConnect set on device: %d", i); - return; - } - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Checking Slot %d", i); - } - } -} - -void SpinBLEClient::scanProcess(int duration) { - this->doScan = false; // Confirming we did the scan - - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Scanning for BLE servers and putting them into a list..."); - - BLEScan *pBLEScan = BLEDevice::getScan(); - pBLEScan->stop(); - vTaskDelay(50 / portTICK_PERIOD_MS); - pBLEScan->clearDuplicateCache(); - pBLEScan->clearResults(); - pBLEScan->setAdvertisedDeviceCallbacks(&myAdvertisedDeviceCallbacks); - pBLEScan->setInterval(49); // 97 - pBLEScan->setWindow(33); // 67 - pBLEScan->setDuplicateFilter(true); - pBLEScan->setActiveScan(true); // might cause memory leak if true - undetermined. We don't get device names without it. - BLEScanResults foundDevices = pBLEScan->start(duration, false); - this->dontBlockScan = false; - - int count = foundDevices.getCount(); - - StaticJsonDocument<1000> devices; - - // Check if 'devices' JSON document already exists and has content; if so, deserialize it. - const char *foundDevicesJson = userConfig->getFoundDevices(); - if (foundDevicesJson[0] != '\0') { - deserializeJson(devices, userConfig->getFoundDevices()); - } - - for (int i = 0; i < count; i++) { - BLEAdvertisedDevice d = foundDevices.getDevice(i); - - // Check for duplicates by name or address before adding - bool isDuplicate = false; - for (JsonPair kv : devices.as()) { - JsonObject obj = kv.value().as(); - if (obj.containsKey("name") && obj["name"] == this->adevName2UniqueName(&d)) { - isDuplicate = true; - break; - } - } - - // is this device advertising something we're interested in? - if (!isDuplicate && (d.isAdvertisingService(CYCLINGPOWERSERVICE_UUID) || d.isAdvertisingService(HEARTSERVICE_UUID) || d.isAdvertisingService(FLYWHEEL_UART_SERVICE_UUID) || - d.isAdvertisingService(FITNESSMACHINESERVICE_UUID) || d.isAdvertisingService(ECHELON_DEVICE_UUID) || d.isAdvertisingService(HID_SERVICE_UUID))) { - String device = "device " + String(devices.size()); // Use the current size to index the new device - - devices[device]["name"] = this->adevName2UniqueName(&d); - - // Workaround for IC4 not advertising FTMS as the first service. - // Potentially others may need to be added in the future. - // The symptom was the bike name not showing up in the HTML. - if (d.haveServiceUUID() && d.isAdvertisingService(FITNESSMACHINESERVICE_UUID)) { - devices[device]["UUID"] = FITNESSMACHINESERVICE_UUID.toString(); - } else { - devices[device]["UUID"] = d.getServiceUUID().toString(); - } - } - } - - String output; - serializeJson(devices, output); - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Bluetooth Client Found Devices: %s", output.c_str()); -#ifdef USE_TELEGRAM - SEND_TO_TELEGRAM("Bluetooth Client Found Devices: " + output); -#endif - userConfig->setFoundDevices(output); // Save the updated JSON document -} - -// remove the last connected BLE Power Meter -void SpinBLEClient::removeDuplicates(NimBLEClient *pClient) { - // BLEAddress thisAddress = pClient->getPeerAddress(); - SpinBLEAdvertisedDevice tBLEd; - SpinBLEAdvertisedDevice oldBLEd; - for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { // Disconnect oldest PM to avoid two connected. - tBLEd = this->myBLEDevices[i]; - if (tBLEd.peerAddress == pClient->getPeerAddress()) { - break; - } - } - - for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { // Disconnect oldest PM to avoid two connected. - oldBLEd = this->myBLEDevices[i]; - if (oldBLEd.advertisedDevice) { - if ((tBLEd.serviceUUID == oldBLEd.serviceUUID) && (tBLEd.peerAddress != oldBLEd.peerAddress)) { - if (BLEDevice::getClientByPeerAddress(oldBLEd.peerAddress)) { - if (BLEDevice::getClientByPeerAddress(oldBLEd.peerAddress)->isConnected()) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s Matched another service. Disconnecting: %s", tBLEd.peerAddress.toString().c_str(), oldBLEd.peerAddress.toString().c_str()); - NimBLEDevice::deleteClient(BLEDevice::getClientByPeerAddress(oldBLEd.peerAddress)); - oldBLEd.reset(); - spinBLEClient.intentionalDisconnect++; - return; - } - } - } - } - } -} - -void SpinBLEClient::resetDevices(NimBLEClient *pClient) { - for (auto &_BLEd : spinBLEClient.myBLEDevices) { - if (pClient->getPeerAddress() == _BLEd.peerAddress) { - SS2K_LOGW(BLE_CLIENT_LOG_TAG, "Reset Client: %s", _BLEd.peerAddress.toString().c_str()); - _BLEd.reset(); - } - } -} - -// Control a connected FTMS trainer. If no args are passed, treat it like an external stepper motor. -void SpinBLEClient::FTMSControlPointWrite(const uint8_t *pData, int length) { - if (userConfig->getFTMSControlPointWrite()) { - NimBLEClient *pClient = nullptr; - uint8_t modData[7]; - for (int i = 0; i < length; i++) { - modData[i] = pData[i]; - } - for (int i = 0; i < NUM_BLE_DEVICES; i++) { - if (myBLEDevices[i].getPostConnected() && (myBLEDevices[i].serviceUUID == FITNESSMACHINESERVICE_UUID)) { - if (NimBLEDevice::getClientByPeerAddress(myBLEDevices[i].peerAddress)->getService(FITNESSMACHINESERVICE_UUID)) { - pClient = NimBLEDevice::getClientByPeerAddress(myBLEDevices[i].peerAddress); - break; - } - } - } - if (pClient) { - NimBLERemoteCharacteristic *writeCharacteristic = pClient->getService(FITNESSMACHINESERVICE_UUID)->getCharacteristic(FITNESSMACHINECONTROLPOINT_UUID); - int logBufLength = 0; - if (writeCharacteristic) { - const int kLogBufCapacity = length + 40; - char logBuf[kLogBufCapacity]; - if (modData[0] == FitnessMachineControlPointProcedure::SetIndoorBikeSimulationParameters) { // use virtual Shifting - int incline = ss2k->getTargetPosition() / userConfig->getInclineMultiplier(); - modData[3] = (uint8_t)(incline & 0xff); - modData[4] = (uint8_t)(incline >> 8); - writeCharacteristic->writeValue(modData, length); - logBufLength = ss2k_log_hex_to_buffer(modData, length, logBuf, 0, kLogBufCapacity); - logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> Shifted Sim Data: %d", rtConfig->getShifterPosition()); - } else { - writeCharacteristic->writeValue(modData, length); - logBufLength = ss2k_log_hex_to_buffer(modData, length, logBuf, 0, kLogBufCapacity); - logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> Shifted ERG Data: %d", rtConfig->getShifterPosition()); - } - SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s", logBuf); - } - } - } -} - -void SpinBLEClient::postConnect() { - for (auto &_BLEd : spinBLEClient.myBLEDevices) { - // Check that the device has been assigned and it hasn't been post connected. - if ((_BLEd.connectedClientID != BLE_HS_CONN_HANDLE_NONE) && !_BLEd.getPostConnected()) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Post connecting: %s , ConnID %d", _BLEd.peerAddress.toString().c_str(), _BLEd.connectedClientID); - if (NimBLEDevice::getClientByPeerAddress(_BLEd.peerAddress)) { - _BLEd.setPostConnected(true); - NimBLEClient *pClient = NimBLEDevice::getClientByPeerAddress(_BLEd.peerAddress); - if (_BLEd.charUUID == ECHELON_DATA_UUID) { - NimBLERemoteCharacteristic *writeCharacteristic = pClient->getService(ECHELON_SERVICE_UUID)->getCharacteristic(ECHELON_WRITE_UUID); - if (writeCharacteristic == nullptr) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to find Echelon write characteristic UUID: %s", ECHELON_WRITE_UUID.toString().c_str()); - pClient->disconnect(); - return; - } - // Enable device notifications - byte message[] = {0xF0, 0xB0, 0x01, 0x01, 0xA2}; - writeCharacteristic->writeValue(message, 5); - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Activated Echelon callbacks."); - rtConfig->setMinResistance(MIN_ECHELON_RESISTANCE); - rtConfig->setMaxResistance(MAX_ECHELON_RESISTANCE); - } - - if ((_BLEd.charUUID == FITNESSMACHINEINDOORBIKEDATA_UUID)) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Updating Connection Params for: %s", _BLEd.peerAddress.toString().c_str()); - BLEDevice::getServer()->updateConnParams(pClient->getConnId(), 100, 100, 2, 1000); - spinBLEClient.handleBattInfo(pClient, true); - - auto featuresCharacteristic = pClient->getService(FITNESSMACHINESERVICE_UUID)->getCharacteristic(FITNESSMACHINEFEATURE_UUID); - if (featuresCharacteristic == nullptr) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to find FTMS features characteristic UUID: %s", FITNESSMACHINEFEATURE_UUID.toString().c_str()); - return; - } - - if (featuresCharacteristic->canRead()) { - auto value = featuresCharacteristic->readValue(); - if (value.size() < sizeof(uint64_t)) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to read FTMS features characteristic"); - return; - } - - // We're only interested in the machine fitness features, not the target setting features. - auto features = *reinterpret_cast(value.data()); - if (!(features & FitnessMachineFeatureFlags::Types::ElapsedTimeSupported) || !(features & FitnessMachineFeatureFlags::Types::RemainingTimeSupported)) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "FTMS Control Point StartOrResume not supported"); - return; - } - } - - NimBLERemoteCharacteristic *writeCharacteristic = pClient->getService(FITNESSMACHINESERVICE_UUID)->getCharacteristic(FITNESSMACHINECONTROLPOINT_UUID); - if (writeCharacteristic == nullptr) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to find FTMS control characteristic UUID: %s", FITNESSMACHINECONTROLPOINT_UUID.toString().c_str()); - return; - } - - // If we would like to control an external FTMS trainer. With most spin bikes we would want this off, but it's useful if you want to use the SmartSpin2k as an - // appliance. - if (userConfig->getFTMSControlPointWrite()) { - writeCharacteristic->writeValue(FitnessMachineControlPointProcedure::RequestControl, 1); - vTaskDelay(BLE_NOTIFY_DELAY / portTICK_PERIOD_MS); - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Activated FTMS Training."); - } - writeCharacteristic->writeValue(FitnessMachineControlPointProcedure::StartOrResume, 1); - } - } - } - } -} - -bool SpinBLEAdvertisedDevice::enqueueData(uint8_t *data, size_t length) { - NotifyData notifyData; - - if (!uxQueueSpacesAvailable(this->dataBufferQueue)) { - // Serial.println("No space available in queue. Skipping enqueue of data."); - return pdFALSE; - } - - notifyData.length = length; - for (size_t i = 0; i < length; i++) { - notifyData.data[i] = data[i]; - // Serial.printf("%02x ", notifyData.data[i]); - } - // Serial.printf("\n"); - - if (xQueueSendToBack(this->dataBufferQueue, ¬ifyData, 10) == pdFALSE) { - // Serial.println("Failed to enqueue data. Freeing data."); - return pdFALSE; - } - // Serial.printf("Successfully enqueued data. %d. \n", notifyData.length); - return pdTRUE; -} - -NotifyData SpinBLEAdvertisedDevice::dequeueData() { - NotifyData receivedNotifyData; - if (this->dataBufferQueue == nullptr) { - // Serial.println("Queue not created. Skipping dequeue of data."); - receivedNotifyData.length = 0; - return receivedNotifyData; - } - if (xQueueReceive(this->dataBufferQueue, &receivedNotifyData, 0) == pdTRUE) { - // Serial.printf("Successfully dequeued data from queue. %d \n", receivedNotifyData.length); - return receivedNotifyData; - } - // Serial.println("buffer was empty"); - receivedNotifyData.length = 0; - return receivedNotifyData; -} - -// Was changed in notify-Buffer - - may not be needed ********************************************************************** -void SpinBLEAdvertisedDevice::print() { - char logBuf[250]; - char *logBufP = logBuf; - logBufP += sprintf(logBufP, "Address: (%s)", peerAddress.toString().c_str()); - logBufP += sprintf(logBufP, " Client ID: (%d)", connectedClientID); - logBufP += sprintf(logBufP, " SerUUID: (%s)", serviceUUID.toString().c_str()); - logBufP += sprintf(logBufP, " CharUUID: (%s)", charUUID.toString().c_str()); - logBufP += sprintf(logBufP, " HRM: (%s)", isHRM ? "true" : "false"); - logBufP += sprintf(logBufP, " PM: (%s)", isPM ? "true" : "false"); - logBufP += sprintf(logBufP, " CSC: (%s)", isCSC ? "true" : "false"); - logBufP += sprintf(logBufP, " CT: (%s)", isCT ? "true" : "false"); - logBufP += sprintf(logBufP, " doConnect: (%s)", doConnect ? "true" : "false"); - strcat(logBufP, "|"); - SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s", String(logBuf)); -} - -void SpinBLEClient::connectBLE_HID(NimBLEClient *pClient) { - NimBLERemoteService *pSvc = nullptr; - NimBLERemoteCharacteristic *pChr = nullptr; - pSvc = pClient->getService(HID_SERVICE_UUID); - if (pSvc) { /** make sure it's not null */ - // This returns the HID report descriptor like this - // HID_REPORT_MAP 0x2a4b Value: 5,1,9,2,A1,1,9,1,A1,0,5,9,19,1,29,5,15,0,25,1,75,1, - // Copy and paste the value digits to http://eleccelerator.com/usbdescreqparser/ - // to see the decoded report descriptor. - /*pChr = pSvc->getCharacteristic(HID_REPORT_MAP_UUID); - if (pChr) { /** make sure it's not null */ - /* Serial.print("HID_REPORT_MAP "); - if (pChr->canRead()) { - std::string value = pChr->readValue(); - Serial.print(pChr->getUUID().toString().c_str()); - Serial.print(" Value: "); - uint8_t *p = (uint8_t *)value.data(); - for (size_t i = 0; i < value.length(); i++) { - Serial.print(p[i], HEX); - Serial.print(','); - } - Serial.println(); - } - } else { - Serial.println("HID REPORT MAP char not found."); - } -*/ - // Subscribe to characteristics HID_REPORT_DATA. - // One real device reports 2 with the same UUID but - // different handles. Using getCharacteristic() results - // in subscribing to only one. - std::vector *charVector; - charVector = pSvc->getCharacteristics(true); - for (auto &it : *charVector) { - if (it->getUUID() == NimBLEUUID(HID_REPORT_DATA_UUID)) { - Serial.println(it->toString().c_str()); - if (it->canNotify()) { - if (!it->subscribe(true, onNotify)) { - /** Disconnect if subscribe failed */ - Serial.println("subscribe notification failed"); - NimBLEDevice::deleteClient(pClient); - return; // false; - } else { - Serial.println("subscribed"); - } - } - } - } - } - Serial.println("Done with this device!"); - return; // true; -} - -void SpinBLEClient::keepAliveBLE_HID(NimBLEClient *pClient) { - static int intervalTimer = millis(); - if ((millis() - intervalTimer) < 6000) { - return; - } - NimBLERemoteService *pSvc = nullptr; - NimBLERemoteCharacteristic *pChr = nullptr; - pSvc = pClient->getService(HID_SERVICE_UUID); - if (pSvc) { /** make sure it's not null */ - pChr = pSvc->getCharacteristic(HID_REPORT_MAP_UUID); - if (pChr) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "BLE HID Keep Alive"); - pClient->setConnectionParams(12, 12, 0, 3200); - intervalTimer = millis(); - } else { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Keep Alive failed"); - } - } -} - -void SpinBLEClient::checkBLEReconnect() { - if ((String(userConfig->getConnectedHeartMonitor()) != "none") && !(spinBLEClient.connectedHRM)) { - this->doScan = true; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "No HRM Connected"); - } - if ((String(userConfig->getConnectedPowerMeter()) != "none") && !(spinBLEClient.connectedPM)) { - this->doScan = true; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "No PM Connected"); - } - if ((String(userConfig->getConnectedRemote()) != "none") && !(spinBLEClient.connectedRemote)) { - this->doScan = true; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "No Rem Connected"); - } -} - -void SpinBLEClient::reconnectAllDevices() { - for (auto i : spinBLEClient.myBLEDevices) { - if (NimBLEDevice::getClientByPeerAddress(i.peerAddress)) { - if (NimBLEDevice::getClientByPeerAddress(i.peerAddress)->isConnected()) { - NimBLEDevice::getClientByPeerAddress(i.peerAddress)->disconnect(); - i.reset(); - spinBLEClient.intentionalDisconnect++; - } - } - } -} - -// Poll BLE devices for battCharacteristic if available and read value. -void SpinBLEClient::handleBattInfo(NimBLEClient *pClient, bool updateNow = false) { - static unsigned long last_battery_update = 0; - if ((millis() - last_battery_update >= BATTERY_UPDATE_INTERVAL_MILLIS) || (last_battery_update == 0) || updateNow) { - last_battery_update = millis(); - if (pClient->getService(HEARTSERVICE_UUID) && pClient->getService(BATTERYSERVICE_UUID)) { // get battery level at first connect - BLERemoteCharacteristic *battCharacteristic = pClient->getService(BATTERYSERVICE_UUID)->getCharacteristic(BATTERYCHARACTERISTIC_UUID); - if (battCharacteristic != nullptr) { - std::string value = battCharacteristic->readValue(); - rtConfig->hr_batt.setValue((uint8_t)value[0]); - SS2K_LOG(BLE_CLIENT_LOG_TAG, "HRM battery updated %d", (int)value[0]); - } else { - rtConfig->hr_batt.setValue(0); - } - } else if ((pClient->getService(CYCLINGPOWERMEASUREMENT_UUID) || pClient->getService(CYCLINGPOWERSERVICE_UUID)) && - pClient->getService(BATTERYSERVICE_UUID)) { // get batterylevel at first connect - BLERemoteCharacteristic *battCharacteristic = pClient->getService(BATTERYSERVICE_UUID)->getCharacteristic(BATTERYCHARACTERISTIC_UUID); - if (battCharacteristic != nullptr) { - std::string value = battCharacteristic->readValue(); - rtConfig->pm_batt.setValue((uint8_t)value[0]); - SS2K_LOG(BLE_CLIENT_LOG_TAG, "PM battery updated %d", (int)value[0]); - } else { - rtConfig->pm_batt.setValue(0); - } - } - } -} -// Returns a device name with the las two of the peer address attached. This lets us distinguish between multiple devices with the same device name. -String SpinBLEClient::adevName2UniqueName(NimBLEAdvertisedDevice *inDev) { - if (inDev->haveName()) { - String _outDevName = String(inDev->getName().c_str()); - // add the last two of the string - _outDevName += +" " + String(inDev->getAddress().toString().c_str()).substring(inDev->getAddress().toString().length() - 2); - return _outDevName; - } else { - String _outDevName = inDev->getAddress().toString().c_str(); - return _outDevName; - } -} - -void SpinBLEAdvertisedDevice::set(BLEAdvertisedDevice *device, int id, BLEUUID inServiceUUID, BLEUUID inCharUUID) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Setting Device %s", device->getAddress().toString().c_str()); - this->advertisedDevice = device; - this->peerAddress = device->getAddress(); - this->connectedClientID = id; - this->serviceUUID = BLEUUID(inServiceUUID); - this->charUUID = BLEUUID(inCharUUID); - this->dataBufferQueue = xQueueCreate(4, sizeof(NotifyData)); - if (inServiceUUID == HEARTSERVICE_UUID) { - this->isHRM = true; - spinBLEClient.connectedHRM = true; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered HRM on Connect"); - } else if (inServiceUUID == CSCSERVICE_UUID) { - this->isCSC = true; - spinBLEClient.connectedCD = true; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered CSC on Connect"); - } else if (inServiceUUID == CYCLINGPOWERSERVICE_UUID || inServiceUUID == FITNESSMACHINESERVICE_UUID || inServiceUUID == FLYWHEEL_UART_SERVICE_UUID || - inServiceUUID == ECHELON_SERVICE_UUID || inServiceUUID == PELOTON_DATA_UUID) { - this->isPM = true; - spinBLEClient.connectedPM = true; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered PM on Connect"); - } else if (inServiceUUID == HID_SERVICE_UUID) { - this->isRemote = true; - spinBLEClient.connectedRemote = true; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered Remote on Connect"); - } else { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to set service!"); - } -} - -void SpinBLEAdvertisedDevice::reset() { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Resetting Device: %d", this->connectedClientID); - if (this->isHRM) spinBLEClient.connectedHRM = false; - if (this->isPM) spinBLEClient.connectedPM = false; - if (this->isCSC) spinBLEClient.connectedCD = false; - spinBLEClient.connectedSpeed = false; - advertisedDevice = nullptr; - // NimBLEAddress peerAddress; - this->connectedClientID = BLE_HS_CONN_HANDLE_NONE; - this->serviceUUID = (uint16_t)0x0000; - this->charUUID = (uint16_t)0x0000; - this->isHRM = false; // Heart Rate Monitor - this->isPM = false; // Power Meter - this->isCSC = false; // Cycling Speed/Cadence - this->isCT = false; // Controllable Trainer - this->isRemote = false; // BLE Remote - this->doConnect = false; // Initiate connection flag - this->isPostConnected = false; // Has Post Connect Been Run? - if (this->dataBufferQueue != nullptr) { - // Serial.println("Resetting queue"); - xQueueReset(this->dataBufferQueue); - } -} diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index dceb78ea..1172bd60 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -202,7 +202,7 @@ bool SpinBLEClient::connectToServer() { NimBLEUUID charUUID; int successful = 0; - const NimBLEAdvertisedDevice *myDevice; + const NimBLEAdvertisedDevice *myDevice = nullptr; int device_number = -1; for (int i = 0; i < NUM_BLE_DEVICES; i++) { @@ -500,7 +500,6 @@ void SpinBLEClient::scanProcess(int duration) { if (pBLEScan->isScanning()) { return; } - pBLEScan->clearResults(); pBLEScan->start(duration, false, true); this->dontBlockScan = false; } @@ -546,7 +545,7 @@ void ScanCallbacks::onScanEnd(const NimBLEScanResults &results, int reason) { String output; serializeJson(devices, output); - // SS2K_LOG(BLE_CLIENT_LOG_TAG, "Bluetooth Client Found Devices: %s", output.c_str()); + //SS2K_LOG(BLE_CLIENT_LOG_TAG, "Found Devices: %s", output.c_str()); #ifdef USE_TELEGRAM SEND_TO_TELEGRAM("Bluetooth Client Found Devices: " + output); #endif diff --git a/src/BLE_Custom_Characteristic.cpp b/src/BLE_Custom_Characteristic.cpp index 41499910..1d1ce9df 100644 --- a/src/BLE_Custom_Characteristic.cpp +++ b/src/BLE_Custom_Characteristic.cpp @@ -100,16 +100,29 @@ void BLE_ss2kCustomCharacteristic::setupService(NimBLEServer *pServer) { void BLE_ss2kCustomCharacteristic::update() {} -void ss2kCustomCharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) { +void ss2kCustomCharacteristicCallbacks::onWrite(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo) { std::string rxValue = pCharacteristic->getValue(); - //SS2K_LOG(CUSTOM_CHAR_LOG_TAG, "Write from %s", connInfo.getAddress().toString().c_str()); + // SS2K_LOG(CUSTOM_CHAR_LOG_TAG, "Write from %s", connInfo.getAddress().toString().c_str()); BLE_ss2kCustomCharacteristic::process(rxValue); } -void ss2kCustomCharacteristicCallbacks::onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) { +void ss2kCustomCharacteristicCallbacks::onSubscribe(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo, uint16_t subValue) { SS2K_LOG(CUSTOM_CHAR_LOG_TAG, "Subscribe from %s", connInfo.getAddress().toString().c_str()); NimBLEDevice::setMTU(515); } +void ss2kCustomCharacteristicCallbacks::onStatus(NimBLECharacteristic *pCharacteristic, int code) { +// loop through and accumulate the data into a C++ string +#ifdef CUSTOM_CHAR_DEBUG + std::string characteristicValue = pCharacteristic->getValue(); + std::string logValue; + for (size_t i = 0; i < characteristicValue.length(); ++i) { + char buf[4]; + snprintf(buf, sizeof(buf), "%02x ", (unsigned char)characteristicValue[i]); + logValue += buf; + } + SS2K_LOG(CUSTOM_CHAR_LOG_TAG, "%s -> %s", pCharacteristic->getUUID().toString().c_str(), logValue.c_str()); +#endif +} void BLE_ss2kCustomCharacteristic::notify(char _item, int tableRow) { // regular non power table update @@ -677,12 +690,12 @@ void BLE_ss2kCustomCharacteristic::process(std::string rxValue) { returnValue[0] = cc_success; if (rxValue[2] >= 0 || rxValue[2] < POWERTABLE_CAD_SIZE) { for (int i = 0; i < POWERTABLE_WATT_SIZE; i++) { - powerTable->tableRow[rxValue[2]].tableEntry[i].targetPosition = (int16_t((uint8_t)(rxValue[i*2 + 3]) << 0 | (uint8_t)(rxValue[i*2 + 4]) << 8)); + powerTable->tableRow[rxValue[2]].tableEntry[i].targetPosition = (int16_t((uint8_t)(rxValue[i * 2 + 3]) << 0 | (uint8_t)(rxValue[i * 2 + 4]) << 8)); } - powerTable->saveFlag = true; + powerTable->saveFlag = true; } else { - //SS2K_LOG(CUSTOM_CHAR_LOG_TAG, "Table row invalid"); - // Logging causes crashes in ISR + // SS2K_LOG(CUSTOM_CHAR_LOG_TAG, "Table row invalid"); + // Logging causes crashes in ISR } } break; diff --git a/src/BLE_Fitness_Machine_Service.cpp b/src/BLE_Fitness_Machine_Service.cpp index a062f4e5..93f16316 100644 --- a/src/BLE_Fitness_Machine_Service.cpp +++ b/src/BLE_Fitness_Machine_Service.cpp @@ -19,8 +19,6 @@ BLE_Fitness_Machine_Service::BLE_Fitness_Machine_Service() fitnessMachineInclinationRange(nullptr), fitnessMachineTrainingStatus(nullptr) {} -uint8_t ftmsTrainingStatus[2] = {0x00, 0x00}; // Initialize to Other state - void BLE_Fitness_Machine_Service::setupService(NimBLEServer *pServer, MyCharacteristicCallbacks *chrCallbacks) { // Resistance, IPower, HeartRate uint8_t ftmsResistanceLevelRange[6] = {0x01, 0x00, 0x64, 0x00, 0x01, 0x00}; // 1:100 increment 1 @@ -113,9 +111,10 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { if (rxValue == "") { return; } - uint8_t returnValue[3] = {FitnessMachineControlPointProcedure::ResponseCode, (uint8_t)rxValue[0], FitnessMachineControlPointResultCode::OpCodeNotSupported}; + std::vector returnValue = {FitnessMachineControlPointProcedure::ResponseCode, (uint8_t)rxValue[0], FitnessMachineControlPointResultCode::OpCodeNotSupported}; BLECharacteristic *pCharacteristic = NimBLEDevice::getServer()->getServiceByUUID(FITNESSMACHINESERVICE_UUID)->getCharacteristic(FITNESSMACHINECONTROLPOINT_UUID); std::vector ftmsStatus = {FitnessMachineStatus::ReservedForFutureUse}; + std::vector ftmsTrainingStatus = {0x00, FitnessMachineTrainingStatus::Other}; if (rxValue.length() >= 1) { uint8_t *pData = reinterpret_cast(&rxValue[0]); @@ -268,26 +267,9 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { ftmsStatus = {FitnessMachineStatus::StartedOrResumedByUser}; ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x00; } - fitnessMachineStatusCharacteristic->setValue(ftmsStatus.data(), ftmsStatus.size()); - //SS2K_LOG(FMTS_SERVER_LOG_TAG, "Calling notify %s -> %02x %02x", fitnessMachineStatusCharacteristic->getUUID().toString().c_str(), ftmsStatus[0], ftmsStatus[1]); - std::string characteristicValue = pCharacteristic->getValue(); - std::string logValue; - for (size_t i = 0; i < characteristicValue.length(); ++i) { - char buf[4]; - snprintf(buf, sizeof(buf), "%02x ", (unsigned char)characteristicValue[i]); - logValue += buf; - } - SS2K_LOG(FMTS_SERVER_LOG_TAG, "Calling notify %s -> %s", pCharacteristic->getUUID().toString().c_str(), logValue.c_str()); - fitnessMachineControlPoint->setValue(returnValue, 3); - fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); - fitnessMachineControlPoint->indicate(); - /* only notify if the value has changed - static uint8_t _lastTrainingStatus[2] = {0x00, 0x00}; - if (memcmp(_lastTrainingStatus, ftmsTrainingStatus, 2) != 0) { - memcpy(_lastTrainingStatus, ftmsTrainingStatus, 2); - fitnessMachineTrainingStatus->notify(); - } */ - fitnessMachineStatusCharacteristic->notify(); + fitnessMachineControlPoint->indicate(returnValue.data(), returnValue.size()); + fitnessMachineTrainingStatus->notify(ftmsTrainingStatus.data(), ftmsTrainingStatus.size()); + fitnessMachineStatusCharacteristic->notify(ftmsStatus.data(), ftmsStatus.size()); } } diff --git a/src/BLE_Server.cpp b/src/BLE_Server.cpp index fb26da00..8c162674 100644 --- a/src/BLE_Server.cpp +++ b/src/BLE_Server.cpp @@ -194,7 +194,7 @@ void MyCharacteristicCallbacks::onStatus(NimBLECharacteristic* pCharacteristic, logValue += buf; } - SS2K_LOGW(BLE_SERVER_LOG_TAG, "Notification/Indication status code: %d for char: %s Data: %s", code, pCharacteristic->getUUID().toString().c_str(), logValue.c_str()); + //SS2K_LOG(BLE_SERVER_LOG_TAG, "%s -> %s", pCharacteristic->getUUID().toString().c_str(), logValue.c_str()); } void MyCharacteristicCallbacks::onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) { From 244f362fe6ad297a81452b19f5654b27db035af1 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Mon, 17 Feb 2025 18:01:20 -0600 Subject: [PATCH 064/451] implemented new fillTable function and changed TABLE_DIVISOR to 10 --- include/settings.h | 6 +- src/Power_Table.cpp | 339 ++++++++++++++------------------------------ 2 files changed, 112 insertions(+), 233 deletions(-) diff --git a/include/settings.h b/include/settings.h index 26d74fd7..f8f95185 100644 --- a/include/settings.h +++ b/include/settings.h @@ -303,7 +303,11 @@ const char* const DEFAULT_PASSWORD = "password"; #define MINIMUM_RELIABLE_POSITIONS 3 // Limit power table size to save memory -#define TABLE_DIVISOR 100.0 +#define TABLE_DIVISOR 10.0 + +#define VERTICAL_NEIGHBOR_DIVISOR 150 + +#define HORIZONTAL_NEIGHBOR_DIVISON 300 // Temperature of the ESP32 at which to start reducing the power output of the stepper motor driver. #define THROTTLE_TEMP 90 diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 4c4811ad..1df9d4e2 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -54,8 +54,8 @@ void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, int totalStep = ((rtConfig->getMaxStep() - rtConfig->getMaxStep() / 2000000)); // stepper distance is 400,000,000 so dividing it by 2,000,000 gives us 200 calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range } else if (rtConfig->getHomed()) { - int totalStep = (rtConfig->getMaxStep() / TABLE_DIVISOR); // maxStep should be around 22000 / TABLE_DIVISOR gives us 200ish - calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range + int totalStep = (rtConfig->getMaxStep() / TABLE_DIVISOR); // maxStep should be around 22000 / TABLE_DIVISOR gives us 2000ish + calcStep = totalStep * 0.05; // 5% of that would give us around a 100 positive and negative range } if (powerBuffer.powerEntry[0].readings == 0) { // we need to make sure stepper position is not negative so it only takes positive resistance values @@ -345,10 +345,30 @@ TestResults PowerTable::testNeighbors(int i, int j, int testValue) { return returnResult; } +int lagrangeCalculation(const std::vector& xVals, const std::vector& yVals, int x) { + int n = xVals.size(); + float result = 0.0f; // Use float to prevent integer truncation + + for (int i = 0; i < n; ++i) { + float term = (float)yVals[i]; // Make sure yValues are treated correctly as floats + + for (int j = 0; j < n; ++j) { + if (i != j) { + term *= (x - xVals[j]) / (float)(xVals[i] - xVals[j]); + } + } + + result += term; + } + + return static_cast(result); // Convert result back to int +} + + void PowerTable::fillTable() { int tempValue = INT16_MIN; - // Fill each empty cell by linear interpolation + // Fill each empty cell by Lagrange interpolation for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { // Interpolate horizontally for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { @@ -360,9 +380,15 @@ void PowerTable::fillTable() { while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear interpolation - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) * (j - left) / (right - left); + // Prepare X and Y values for Lagrange interpolation + std::vector xValues = {this->tableRow[i].tableEntry[left].targetPosition, this->tableRow[i].tableEntry[right].targetPosition}; + std::vector yValues = {left, right}; // We use the column indices as X values + + // Perform Lagrange interpolation + tempValue = lagrangeCalculation(xValues, yValues, j); + SS2K_LOG(POWERTABLE_LOG_TAG, "Horizontal Interpolation Lagrange Calc: (%d)", tempValue); + + // Test the neighbors to check if the interpolation result is valid if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } @@ -382,9 +408,15 @@ void PowerTable::fillTable() { while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { - // Linear interpolation - tempValue = this->tableRow[top].tableEntry[j].targetPosition + - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) * (i - top) / (bottom - top); + // Prepare X and Y values for Lagrange interpolation + std::vector xValues = {this->tableRow[top].tableEntry[j].targetPosition, this->tableRow[bottom].tableEntry[j].targetPosition}; + std::vector yValues = {top, bottom}; // We use the row indices as X values + + // Perform Lagrange interpolation + tempValue = lagrangeCalculation(xValues, yValues, i); + SS2K_LOG(POWERTABLE_LOG_TAG, "Vertical Interpolation Lagrange Calc: (%d)", tempValue); + + // Test the neighbors to check if the interpolation result is valid if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } @@ -398,193 +430,63 @@ void PowerTable::extrapFillTable() { // Find the center of the known data int sumRow = 0, sumCol = 0, count = 0; for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - sumRow += i; - sumCol += j; - count++; + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + sumRow += i; + sumCol += j; + count++; + } } - } } // prevent divide by zero if (count == 0) { - return; + return; } int centerRow = sumRow / count; int centerCol = sumCol / count; - int tempValue = INT16_MIN; - // Function to extrapolate a single cell based on its neighbors + // Function to extrapolate a single cell using Lagrange polynomial auto extrapolateCell = [&](int i, int j) { - // Find nearest left non-empty cell - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - - // Find nearest right non-empty cell - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear extrapolation - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - if (j < left) { - // Extrapolate to the left - tempValue = this->tableRow[i].tableEntry[left].targetPosition - - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } else if (j > right) { - // Extrapolate to the right - tempValue = this->tableRow[i].tableEntry[right].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } + std::vector xVals, yVals; + + // Collect known values to the left and right of the point + int left = j - 1; + while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + + int right = j + 1; + while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + + // Collect points for extrapolation + if (left >= 0) { + xVals.push_back(left); + yVals.push_back(this->tableRow[i].tableEntry[left].targetPosition); } - } else if (left - 1 >= 0) { - // Only left value available, extrapolate to the right - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + if (right < POWERTABLE_WATT_SIZE) { + xVals.push_back(right); + yVals.push_back(this->tableRow[i].tableEntry[right].targetPosition); } - } else if (right + 1 < POWERTABLE_WATT_SIZE) { - // Only right value available, extrapolate to the left - if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - tempValue = - this->tableRow[i].tableEntry[right].targetPosition - - (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + + if (xVals.size() > 1) { + // Use Lagrange extrapolation for this cell + int tempValue = lagrangeCalculation(xVals, yVals, j); + SS2K_LOG(POWERTABLE_LOG_TAG, "Exrapolation lagrange calc: (%d)", tempValue); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } } - } }; // Extrapolate horizontally and vertically starting from the center for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { - for (int i = centerRow - distance; i <= centerRow + distance; ++i) { - for (int j = centerCol - distance; j <= centerCol + distance; ++j) { - if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - extrapolateCell(i, j); - } - } - } - } - // Extrapolate each empty cell - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - // Extrapolate horizontally - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest left non-empty cell - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - - // Find nearest right non-empty cell - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear extrapolation - if (j < left) { - // Extrapolate to the left - tempValue = this->tableRow[i].tableEntry[left].targetPosition - - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - - } else if (j > right) { - // Extrapolate to the right - tempValue = this->tableRow[i].tableEntry[right].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (left >= 1) { - // Only left value available, extrapolate to the right - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + for (int i = centerRow - distance; i <= centerRow + distance; ++i) { + for (int j = centerCol - distance; j <= centerCol + distance; ++j) { + if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + extrapolateCell(i, j); } - } - } else if (right + 1 < POWERTABLE_WATT_SIZE) { - // Only right value available, extrapolate to the left - if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[right].targetPosition - - (right - j) * - (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } - } - } - } - - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - // Extrapolate vertically - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top non-empty cell - int top = i - 1; - while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; - - // Find nearest bottom non-empty cell - int bottom = i + 1; - while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; - - if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { - // Linear extrapolation - if (i < top) { - // Extrapolate upwards - tempValue = this->tableRow[top].tableEntry[j].targetPosition - - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } else if (i > bottom) { - // Extrapolate downwards - tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (top >= 1) { - // Only top value available, extrapolate downwards - if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { - tempValue = this->tableRow[top].tableEntry[j].targetPosition + - (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } else { - } - } - } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { - // Only bottom value available, extrapolate upwards - if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { - tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - - (bottom - i) * - (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } } - } } - } } } @@ -592,65 +494,38 @@ void PowerTable::extrapolateDiagonal() { int tempValue = INT16_MIN; for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top-left non-empty cell - int topLeftRow = i - 1, topLeftCol = j - 1; - while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { - topLeftRow--; - topLeftCol--; - } - - // Find nearest bottom-right non-empty cell - int bottomRightRow = i + 1, bottomRightCol = j + 1; - while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && - this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { - bottomRightRow++; - bottomRightCol++; - } - - // Perform diagonal extrapolation (top-left to bottom-right) - if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { - tempValue = - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + - ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / - (bottomRightCol - topLeftCol); - - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest top-left and bottom-right non-empty cells + int topLeftRow = i - 1, topLeftCol = j - 1; + while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { + topLeftRow--; + topLeftCol--; + } - // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left - if (tempValue == INT16_MIN) { - // Find nearest top-right non-empty cell - int topRightRow = i - 1, topRightCol = j + 1; - while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { - topRightRow--; - topRightCol++; - } + int bottomRightRow = i + 1, bottomRightCol = j + 1; + while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && + this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { + bottomRightRow++; + bottomRightCol++; + } - // Find nearest bottom-left non-empty cell - int bottomLeftRow = i + 1, bottomLeftCol = j - 1; - while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { - bottomLeftRow++; - bottomLeftCol--; - } + // Perform diagonal Lagrange extrapolation (top-left to bottom-right) + if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { + std::vector xVals = {topLeftCol, bottomRightCol}; + std::vector yVals = { + this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition, + this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition + }; - // Perform diagonal extrapolation (top-right to bottom-left) - if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { - tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + - ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * - (j - bottomLeftCol)) / - (topRightCol - bottomLeftCol); + tempValue = lagrangeCalculation(xVals, yVals, j); - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } } - } } - } } } @@ -762,7 +637,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { // test which bit fields didn't match if (!testResults.leftNeighbor.passedTest) { if (testResults.leftNeighbor.i == k && - (testResults.leftNeighbor.targetPosition <= targetPosition + 30 && + (testResults.leftNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_DIVISON && testResults.leftNeighbor.targetPosition >= targetPosition)) { // check if the cadence is the same and positions are within a set range in this case its 30. SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and targetPosition is within range"); @@ -804,7 +679,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } if (!testResults.rightNeighbor.passedTest) { - if (testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition - 30 && testResults.rightNeighbor.targetPosition <= targetPosition)) { + if (testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_DIVISOR && testResults.rightNeighbor.targetPosition <= targetPosition)) { int avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); int count = 0; @@ -842,7 +717,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } if (!testResults.topNeighbor.passedTest) { - if (testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition - 30 && testResults.topNeighbor.targetPosition <= targetPosition)) { + if (testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_DIVISOR && testResults.topNeighbor.targetPosition <= targetPosition)) { int avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); int count = 0; @@ -879,7 +754,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } if (!testResults.bottomNeighbor.passedTest) { - if (testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition + 30 && testResults.bottomNeighbor.targetPosition >= targetPosition)) { + if (testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_DIVISON && testResults.bottomNeighbor.targetPosition >= targetPosition)) { int avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); int count = 0; From 7cdc41d916eaa67590be42d46e688d546ac055bf Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Mon, 17 Feb 2025 19:55:46 -0600 Subject: [PATCH 065/451] workaround for onDisconnect() not getting called --- src/BLE_Client.cpp | 15 ++++++++------- src/BLE_Common.cpp | 9 ++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index 1172bd60..57ff00ce 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -201,14 +201,15 @@ bool SpinBLEClient::connectToServer() { NimBLEUUID serviceUUID; NimBLEUUID charUUID; - int successful = 0; + int successful = 0; const NimBLEAdvertisedDevice *myDevice = nullptr; - int device_number = -1; + int device_number = -1; for (int i = 0; i < NUM_BLE_DEVICES; i++) { if (spinBLEClient.myBLEDevices[i].doConnect == true) { // Client wants to be connected if (spinBLEClient.myBLEDevices[i].advertisedDevice) { // Client is assigned - myDevice = spinBLEClient.myBLEDevices[i].advertisedDevice; + myDevice = spinBLEClient.myBLEDevices[i].advertisedDevice; + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Connecting slot %d", i); device_number = i; break; } else { @@ -448,7 +449,7 @@ void ScanCallbacks::onResult(const NimBLEAdvertisedDevice *advertisedDevice) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s%s%s", THIS, REMOTE, DIDNT_MATCH_THE_SAVED, userConfig->getConnectedRemote()); return; // Ignore this device; } else { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s %s%s", REMOTE, NAME, MATCHED, aDevName); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s %s%s%s", REMOTE, NAME, MATCHED, aDevName.c_str()); } } } else if (advertisedDevice->getServiceUUID() == HEARTSERVICE_UUID) { @@ -461,7 +462,7 @@ void ScanCallbacks::onResult(const NimBLEAdvertisedDevice *advertisedDevice) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s%s%s", THIS, HRM, DIDNT_MATCH_THE_SAVED, userConfig->getConnectedHeartMonitor()); return; // Ignore this device; } else { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s %s%s", HRM, NAME, MATCHED, aDevName); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s %s%s%s", HRM, NAME, MATCHED, aDevName.c_str()); } } } else { @@ -474,7 +475,7 @@ void ScanCallbacks::onResult(const NimBLEAdvertisedDevice *advertisedDevice) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s%s%s", THIS, PM, DIDNT_MATCH_THE_SAVED, userConfig->getConnectedPowerMeter()); return; // Ignore this device; } else { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s %s%s", PM, NAME, MATCHED, aDevName); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s %s%s%s", PM, NAME, MATCHED, aDevName.c_str()); } } } @@ -545,7 +546,7 @@ void ScanCallbacks::onScanEnd(const NimBLEScanResults &results, int reason) { String output; serializeJson(devices, output); - //SS2K_LOG(BLE_CLIENT_LOG_TAG, "Found Devices: %s", output.c_str()); + // SS2K_LOG(BLE_CLIENT_LOG_TAG, "Found Devices: %s", output.c_str()); #ifdef USE_TELEGRAM SEND_TO_TELEGRAM("Bluetooth Client Found Devices: " + output); #endif diff --git a/src/BLE_Common.cpp b/src/BLE_Common.cpp index e3c25369..83f4cdbe 100644 --- a/src/BLE_Common.cpp +++ b/src/BLE_Common.cpp @@ -76,11 +76,10 @@ void BLECommunications() { spinBLEClient.handleBattInfo(pClient, false); } - } else if (!pClient->isConnected()) { // This shouldn't ever be - // called... - SS2K_LOG(BLE_COMMON_LOG_TAG, "Workaround connect"); - _BLEd.doConnect = true; - //} + } else if (!pClient->isConnected()) { // This is a workaround for a bug in NimBLE where onDisconnect() is not called automatically. + MyClientCallback workaroundCallback; + workaroundCallback.onDisconnect(pClient, 0); + SS2K_LOG(BLE_COMMON_LOG_TAG, "Client %s not connected in communications loop", _BLEd.peerAddress.toString().c_str()); } } } From 01a75ae9cfa136fdeb5ce0e14c3d740f6d167b2a Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 19 Feb 2025 14:39:30 -0800 Subject: [PATCH 066/451] HRM data now updates correctly from multiple sensors --- include/BLE_Fitness_Machine_Service.h | 3 +- include/BLE_Heart_Service.h | 7 +-- include/settings.h | 2 +- src/BLE_Fitness_Machine_Service.cpp | 76 ++++++++++++++++----------- src/BLE_Heart_Service.cpp | 27 ++++++++-- src/SensorCollector.cpp | 19 +++++-- 6 files changed, 90 insertions(+), 44 deletions(-) diff --git a/include/BLE_Fitness_Machine_Service.h b/include/BLE_Fitness_Machine_Service.h index 386ff7e9..8fa14814 100644 --- a/include/BLE_Fitness_Machine_Service.h +++ b/include/BLE_Fitness_Machine_Service.h @@ -27,8 +27,7 @@ class BLE_Fitness_Machine_Service { BLECharacteristic *fitnessMachinePowerRange; BLECharacteristic *fitnessMachineInclinationRange; BLECharacteristic *fitnessMachineTrainingStatus; - uint8_t ftmsIndoorBikeData[11] = {0}; void processFTMSWrite(); }; -extern BLE_Fitness_Machine_Service fitnessMachineService; \ No newline at end of file +extern BLE_Fitness_Machine_Service fitnessMachineService; diff --git a/include/BLE_Heart_Service.h b/include/BLE_Heart_Service.h index 49755e7e..c6f21186 100644 --- a/include/BLE_Heart_Service.h +++ b/include/BLE_Heart_Service.h @@ -15,8 +15,9 @@ class BLE_Heart_Service { BLE_Heart_Service(); void setupService(NimBLEServer *pServer, MyCharacteristicCallbacks *chrCallbacks); void update(); + void deinit(); private: -BLEService *pHeartService; -BLECharacteristic *heartRateMeasurementCharacteristic; -}; \ No newline at end of file + NimBLEService *pHeartService; + NimBLECharacteristic *heartRateMeasurementCharacteristic; +}; diff --git a/include/settings.h b/include/settings.h index b688dc4b..04fed84f 100644 --- a/include/settings.h +++ b/include/settings.h @@ -351,7 +351,7 @@ const char* const DEFAULT_PASSWORD = "password"; // #define DEBUG_TORQUETABLE // Uncomment to enable BLE_TX_RX Logging -// #define DEBUG_BLE_TX_RX +#define DEBUG_BLE_TX_RX // UNcomment to enable Custom Characteristic Logging // #define CUSTOM_CHAR_DEBUG diff --git a/src/BLE_Fitness_Machine_Service.cpp b/src/BLE_Fitness_Machine_Service.cpp index 93f16316..5925ae90 100644 --- a/src/BLE_Fitness_Machine_Service.cpp +++ b/src/BLE_Fitness_Machine_Service.cpp @@ -7,6 +7,7 @@ #include "BLE_Fitness_Machine_Service.h" #include +#include BLE_Fitness_Machine_Service::BLE_Fitness_Machine_Service() : pFitnessMachineService(nullptr), @@ -32,10 +33,6 @@ void BLE_Fitness_Machine_Service::setupService(NimBLEServer *pServer, MyCharacte FitnessMachineTargetFlags::Types::ResistanceTargetSettingSupported | FitnessMachineTargetFlags::Types::IndoorBikeSimulationParametersSupported | FitnessMachineTargetFlags::Types::SpinDownControlSupported}; - // Fitness Machine Indoor Bike Data Flags Setup - FitnessMachineIndoorBikeDataFlags::Types ftmsIBDFlags = FitnessMachineIndoorBikeDataFlags::InstantaneousCadencePresent | - FitnessMachineIndoorBikeDataFlags::ResistanceLevelPresent | FitnessMachineIndoorBikeDataFlags::InstantaneousPowerPresent | - FitnessMachineIndoorBikeDataFlags::HeartRatePresent; // Fitness Machine service setup pFitnessMachineService = spinBLEServer.pServer->createService(FITNESSMACHINESERVICE_UUID); @@ -49,9 +46,7 @@ void BLE_Fitness_Machine_Service::setupService(NimBLEServer *pServer, MyCharacte fitnessMachineTrainingStatus = pFitnessMachineService->createCharacteristic(FITNESSMACHINETRAININGSTATUS_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); fitnessMachineFeature->setValue(ftmsFeature.bytes, sizeof(ftmsFeature)); - ftmsIndoorBikeData[0] = static_cast(ftmsIBDFlags & 0xFF); // LSB, mask with 0xFF to get the lower 8 bits - ftmsIndoorBikeData[1] = static_cast((ftmsIBDFlags >> 8) & 0xFF); // MSB, shift right by 8 bits and mask with 0xFF - fitnessMachineIndoorBikeData->setValue(ftmsIndoorBikeData, sizeof(ftmsIndoorBikeData)); + fitnessMachineResistanceLevelRange->setValue(ftmsResistanceLevelRange, sizeof(ftmsResistanceLevelRange)); fitnessMachinePowerRange->setValue(ftmsPowerRange, sizeof(ftmsPowerRange)); fitnessMachineInclinationRange->setValue(ftmsInclinationRange, sizeof(ftmsInclinationRange)); @@ -62,15 +57,11 @@ void BLE_Fitness_Machine_Service::setupService(NimBLEServer *pServer, MyCharacte } void BLE_Fitness_Machine_Service::update() { + std::vector ftmsIndoorBikeData; + this->processFTMSWrite(); - /*if (!spinBLEServer.clientSubscribed.IndoorBikeData) { - return; - }*/ - float cadRaw = rtConfig->cad.getValue(); - int cad = static_cast(cadRaw * 2); - int watts = rtConfig->watts.getValue(); - int hr = rtConfig->hr.getValue(); - int res = rtConfig->resistance.getValue(); + + // Calculate Speed for FTMS int speedFtmsUnit = 0; if (rtConfig->getSimulatedSpeed() > 5) { speedFtmsUnit = rtConfig->getSimulatedSpeed() * 100; @@ -78,29 +69,50 @@ void BLE_Fitness_Machine_Service::update() { speedFtmsUnit = spinBLEServer.calculateSpeed() * 100; } - ftmsIndoorBikeData[2] = (uint8_t)(speedFtmsUnit & 0xff); - ftmsIndoorBikeData[3] = (uint8_t)(speedFtmsUnit >> 8); + // Rebuild ftmsIndoorBikeData vector with current values + ftmsIndoorBikeData.clear(); + + // Fitness Machine Indoor Bike Data Flags Setup + FitnessMachineIndoorBikeDataFlags::Types ftmsIBDFlags = FitnessMachineIndoorBikeDataFlags::InstantaneousCadencePresent | + FitnessMachineIndoorBikeDataFlags::ResistanceLevelPresent | FitnessMachineIndoorBikeDataFlags::InstantaneousPowerPresent; + + if (String(userConfig->getConnectedHeartMonitor()) != "none") { + ftmsIBDFlags = ftmsIBDFlags | FitnessMachineIndoorBikeDataFlags::HeartRatePresent; + } + + // Add flags + ftmsIndoorBikeData.push_back(static_cast(ftmsIBDFlags & 0xFF)); + ftmsIndoorBikeData.push_back(static_cast((ftmsIBDFlags >> 8) & 0xFF)); + + // Add speed + ftmsIndoorBikeData.push_back(static_cast(speedFtmsUnit & 0xff)); + ftmsIndoorBikeData.push_back(static_cast(speedFtmsUnit >> 8)); - ftmsIndoorBikeData[4] = (uint8_t)(cad & 0xff); - ftmsIndoorBikeData[5] = (uint8_t)(cad >> 8); + // Add cadence. FTMS expects cadence in 0.5 RPM units + ftmsIndoorBikeData.push_back(static_cast(static_cast(rtConfig->cad.getValue() * 2) & 0xff)); + ftmsIndoorBikeData.push_back(static_cast(static_cast(rtConfig->cad.getValue() * 2) >> 8)); - ftmsIndoorBikeData[6] = (uint8_t)(res & 0xff); - ftmsIndoorBikeData[7] = (uint8_t)(res >> 8); + // Add resistance + ftmsIndoorBikeData.push_back(static_cast(rtConfig->resistance.getValue() & 0xff)); + ftmsIndoorBikeData.push_back(static_cast(rtConfig->resistance.getValue() >> 8)); - ftmsIndoorBikeData[8] = (uint8_t)(watts & 0xff); - ftmsIndoorBikeData[9] = (uint8_t)(watts >> 8); + // Add power + ftmsIndoorBikeData.push_back(static_cast(rtConfig->watts.getValue() & 0xff)); + ftmsIndoorBikeData.push_back(static_cast(rtConfig->watts.getValue() >> 8)); - ftmsIndoorBikeData[10] = (uint8_t)hr; + // Add heart rate if HRM is connected + if (String(userConfig->getConnectedHeartMonitor()) != "none") { + ftmsIndoorBikeData.push_back(static_cast(rtConfig->hr.getValue())); + } - fitnessMachineIndoorBikeData->setValue(ftmsIndoorBikeData, sizeof(ftmsIndoorBikeData)); - fitnessMachineIndoorBikeData->notify(); + fitnessMachineIndoorBikeData->notify(ftmsIndoorBikeData.data(), ftmsIndoorBikeData.size()); const int kLogBufCapacity = 200; // Data(30), Sep(data/2), Arrow(3), CharId(37), Sep(3), CharId(37), Sep(3), Name(10), Prefix(2), HR(7), SEP(1), CD(10), SEP(1), PW(8), // SEP(1), SD(7), Suffix(2), Nul(1), rounded up char logBuf[kLogBufCapacity]; - const size_t ftmsIndoorBikeDataLength = sizeof(ftmsIndoorBikeData) / sizeof(ftmsIndoorBikeData[0]); - logCharacteristic(logBuf, kLogBufCapacity, ftmsIndoorBikeData, ftmsIndoorBikeDataLength, FITNESSMACHINESERVICE_UUID, fitnessMachineIndoorBikeData->getUUID(), - "FTMS(IBD)[ HR(%d) CD(%.2f) PW(%d) SD(%.2f) ]", hr % 1000, fmodf(cadRaw, 1000.0), watts % 10000, fmodf((float)speedFtmsUnit / 100.0, 1000.0)); + logCharacteristic(logBuf, kLogBufCapacity, ftmsIndoorBikeData.data(), ftmsIndoorBikeData.size(), FITNESSMACHINESERVICE_UUID, fitnessMachineIndoorBikeData->getUUID(), + "FTMS(IBD)[ HR(%d) CD(%.2f) PW(%d) SD(%.2f) ]", rtConfig->hr.getValue() % 1000, fmodf(rtConfig->cad.getValue(), 1000.0), rtConfig->watts.getValue() % 10000, + fmodf((float)speedFtmsUnit / 100.0, 1000.0)); } // The things that happen when we receive a FitnessMachineControlPointProcedure from a Client. @@ -111,9 +123,9 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { if (rxValue == "") { return; } - std::vector returnValue = {FitnessMachineControlPointProcedure::ResponseCode, (uint8_t)rxValue[0], FitnessMachineControlPointResultCode::OpCodeNotSupported}; - BLECharacteristic *pCharacteristic = NimBLEDevice::getServer()->getServiceByUUID(FITNESSMACHINESERVICE_UUID)->getCharacteristic(FITNESSMACHINECONTROLPOINT_UUID); - std::vector ftmsStatus = {FitnessMachineStatus::ReservedForFutureUse}; + std::vector returnValue = {FitnessMachineControlPointProcedure::ResponseCode, (uint8_t)rxValue[0], FitnessMachineControlPointResultCode::OpCodeNotSupported}; + BLECharacteristic *pCharacteristic = NimBLEDevice::getServer()->getServiceByUUID(FITNESSMACHINESERVICE_UUID)->getCharacteristic(FITNESSMACHINECONTROLPOINT_UUID); + std::vector ftmsStatus = {FitnessMachineStatus::ReservedForFutureUse}; std::vector ftmsTrainingStatus = {0x00, FitnessMachineTrainingStatus::Other}; if (rxValue.length() >= 1) { diff --git a/src/BLE_Heart_Service.cpp b/src/BLE_Heart_Service.cpp index 0cf1afbc..d159707f 100644 --- a/src/BLE_Heart_Service.cpp +++ b/src/BLE_Heart_Service.cpp @@ -18,13 +18,34 @@ void BLE_Heart_Service::setupService(NimBLEServer *pServer, MyCharacteristicCall heartRateMeasurementCharacteristic->setValue(heartRateMeasurement, 2); heartRateMeasurementCharacteristic->setCallbacks(chrCallbacks); pHeartService->start(); - //spinBLEServer.pServer->getAdvertising()->addServiceUUID(pHeartService->getUUID()); +} + +void BLE_Heart_Service::deinit() { + if (pHeartService != nullptr) { + if (heartRateMeasurementCharacteristic != nullptr) { + pHeartService->removeCharacteristic(heartRateMeasurementCharacteristic); + heartRateMeasurementCharacteristic = nullptr; + } + spinBLEServer.pServer->removeService(pHeartService); + pHeartService = nullptr; + spinBLEServer.pServer->getAdvertising()->stop(); + SS2K_LOG(BLE_COMMON_LOG_TAG, "Heart Rate Service De-initialized"); + } } void BLE_Heart_Service::update() { - /*if (!spinBLEServer.clientSubscribed.Heartrate) { + /* Check if heart rate monitor is connected + if (String(userConfig->getConnectedHeartMonitor()) == "none") { + deinit(); return; + } + + if (!pHeartService) { + // Re-initialize if needed, most likely after changing HRM from none to a specific device + MyCharacteristicCallbacks* chrCallbacks; + setupService(spinBLEServer.pServer, chrCallbacks); }*/ + byte heartRateMeasurement[2] = {0x00, (byte)rtConfig->hr.getValue()}; heartRateMeasurementCharacteristic->setValue(heartRateMeasurement, 2); heartRateMeasurementCharacteristic->notify(); @@ -34,4 +55,4 @@ void BLE_Heart_Service::update() { const size_t heartRateMeasurementLength = sizeof(heartRateMeasurement) / sizeof(heartRateMeasurement[0]); logCharacteristic(logBuf, kLogBufCapacity, heartRateMeasurement, heartRateMeasurementLength, HEARTSERVICE_UUID, heartRateMeasurementCharacteristic->getUUID(), "HRS(HRM)[ HR(%d) ]", rtConfig->hr.getValue() % 1000); -} \ No newline at end of file +} diff --git a/src/SensorCollector.cpp b/src/SensorCollector.cpp index 1efbe7db..54d1771e 100644 --- a/src/SensorCollector.cpp +++ b/src/SensorCollector.cpp @@ -27,9 +27,22 @@ void collectAndSet(NimBLEUUID charUUID, NimBLEUUID serviceUUID, NimBLEAddress ad logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " | %s[", sensorData->getId().c_str()); if (sensorData->hasHeartRate() && !rtConfig->hr.getSimulate()) { int heartRate = sensorData->getHeartRate(); - rtConfig->hr.setValue(heartRate); - spinBLEClient.connectedHRM = true; - logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " HR(%d)", heartRate % 1000); + static int zeroCount = 0; + zeroCount++; + if (heartRate > 0) { + rtConfig->hr.setValue(heartRate); + logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " HR(%d)", heartRate % 1000); + spinBLEClient.connectedHRM = true; + zeroCount = 0; + }else{ + //require 10 readings in a row before setting the HR to 0 + if (zeroCount > 10){ + rtConfig->hr.setValue(0); + logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " HR IGNORED", 0); + spinBLEClient.connectedHRM = false; + zeroCount = 0; + } + } } if (sensorData->hasCadence() && !rtConfig->cad.getSimulate()) { From 561a395ccb14cce438543a5667a09603cfa7ee16 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 19 Feb 2025 14:41:14 -0800 Subject: [PATCH 067/451] logging update --- src/SensorCollector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SensorCollector.cpp b/src/SensorCollector.cpp index 54d1771e..3cf686aa 100644 --- a/src/SensorCollector.cpp +++ b/src/SensorCollector.cpp @@ -36,9 +36,9 @@ void collectAndSet(NimBLEUUID charUUID, NimBLEUUID serviceUUID, NimBLEAddress ad zeroCount = 0; }else{ //require 10 readings in a row before setting the HR to 0 + logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " HR IGNORED"); if (zeroCount > 10){ rtConfig->hr.setValue(0); - logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " HR IGNORED", 0); spinBLEClient.connectedHRM = false; zeroCount = 0; } From e8e793e14a14423709fc4275adcbced09476f7ab Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Wed, 19 Feb 2025 16:50:49 -0600 Subject: [PATCH 068/451] added horiz and vert range and constraint for moving failed neighbor with readings --- include/settings.h | 6 +++ src/Power_Table.cpp | 123 ++++++++++++++++++++++++++++---------------- 2 files changed, 84 insertions(+), 45 deletions(-) diff --git a/include/settings.h b/include/settings.h index b688dc4b..d0102ca5 100644 --- a/include/settings.h +++ b/include/settings.h @@ -305,6 +305,12 @@ const char* const DEFAULT_PASSWORD = "password"; // Limit power table size to save memory #define TABLE_DIVISOR 100.0 +//Max distance a failed neighbor can be horizontally from target position +#define HORIZONTAL_NEIGHBOR_RANGE 20 + +//Max distance a failed neighbr can be vertically from target position +#define VERTICAL_NEIGHBOR_RANGE 10 + // Temperature of the ESP32 at which to start reducing the power output of the stepper motor driver. #define THROTTLE_TEMP 90 diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 4c4811ad..a181df26 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -762,24 +762,30 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { // test which bit fields didn't match if (!testResults.leftNeighbor.passedTest) { if (testResults.leftNeighbor.i == k && - (testResults.leftNeighbor.targetPosition <= targetPosition + 30 && + (testResults.leftNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE && testResults.leftNeighbor.targetPosition >= targetPosition)) { // check if the cadence is the same and positions are within a set range in this case its 30. SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and targetPosition is within range"); int avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - int count = 0; if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) { // check if the current position moved left is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %f", targetPosition); this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); // enter the data - count++; + } else { + if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings != 0) + { + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + } } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { // checks if the avg position with the current watts and cadence is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); this->enterData(k, i, avgPosition); // enter the data - count++; + } else { + if(this->tableRow[k].tableEntry[i].readings != 0){ + this->tableRow[k].tableEntry[i].readings--; + } } if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition) @@ -787,132 +793,159 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "Left Neighbors position was valid with Right Neighbors cadence and watts! Left Neighbor Position: %d", testResults.leftNeighbor.targetPosition); this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition); - count++; + } else { + if(this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings != 0){ + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + } } - if(count==0){ - + // still downvote data if all the tests fail + if(!((this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) || + (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition).allNeighborsPassed))) + { this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); - } - } else { - this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); - } } if (!testResults.rightNeighbor.passedTest) { - if (testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition - 30 && testResults.rightNeighbor.targetPosition <= targetPosition)) { + if (testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE + && testResults.rightNeighbor.targetPosition <= targetPosition)) { int avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - int count = 0; if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved right was valid! Current position: %f", targetPosition); this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); - count++; + } else { + if(this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings != 0){ + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + } } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - this->enterData(k, i, avgPosition); - count++; + this->enterData(k, i, avgPosition); + } else { + if(this->tableRow[k].tableEntry[i].readings != 0){ + this->tableRow[k].tableEntry[i].readings--; + } } if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Right Neighbors position was valid with Left Neighbors cadence and watts! Right Neighbor Position: %d", testResults.rightNeighbor.targetPosition); this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition); - count++; + } else { + if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings != 0){ + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + } } - if(count==0){ - + // still downvote data if all the tests fail + if(!((this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) || + (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed))) + { this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); - } - } else { - this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); - } } if (!testResults.topNeighbor.passedTest) { - if (testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition - 30 && testResults.topNeighbor.targetPosition <= targetPosition)) { + if (testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE + && testResults.topNeighbor.targetPosition <= targetPosition)) { int avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - int count = 0; if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); - count++; + } else { + if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings != 0){ + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + } } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); this->enterData(k, i, avgPosition); - count++; + } else { + if(this->tableRow[k].tableEntry[i].readings != 0){ + this->tableRow[k].tableEntry[i].readings--; + } } if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Top Neighbors position was valid with Bottom Neighbors cadence and watts! Top Neighbor Position: %d", testResults.topNeighbor.targetPosition); this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); - count++; + } else { + if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings != 0){ + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + } } - if(count==0){ - + // still downvote data if all the tests fail + if(!((this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) || + (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed))) + { this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); - } } else { - this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); - } } if (!testResults.bottomNeighbor.passedTest) { - if (testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition + 30 && testResults.bottomNeighbor.targetPosition >= targetPosition)) { + if (testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE && + testResults.bottomNeighbor.targetPosition >= targetPosition)) { int avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - int count = 0; if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); - count++; + } else { + if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings != 0){ + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + } } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); this->enterData(k, i, avgPosition); - count++; + } else { + if(this->tableRow[k].tableEntry[i].readings != 0){ + this->tableRow[k].tableEntry[i].readings--; + } } if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom Neighbors position was valid with Top Neighbors cadence and watts! Bottom Neighbor Position: %d", testResults.topNeighbor.targetPosition); this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition); - count++; + } else { + if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings != 0){ + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + } } - if(count==0){ - + // still downvote data if all the tests fail + if(!((this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) || + (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed))) + { this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); - } - } else { - this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); - } } return; @@ -963,7 +996,7 @@ void PowerTable::downVoteData(int i, int j, float target, int neighbor){ penalty = 0; } this->tableRow[i].tableEntry[j].readings -= penalty; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", i, j, + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed (%d)(%d)(%d), readings (%d)", i, j, neighbor, this->tableRow[i].tableEntry[j].readings); } From 62fe573a9c9d691c3457c08081ab2e7d8dae52f0 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Thu, 20 Feb 2025 18:36:31 -0600 Subject: [PATCH 069/451] commented out neighbor constraint and fixed enterData function. WIP --- src/Power_Table.cpp | 169 +++++++++++++++++++++++++------------------- 1 file changed, 98 insertions(+), 71 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index a181df26..26395d6d 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -772,32 +772,35 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) { // check if the current position moved left is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %f", targetPosition); this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); // enter the data - } else { - if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings != 0) - { - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - } - } + } + // else { + // if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings != 0) + // { + // this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + // } + // } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { // checks if the avg position with the current watts and cadence is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); this->enterData(k, i, avgPosition); // enter the data - } else { - if(this->tableRow[k].tableEntry[i].readings != 0){ - this->tableRow[k].tableEntry[i].readings--; - } - } + } + // else { + // if(this->tableRow[k].tableEntry[i].readings != 0){ + // this->tableRow[k].tableEntry[i].readings--; + // } + // } if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition) .allNeighborsPassed) { // checks if the failed nighbor is valid with the right neighbors cadence and watts SS2K_LOG(POWERTABLE_LOG_TAG, "Left Neighbors position was valid with Right Neighbors cadence and watts! Left Neighbor Position: %d", testResults.leftNeighbor.targetPosition); this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition); - } else { - if(this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings != 0){ - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - } - } + } + // else { + // if(this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings != 0){ + // this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + // } + // } // still downvote data if all the tests fail if(!((this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) || @@ -820,30 +823,33 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved right was valid! Current position: %f", targetPosition); this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); - } else { - if(this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings != 0){ - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - } - } + } + // else { + // if(this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings != 0){ + // this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + // } + // } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); this->enterData(k, i, avgPosition); - } else { - if(this->tableRow[k].tableEntry[i].readings != 0){ - this->tableRow[k].tableEntry[i].readings--; - } - } + } + // else { + // if(this->tableRow[k].tableEntry[i].readings != 0){ + // this->tableRow[k].tableEntry[i].readings--; + // } + // } if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Right Neighbors position was valid with Left Neighbors cadence and watts! Right Neighbor Position: %d", testResults.rightNeighbor.targetPosition); this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition); - } else { - if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings != 0){ - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - } - } + } + // else { + // if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings != 0){ + // this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + // } + // } // still downvote data if all the tests fail if(!((this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) || @@ -866,30 +872,33 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); - } else { - if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings != 0){ - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - } - } + } + // else { + // if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings != 0){ + // this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + // } + // } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); this->enterData(k, i, avgPosition); - } else { - if(this->tableRow[k].tableEntry[i].readings != 0){ - this->tableRow[k].tableEntry[i].readings--; - } } + // else { + // if(this->tableRow[k].tableEntry[i].readings != 0){ + // this->tableRow[k].tableEntry[i].readings--; + // } + // } if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Top Neighbors position was valid with Bottom Neighbors cadence and watts! Top Neighbor Position: %d", testResults.topNeighbor.targetPosition); this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); - } else { - if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings != 0){ - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - } } + // else { + // if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings != 0){ + // this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + // } + // } // still downvote data if all the tests fail if(!((this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) || @@ -912,30 +921,33 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); - } else { - if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings != 0){ - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - } - } + } + // else { + // if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings != 0){ + // this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + // } + // } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); this->enterData(k, i, avgPosition); - } else { - if(this->tableRow[k].tableEntry[i].readings != 0){ - this->tableRow[k].tableEntry[i].readings--; - } - } + } + // else { + // if(this->tableRow[k].tableEntry[i].readings != 0){ + // this->tableRow[k].tableEntry[i].readings--; + // } + // } if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom Neighbors position was valid with Top Neighbors cadence and watts! Bottom Neighbor Position: %d", testResults.topNeighbor.targetPosition); this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition); - } else { - if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings != 0){ - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - } - } + } + // else { + // if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings != 0){ + // this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + // } + // } // still downvote data if all the tests fail if(!((this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) || @@ -950,22 +962,24 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } return; } + this->enterData(k, i, (int)targetPosition); + //this->tableRow[k].tableEntry[i].readings++; // Attempt to fill the table with calculated data... - if (this->getNumEntries() > 4) { - int entries = 0; - int newEntries = 1; - // loop until we can't calculate any new data - while (entries < newEntries) { - entries = newEntries; - this->fillTable(); - this->extrapFillTable(); - this->extrapolateDiagonal(); - newEntries = getNumEntries(); - } - } + // if (this->getNumEntries() > 4) { + // int entries = 0; + // int newEntries = 1; + // // loop until we can't calculate any new data + // while (entries < newEntries) { + // entries = newEntries; + // this->fillTable(); + // this->extrapFillTable(); + // this->extrapolateDiagonal(); + // newEntries = getNumEntries(); + // } + // } // Notify connected client of new data BLE_ss2kCustomCharacteristic::notify(0x27, k); } @@ -984,6 +998,19 @@ void PowerTable::enterData(int i, int j, int pos) { } } this->tableRow[i].tableEntry[j].readings++; + + if (this->getNumEntries() > 4) { + int entries = 0; + int newEntries = 1; + // loop until we can't calculate any new data + while (entries < newEntries) { + entries = newEntries; + this->fillTable(); + this->extrapFillTable(); + this->extrapolateDiagonal(); + newEntries = getNumEntries(); + } + } } void PowerTable::downVoteData(int i, int j, float target, int neighbor){ From e2676674fa64e3366e19e81fb41b915518b4a07d Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Thu, 20 Feb 2025 17:09:45 -0800 Subject: [PATCH 070/451] comment spelling fix --- include/settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/settings.h b/include/settings.h index fea64790..8ac974ad 100644 --- a/include/settings.h +++ b/include/settings.h @@ -308,7 +308,7 @@ const char* const DEFAULT_PASSWORD = "password"; //Max distance a failed neighbor can be horizontally from target position #define HORIZONTAL_NEIGHBOR_RANGE 20 -//Max distance a failed neighbr can be vertically from target position +//Max distance a failed neighbor can be vertically from target position #define VERTICAL_NEIGHBOR_RANGE 10 // Temperature of the ESP32 at which to start reducing the power output of the stepper motor driver. From 08d4b262de20a349711446044625fea7ca596cb0 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Thu, 20 Feb 2025 17:20:48 -0800 Subject: [PATCH 071/451] powertable logging toggle --- include/settings.h | 6 +++--- src/Power_Table.cpp | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/settings.h b/include/settings.h index 8ac974ad..ebed625e 100644 --- a/include/settings.h +++ b/include/settings.h @@ -353,11 +353,11 @@ const char* const DEFAULT_PASSWORD = "password"; // Calculation. Never sets userConfig->setSimulatedPower(); // #define DEBUG_HR_TO_PWR -// Uncomment to enable HR->PWR enhanced torquetable debugging. -// #define DEBUG_TORQUETABLE +// Uncomment to enable power table logging. +#define DEBUG_POWERTABLE // Uncomment to enable BLE_TX_RX Logging -#define DEBUG_BLE_TX_RX +// #define DEBUG_BLE_TX_RX // UNcomment to enable Custom Characteristic Logging // #define CUSTOM_CHAR_DEBUG diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 26395d6d..47d5611d 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -1305,6 +1305,7 @@ bool PowerTable::reset() { } void PowerTable::toLog() { + #ifdef DEBUG_POWERTABLE int maxLen = 4; // Find the longest integer to dynamically size the table for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { @@ -1342,6 +1343,7 @@ void PowerTable::toLog() { } SS2K_LOG(POWERTABLE_LOG_TAG, "%s", logString.c_str()); } + #endif } int PowerTable::getNumReadings() { From 9ec11c8f828127da8cd1e4c858d7409fe4552a29 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Thu, 20 Feb 2025 21:24:24 -0600 Subject: [PATCH 072/451] went back to old fill functions and caught up with testing --- include/settings.h | 8 +- src/BLE_Client.cpp | 2 +- src/Power_Table.cpp | 574 ++++++++++++++++++++++++++++++-------------- 3 files changed, 398 insertions(+), 186 deletions(-) diff --git a/include/settings.h b/include/settings.h index f8f95185..e627a3ed 100644 --- a/include/settings.h +++ b/include/settings.h @@ -303,11 +303,13 @@ const char* const DEFAULT_PASSWORD = "password"; #define MINIMUM_RELIABLE_POSITIONS 3 // Limit power table size to save memory -#define TABLE_DIVISOR 10.0 +#define TABLE_DIVISOR 100.0 -#define VERTICAL_NEIGHBOR_DIVISOR 150 +//Max distance a failed neighbor can be horizontally from target position +#define HORIZONTAL_NEIGHBOR_RANGE 20 -#define HORIZONTAL_NEIGHBOR_DIVISON 300 +//Max distance a failed neighbr can be vertically from target position +#define VERTICAL_NEIGHBOR_RANGE 10 // Temperature of the ESP32 at which to start reducing the power output of the stepper motor driver. #define THROTTLE_TEMP 90 diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index dceb78ea..a5153eb7 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -420,7 +420,7 @@ void MyClientCallback::onAuthenticationComplete(NimBLEConnInfo &connInfo) { * - If the device does not match the user configuration, it ignores the device. */ void ScanCallbacks::onResult(const NimBLEAdvertisedDevice *advertisedDevice) { - Serial.printf("Advertised Device found: %s\n", advertisedDevice->toString().c_str()); + //Serial.printf("Advertised Device found: %s\n", advertisedDevice->toString().c_str()); // Define granular constants for maximal reuse during logging const char *const MATCHED = "Matched "; const char *const DIDNT_MATCH_THE_SAVED = " didn't match the saved: "; diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 1df9d4e2..68ced8fc 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -345,30 +345,10 @@ TestResults PowerTable::testNeighbors(int i, int j, int testValue) { return returnResult; } -int lagrangeCalculation(const std::vector& xVals, const std::vector& yVals, int x) { - int n = xVals.size(); - float result = 0.0f; // Use float to prevent integer truncation - - for (int i = 0; i < n; ++i) { - float term = (float)yVals[i]; // Make sure yValues are treated correctly as floats - - for (int j = 0; j < n; ++j) { - if (i != j) { - term *= (x - xVals[j]) / (float)(xVals[i] - xVals[j]); - } - } - - result += term; - } - - return static_cast(result); // Convert result back to int -} - - void PowerTable::fillTable() { int tempValue = INT16_MIN; - // Fill each empty cell by Lagrange interpolation + // Fill each empty cell by linear interpolation for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { // Interpolate horizontally for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { @@ -380,15 +360,9 @@ void PowerTable::fillTable() { while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Prepare X and Y values for Lagrange interpolation - std::vector xValues = {this->tableRow[i].tableEntry[left].targetPosition, this->tableRow[i].tableEntry[right].targetPosition}; - std::vector yValues = {left, right}; // We use the column indices as X values - - // Perform Lagrange interpolation - tempValue = lagrangeCalculation(xValues, yValues, j); - SS2K_LOG(POWERTABLE_LOG_TAG, "Horizontal Interpolation Lagrange Calc: (%d)", tempValue); - - // Test the neighbors to check if the interpolation result is valid + // Linear interpolation + tempValue = this->tableRow[i].tableEntry[left].targetPosition + + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) * (j - left) / (right - left); if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } @@ -408,15 +382,9 @@ void PowerTable::fillTable() { while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { - // Prepare X and Y values for Lagrange interpolation - std::vector xValues = {this->tableRow[top].tableEntry[j].targetPosition, this->tableRow[bottom].tableEntry[j].targetPosition}; - std::vector yValues = {top, bottom}; // We use the row indices as X values - - // Perform Lagrange interpolation - tempValue = lagrangeCalculation(xValues, yValues, i); - SS2K_LOG(POWERTABLE_LOG_TAG, "Vertical Interpolation Lagrange Calc: (%d)", tempValue); - - // Test the neighbors to check if the interpolation result is valid + // Linear interpolation + tempValue = this->tableRow[top].tableEntry[j].targetPosition + + (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) * (i - top) / (bottom - top); if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } @@ -430,63 +398,193 @@ void PowerTable::extrapFillTable() { // Find the center of the known data int sumRow = 0, sumCol = 0, count = 0; for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - sumRow += i; - sumCol += j; - count++; - } + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + sumRow += i; + sumCol += j; + count++; } + } } // prevent divide by zero if (count == 0) { - return; + return; } int centerRow = sumRow / count; int centerCol = sumCol / count; + int tempValue = INT16_MIN; - // Function to extrapolate a single cell using Lagrange polynomial + // Function to extrapolate a single cell based on its neighbors auto extrapolateCell = [&](int i, int j) { - std::vector xVals, yVals; - - // Collect known values to the left and right of the point - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - - // Collect points for extrapolation - if (left >= 0) { - xVals.push_back(left); - yVals.push_back(this->tableRow[i].tableEntry[left].targetPosition); - } - if (right < POWERTABLE_WATT_SIZE) { - xVals.push_back(right); - yVals.push_back(this->tableRow[i].tableEntry[right].targetPosition); - } - - if (xVals.size() > 1) { - // Use Lagrange extrapolation for this cell - int tempValue = lagrangeCalculation(xVals, yVals, j); - SS2K_LOG(POWERTABLE_LOG_TAG, "Exrapolation lagrange calc: (%d)", tempValue); + // Find nearest left non-empty cell + int left = j - 1; + while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + + // Find nearest right non-empty cell + int right = j + 1; + while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + + if (left >= 0 && right < POWERTABLE_WATT_SIZE) { + // Linear extrapolation + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + if (j < left) { + // Extrapolate to the left + tempValue = this->tableRow[i].tableEntry[left].targetPosition - + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } + } else if (j > right) { + // Extrapolate to the right + tempValue = this->tableRow[i].tableEntry[right].targetPosition + + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } else if (left - 1 >= 0) { + // Only left value available, extrapolate to the right + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { + tempValue = this->tableRow[i].tableEntry[left].targetPosition + + (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } } + } else if (right + 1 < POWERTABLE_WATT_SIZE) { + // Only right value available, extrapolate to the left + if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + tempValue = + this->tableRow[i].tableEntry[right].targetPosition - + (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } }; // Extrapolate horizontally and vertically starting from the center for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { - for (int i = centerRow - distance; i <= centerRow + distance; ++i) { - for (int j = centerCol - distance; j <= centerCol + distance; ++j) { - if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - extrapolateCell(i, j); + for (int i = centerRow - distance; i <= centerRow + distance; ++i) { + for (int j = centerCol - distance; j <= centerCol + distance; ++j) { + if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + extrapolateCell(i, j); + } + } + } + } + // Extrapolate each empty cell + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + // Extrapolate horizontally + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest left non-empty cell + int left = j - 1; + while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + + // Find nearest right non-empty cell + int right = j + 1; + while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + if (left >= 0 && right < POWERTABLE_WATT_SIZE) { + // Linear extrapolation + if (j < left) { + // Extrapolate to the left + tempValue = this->tableRow[i].tableEntry[left].targetPosition - + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + + } else if (j > right) { + // Extrapolate to the right + tempValue = this->tableRow[i].tableEntry[right].targetPosition + + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (left >= 1) { + // Only left value available, extrapolate to the right + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { + tempValue = this->tableRow[i].tableEntry[left].targetPosition + + (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (right + 1 < POWERTABLE_WATT_SIZE) { + // Only right value available, extrapolate to the left + if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { + tempValue = this->tableRow[i].tableEntry[right].targetPosition - + (right - j) * + (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } + } } + } } + } + } + + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + // Extrapolate vertically + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest top non-empty cell + int top = i - 1; + while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; + + // Find nearest bottom non-empty cell + int bottom = i + 1; + while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; + + if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { + // Linear extrapolation + if (i < top) { + // Extrapolate upwards + tempValue = this->tableRow[top].tableEntry[j].targetPosition - + (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } else if (i > bottom) { + // Extrapolate downwards + tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + + (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (top >= 1) { + // Only top value available, extrapolate downwards + if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { + tempValue = this->tableRow[top].tableEntry[j].targetPosition + + (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } else { + } + } + } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { + // Only bottom value available, extrapolate upwards + if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { + tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - + (bottom - i) * + (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } + } } } @@ -494,38 +592,65 @@ void PowerTable::extrapolateDiagonal() { int tempValue = INT16_MIN; for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top-left and bottom-right non-empty cells - int topLeftRow = i - 1, topLeftCol = j - 1; - while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { - topLeftRow--; - topLeftCol--; - } + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest top-left non-empty cell + int topLeftRow = i - 1, topLeftCol = j - 1; + while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { + topLeftRow--; + topLeftCol--; + } - int bottomRightRow = i + 1, bottomRightCol = j + 1; - while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && - this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { - bottomRightRow++; - bottomRightCol++; - } + // Find nearest bottom-right non-empty cell + int bottomRightRow = i + 1, bottomRightCol = j + 1; + while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && + this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { + bottomRightRow++; + bottomRightCol++; + } - // Perform diagonal Lagrange extrapolation (top-left to bottom-right) - if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { - std::vector xVals = {topLeftCol, bottomRightCol}; - std::vector yVals = { - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition, - this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - }; + // Perform diagonal extrapolation (top-left to bottom-right) + if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { + tempValue = + this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + + ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / + (bottomRightCol - topLeftCol); - tempValue = lagrangeCalculation(xVals, yVals, j); + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } + // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left + if (tempValue == INT16_MIN) { + // Find nearest top-right non-empty cell + int topRightRow = i - 1, topRightCol = j + 1; + while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { + topRightRow--; + topRightCol++; + } + + // Find nearest bottom-left non-empty cell + int bottomLeftRow = i + 1, bottomLeftCol = j - 1; + while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { + bottomLeftRow++; + bottomLeftCol--; } + + // Perform diagonal extrapolation (top-right to bottom-left) + if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { + tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + + ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * + (j - bottomLeftCol)) / + (topRightCol - bottomLeftCol); + + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } } + } } } @@ -637,177 +762,249 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { // test which bit fields didn't match if (!testResults.leftNeighbor.passedTest) { if (testResults.leftNeighbor.i == k && - (testResults.leftNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_DIVISON && + (testResults.leftNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE && testResults.leftNeighbor.targetPosition >= targetPosition)) { // check if the cadence is the same and positions are within a set range in this case its 30. SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and targetPosition is within range"); int avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - int count = 0; if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) { // check if the current position moved left is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %f", targetPosition); - this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); // enter the data - count++; - } + if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings < 10){ + this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); // enter the data + } + } + // else { + // if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings != 0) + // { + // this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + // } + // } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { // checks if the avg position with the current watts and cadence is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - this->enterData(k, i, avgPosition); // enter the data - count++; - } + if(this->tableRow[k].tableEntry[i].readings < 10){ + this->enterData(k, i, avgPosition); + } + } + // else { + // if(this->tableRow[k].tableEntry[i].readings != 0){ + // this->tableRow[k].tableEntry[i].readings--; + // } + // } if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition) .allNeighborsPassed) { // checks if the failed nighbor is valid with the right neighbors cadence and watts SS2K_LOG(POWERTABLE_LOG_TAG, "Left Neighbors position was valid with Right Neighbors cadence and watts! Left Neighbor Position: %d", testResults.leftNeighbor.targetPosition); - this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition); - count++; - } - - if(count==0){ - + if(this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings < 10){ + this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition); + } + + } + // else { + // if(this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings != 0){ + // this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + // } + // } + + // still downvote data if all the tests fail + if(!((this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) || + (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition).allNeighborsPassed))) + { this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); - } - } else { - this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); - } } if (!testResults.rightNeighbor.passedTest) { - if (testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_DIVISOR && testResults.rightNeighbor.targetPosition <= targetPosition)) { + if (testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE + && testResults.rightNeighbor.targetPosition <= targetPosition)) { int avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - int count = 0; if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved right was valid! Current position: %f", targetPosition); - this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); - count++; - } + if(this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings < 10){ + this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); + } + } + // else { + // if(this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings != 0){ + // this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + // } + // } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - this->enterData(k, i, avgPosition); - count++; - } + if(this->tableRow[k].tableEntry[i].readings < 10){ + this->enterData(k, i, avgPosition); + } + } + // else { + // if(this->tableRow[k].tableEntry[i].readings != 0){ + // this->tableRow[k].tableEntry[i].readings--; + // } + // } if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Right Neighbors position was valid with Left Neighbors cadence and watts! Right Neighbor Position: %d", testResults.rightNeighbor.targetPosition); - this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition); - count++; - } + if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings < 10){ + this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition); + } + } + // else { + // if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings != 0){ + // this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + // } + // } - if(count==0){ - + // still downvote data if all the tests fail + if(!((this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) || + (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed))) + { this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); - } - } else { - this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); - } } if (!testResults.topNeighbor.passedTest) { - if (testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_DIVISOR && testResults.topNeighbor.targetPosition <= targetPosition)) { + if (testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE + && testResults.topNeighbor.targetPosition <= targetPosition)) { int avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - int count = 0; if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); - this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); - count++; - } + if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings < 10){ + this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); + } + } + // else { + // if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings != 0){ + // this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + // } + // } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - this->enterData(k, i, avgPosition); - count++; + if(this->tableRow[k].tableEntry[i].readings < 10){ + this->enterData(k, i, avgPosition); + } } + // else { + // if(this->tableRow[k].tableEntry[i].readings != 0){ + // this->tableRow[k].tableEntry[i].readings--; + // } + // } if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Top Neighbors position was valid with Bottom Neighbors cadence and watts! Top Neighbor Position: %d", testResults.topNeighbor.targetPosition); - this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); - count++; + if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings < 10){ + this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); + } } - - if(count==0){ - + // else { + // if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings != 0){ + // this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + // } + // } + + // still downvote data if all the tests fail + if(!((this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) || + (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed))) + { this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); - } } else { - this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); - } } if (!testResults.bottomNeighbor.passedTest) { - if (testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_DIVISON && testResults.bottomNeighbor.targetPosition >= targetPosition)) { + if (testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE && + testResults.bottomNeighbor.targetPosition >= targetPosition)) { int avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - int count = 0; if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); - this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); - count++; - } + if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings < 10){ + this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); + } + } + // else { + // if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings != 0){ + // this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + // } + // } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - this->enterData(k, i, avgPosition); - count++; - } + if(this->tableRow[k].tableEntry[i].readings < 10){ + this->enterData(k, i, avgPosition); + } + } + // else { + // if(this->tableRow[k].tableEntry[i].readings != 0){ + // this->tableRow[k].tableEntry[i].readings--; + // } + // } if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom Neighbors position was valid with Top Neighbors cadence and watts! Bottom Neighbor Position: %d", testResults.topNeighbor.targetPosition); - this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition); - count++; - } - - if(count==0){ - + if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings < 10){ + this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition); + } + } + // else { + // if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings != 0){ + // this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + // } + // } + + // still downvote data if all the tests fail + if(!((this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) || + (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed))) + { this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); - } - } else { - this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); - } } return; } + this->enterData(k, i, (int)targetPosition); + //this->tableRow[k].tableEntry[i].readings++; // Attempt to fill the table with calculated data... - if (this->getNumEntries() > 4) { - int entries = 0; - int newEntries = 1; - // loop until we can't calculate any new data - while (entries < newEntries) { - entries = newEntries; - this->fillTable(); - this->extrapFillTable(); - this->extrapolateDiagonal(); - newEntries = getNumEntries(); - } - } + // if (this->getNumEntries() > 4) { + // int entries = 0; + // int newEntries = 1; + // // loop until we can't calculate any new data + // while (entries < newEntries) { + // entries = newEntries; + // this->fillTable(); + // this->extrapFillTable(); + // this->extrapolateDiagonal(); + // newEntries = getNumEntries(); + // } + // } // Notify connected client of new data BLE_ss2kCustomCharacteristic::notify(0x27, k); } @@ -826,6 +1023,19 @@ void PowerTable::enterData(int i, int j, int pos) { } } this->tableRow[i].tableEntry[j].readings++; + + if (this->getNumEntries() > 4) { + int entries = 0; + int newEntries = 1; + // loop until we can't calculate any new data + while (entries < newEntries) { + entries = newEntries; + this->fillTable(); + this->extrapFillTable(); + this->extrapolateDiagonal(); + newEntries = getNumEntries(); + } + } } void PowerTable::downVoteData(int i, int j, float target, int neighbor){ @@ -838,7 +1048,7 @@ void PowerTable::downVoteData(int i, int j, float target, int neighbor){ penalty = 0; } this->tableRow[i].tableEntry[j].readings -= penalty; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed Bottom (%d)(%d)(%d), readings (%d)", i, j, + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed (%d)(%d)(%d), readings (%d)", i, j, neighbor, this->tableRow[i].tableEntry[j].readings); } From 25eefd68482f62ba38799660dfd8d9313d203d11 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Fri, 21 Feb 2025 16:37:25 -0600 Subject: [PATCH 073/451] added logging for clear and reset. --- src/Power_Table.cpp | 99 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 82 insertions(+), 17 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 68ced8fc..ca563942 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -24,6 +24,7 @@ void PowerBuffer::set(int i) { } void PowerBuffer::reset() { + SS2K_LOG(POWERTABLE_LOG_TAG, "Power Table Reset"); for (int i = 0; i < POWER_SAMPLES; i++) { this->powerEntry[i].readings = 0; this->powerEntry[i].cad = 0; @@ -667,6 +668,7 @@ int PowerTable::getNumEntries() { } void PowerTable::clean() { + SS2K_LOG(POWERTABLE_LOG_TAG, "Clean Power Table"); int ret = 0; for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { @@ -764,15 +766,18 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (testResults.leftNeighbor.i == k && (testResults.leftNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE && testResults.leftNeighbor.targetPosition >= targetPosition)) { // check if the cadence is the same and positions are within a set range in this case its 30. - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and targetPosition is within range"); int avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.leftNeighbor.targetPosition, targetPosition, avgPosition); + if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) { // check if the current position moved left is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %f", targetPosition); if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings < 10){ this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); // enter the data + }else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings = 0; } } // else { @@ -786,6 +791,9 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); if(this->tableRow[k].tableEntry[i].readings < 10){ this->enterData(k, i, avgPosition); + }else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); + this->tableRow[k].tableEntry[i].readings = 0; } } // else { @@ -800,7 +808,10 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { testResults.leftNeighbor.targetPosition); if(this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings < 10){ this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition); - } + }else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings = 0; + } } // else { @@ -814,10 +825,16 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition).allNeighborsPassed))) { - this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, + testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + //this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); } } else { - this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, + testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + //this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); } } @@ -825,12 +842,16 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE && testResults.rightNeighbor.targetPosition <= targetPosition)) { int avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.rightNeighbor.targetPosition, targetPosition, avgPosition); + if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved right was valid! Current position: %f", targetPosition); if(this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings < 10){ this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); + }else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings = 0; } } // else { @@ -843,6 +864,9 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); if(this->tableRow[k].tableEntry[i].readings < 10){ this->enterData(k, i, avgPosition); + }else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); + this->tableRow[k].tableEntry[i].readings = 0; } } // else { @@ -856,7 +880,10 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { testResults.rightNeighbor.targetPosition); if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings < 10){ this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition); - } + } else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings = 0; + } } // else { // if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings != 0){ @@ -869,10 +896,16 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed))) { - this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, + testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + //this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); } } else { - this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, + testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + //this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); } } @@ -880,12 +913,16 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE && testResults.topNeighbor.targetPosition <= targetPosition)) { int avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.topNeighbor.targetPosition, targetPosition, avgPosition); + if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings < 10){ this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); + } else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings = 0; } } // else { @@ -898,6 +935,9 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); if(this->tableRow[k].tableEntry[i].readings < 10){ this->enterData(k, i, avgPosition); + } else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); + this->tableRow[k].tableEntry[i].readings = 0; } } // else { @@ -911,7 +951,10 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { testResults.topNeighbor.targetPosition); if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings < 10){ this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); - } + }else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings = 0; + } } // else { // if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings != 0){ @@ -924,10 +967,16 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed))) { - this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, + testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + //this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); } } else { - this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, + testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + //this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); } } @@ -935,12 +984,16 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE && testResults.bottomNeighbor.targetPosition >= targetPosition)) { int avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.bottomNeighbor.targetPosition, targetPosition, avgPosition); + if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings < 10){ this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); + } else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings = 0; } } // else { @@ -953,6 +1006,9 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); if(this->tableRow[k].tableEntry[i].readings < 10){ this->enterData(k, i, avgPosition); + } else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); + this->tableRow[k].tableEntry[i].readings = 0; } } // else { @@ -966,7 +1022,10 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { testResults.topNeighbor.targetPosition); if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings < 10){ this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition); - } + } else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings = 0; + } } // else { // if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings != 0){ @@ -979,10 +1038,16 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed))) { - this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed bottom (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, + testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + //this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); } } else { - this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, + testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + //this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); } } return; From 8f4c168bfe02c922d39164e3120ecc0fc77e653b Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Fri, 21 Feb 2025 16:58:53 -0600 Subject: [PATCH 074/451] took out constraints WIP --- src/Power_Table.cpp | 274 +++++++++++++++++++------------------------- 1 file changed, 116 insertions(+), 158 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index ca563942..5224b6d0 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -773,63 +773,48 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) { // check if the current position moved left is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %f", targetPosition); - if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings < 10){ this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); // enter the data - }else { - SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings = 0; - } } - // else { - // if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings != 0) - // { - // this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - // } - // } + else { + + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + + } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { // checks if the avg position with the current watts and cadence is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - if(this->tableRow[k].tableEntry[i].readings < 10){ + this->enterData(k, i, avgPosition); - }else { - SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); - this->tableRow[k].tableEntry[i].readings = 0; - } + } - // else { - // if(this->tableRow[k].tableEntry[i].readings != 0){ - // this->tableRow[k].tableEntry[i].readings--; - // } - // } + else { + + this->tableRow[k].tableEntry[i].readings--; + + } if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition) .allNeighborsPassed) { // checks if the failed nighbor is valid with the right neighbors cadence and watts SS2K_LOG(POWERTABLE_LOG_TAG, "Left Neighbors position was valid with Right Neighbors cadence and watts! Left Neighbor Position: %d", testResults.leftNeighbor.targetPosition); - if(this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings < 10){ this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition); - }else { - SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings = 0; - } - } - // else { - // if(this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings != 0){ - // this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - // } - // } + else { + + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + + } // still downvote data if all the tests fail - if(!((this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) || - (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || - (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition).allNeighborsPassed))) - { - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, - testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - //this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); - } + // if(!((this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) || + // (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + // (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition).allNeighborsPassed))) + // { + // SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, + // testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + // this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + // //this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); + // } } else { SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); @@ -847,60 +832,51 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved right was valid! Current position: %f", targetPosition); - if(this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings < 10){ + this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); - }else { - SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings = 0; - } + } - // else { - // if(this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings != 0){ - // this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - // } - // } + else { + + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + + } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - if(this->tableRow[k].tableEntry[i].readings < 10){ + this->enterData(k, i, avgPosition); - }else { - SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); - this->tableRow[k].tableEntry[i].readings = 0; - } + } - // else { - // if(this->tableRow[k].tableEntry[i].readings != 0){ - // this->tableRow[k].tableEntry[i].readings--; - // } - // } + else { + + this->tableRow[k].tableEntry[i].readings--; + + } if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Right Neighbors position was valid with Left Neighbors cadence and watts! Right Neighbor Position: %d", testResults.rightNeighbor.targetPosition); - if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings < 10){ + this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition); - } else { - SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings = 0; - } + } - // else { - // if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings != 0){ - // this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - // } - // } + else { + + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + + } // still downvote data if all the tests fail - if(!((this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) || - (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || - (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed))) - { - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, - testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - //this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); - } + // if(!((this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) || + // (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + // (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed))) + // { + // SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, + // testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + // this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + // //this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); + // } } else { SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); @@ -918,60 +894,51 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); - if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings < 10){ + this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); - } else { - SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings = 0; - } + } - // else { - // if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings != 0){ - // this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - // } - // } + else { + + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + + } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - if(this->tableRow[k].tableEntry[i].readings < 10){ + this->enterData(k, i, avgPosition); - } else { - SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); - this->tableRow[k].tableEntry[i].readings = 0; - } + + } + else { + + this->tableRow[k].tableEntry[i].readings--; + } - // else { - // if(this->tableRow[k].tableEntry[i].readings != 0){ - // this->tableRow[k].tableEntry[i].readings--; - // } - // } if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Top Neighbors position was valid with Bottom Neighbors cadence and watts! Top Neighbor Position: %d", testResults.topNeighbor.targetPosition); - if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings < 10){ + this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); - }else { - SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings = 0; - } + + } + else { + + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + } - // else { - // if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings != 0){ - // this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - // } - // } // still downvote data if all the tests fail - if(!((this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) || - (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || - (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed))) - { - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, - testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - //this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); - } + // if(!((this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) || + // (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + // (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed))) + // { + // SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, + // testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + // this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + // //this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); + // } } else { SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); @@ -989,60 +956,51 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); - if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings < 10){ + this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); - } else { - SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings = 0; - } + } - // else { - // if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings != 0){ - // this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - // } - // } + else { + + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + + } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - if(this->tableRow[k].tableEntry[i].readings < 10){ + this->enterData(k, i, avgPosition); - } else { - SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); - this->tableRow[k].tableEntry[i].readings = 0; - } + } - // else { - // if(this->tableRow[k].tableEntry[i].readings != 0){ - // this->tableRow[k].tableEntry[i].readings--; - // } - // } + else { + + this->tableRow[k].tableEntry[i].readings--; + + } if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom Neighbors position was valid with Top Neighbors cadence and watts! Bottom Neighbor Position: %d", testResults.topNeighbor.targetPosition); - if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings < 10){ + this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition); - } else { - SS2K_LOG(POWERTABLE_LOG_TAG, "Neighbor reading = 0"); - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings = 0; - } + } - // else { - // if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings != 0){ - // this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - // } - // } + else { + + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + + } // still downvote data if all the tests fail - if(!((this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) || - (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || - (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed))) - { - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed bottom (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, - testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - //this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); - } + // if(!((this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) || + // (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + // (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed))) + // { + // SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed bottom (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, + // testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + // this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + // //this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); + // } } else { SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); From 37418f5fc41f1cc05170c65b8252b245fba9d016 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Fri, 21 Feb 2025 18:48:55 -0600 Subject: [PATCH 075/451] changed failed neighbor constrain WIP --- include/settings.h | 2 +- src/Power_Table.cpp | 179 ++++++++++++++++++++++---------------------- 2 files changed, 90 insertions(+), 91 deletions(-) diff --git a/include/settings.h b/include/settings.h index e627a3ed..92c5508f 100644 --- a/include/settings.h +++ b/include/settings.h @@ -306,7 +306,7 @@ const char* const DEFAULT_PASSWORD = "password"; #define TABLE_DIVISOR 100.0 //Max distance a failed neighbor can be horizontally from target position -#define HORIZONTAL_NEIGHBOR_RANGE 20 +#define HORIZONTAL_NEIGHBOR_RANGE 30 //Max distance a failed neighbr can be vertically from target position #define VERTICAL_NEIGHBOR_RANGE 10 diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 5224b6d0..959b6f6f 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -763,9 +763,8 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { // test which bit fields didn't match if (!testResults.leftNeighbor.passedTest) { - if (testResults.leftNeighbor.i == k && - (testResults.leftNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE && - testResults.leftNeighbor.targetPosition >= targetPosition)) { // check if the cadence is the same and positions are within a set range in this case its 30. + if ((testResults.leftNeighbor.i <= k + POWERTABLE_CAD_INCREMENT && testResults.leftNeighbor.i >= k - POWERTABLE_CAD_INCREMENT) + && (testResults.leftNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE && testResults.leftNeighbor.targetPosition >= targetPosition)) { // check if the cadence is the same and positions are within a set range in this case its 30. int avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.leftNeighbor.targetPosition, targetPosition, avgPosition); @@ -775,11 +774,11 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %f", targetPosition); this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); // enter the data } - else { + // else { - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + // this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - } + // } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { // checks if the avg position with the current watts and cadence is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); @@ -787,11 +786,11 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(k, i, avgPosition); } - else { + // else { - this->tableRow[k].tableEntry[i].readings--; + // this->tableRow[k].tableEntry[i].readings--; - } + // } if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition) .allNeighborsPassed) { // checks if the failed nighbor is valid with the right neighbors cadence and watts @@ -799,24 +798,24 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { testResults.leftNeighbor.targetPosition); this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition); } - else { + // else { - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + // this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - } - - // still downvote data if all the tests fail - // if(!((this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) || - // (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || - // (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition).allNeighborsPassed))) - // { - // SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, - // testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); - // this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - // //this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); // } + + //still downvote data if all the tests fail + if(!((this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) || + (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition).allNeighborsPassed))) + { + SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, + testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + //this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); + } } else { - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, + SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; //this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); @@ -824,8 +823,8 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } if (!testResults.rightNeighbor.passedTest) { - if (testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE - && testResults.rightNeighbor.targetPosition <= targetPosition)) { + if ((testResults.rightNeighbor.i <= k + POWERTABLE_CAD_INCREMENT && testResults.rightNeighbor.i >= k - POWERTABLE_CAD_INCREMENT) && + (testResults.rightNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE && testResults.rightNeighbor.targetPosition <= targetPosition)) { int avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.rightNeighbor.targetPosition, targetPosition, avgPosition); @@ -836,11 +835,11 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); } - else { + // else { - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + // this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - } + // } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); @@ -848,11 +847,11 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(k, i, avgPosition); } - else { + // else { - this->tableRow[k].tableEntry[i].readings--; + // this->tableRow[k].tableEntry[i].readings--; - } + // } if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Right Neighbors position was valid with Left Neighbors cadence and watts! Right Neighbor Position: %d", @@ -861,24 +860,24 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition); } - else { + // else { - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + // this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - } - - // still downvote data if all the tests fail - // if(!((this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) || - // (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || - // (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed))) - // { - // SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, - // testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); - // this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - // //this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); // } + + // still downvote data if all the tests fail + if(!((this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) || + (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed))) + { + SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, + testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + //this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); + } } else { - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, + SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; //this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); @@ -886,7 +885,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } if (!testResults.topNeighbor.passedTest) { - if (testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE + if ((testResults.topNeighbor.j == i) && (testResults.topNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE && testResults.topNeighbor.targetPosition <= targetPosition)) { int avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.topNeighbor.targetPosition, targetPosition, avgPosition); @@ -898,11 +897,11 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); } - else { + // else { - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + // this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - } + // } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); @@ -910,11 +909,11 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(k, i, avgPosition); } - else { + // else { - this->tableRow[k].tableEntry[i].readings--; + // this->tableRow[k].tableEntry[i].readings--; - } + // } if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Top Neighbors position was valid with Bottom Neighbors cadence and watts! Top Neighbor Position: %d", @@ -923,24 +922,24 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); } - else { + // else { - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + // this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - } - - // still downvote data if all the tests fail - // if(!((this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) || - // (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || - // (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed))) - // { - // SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, - // testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - // this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - // //this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); // } + + //still downvote data if all the tests fail + if(!((this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) || + (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed))) + { + SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, + testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + //this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); + } } else { - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, + SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; //this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); @@ -948,7 +947,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } if (!testResults.bottomNeighbor.passedTest) { - if (testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE && + if ((testResults.bottomNeighbor.j == i) && (testResults.bottomNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE && testResults.bottomNeighbor.targetPosition >= targetPosition)) { int avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.bottomNeighbor.targetPosition, targetPosition, avgPosition); @@ -960,11 +959,11 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); } - else { + // else { - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + // this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - } + // } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); @@ -972,11 +971,11 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(k, i, avgPosition); } - else { + // else { - this->tableRow[k].tableEntry[i].readings--; + // this->tableRow[k].tableEntry[i].readings--; - } + // } if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom Neighbors position was valid with Top Neighbors cadence and watts! Bottom Neighbor Position: %d", @@ -985,24 +984,24 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition); } - else { + // else { - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + // this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - } - - // still downvote data if all the tests fail - // if(!((this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) || - // (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || - // (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed))) - // { - // SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed bottom (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, - // testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - // this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - // //this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); // } + + // still downvote data if all the tests fail + if(!((this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) || + (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed))) + { + SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed bottom (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, + testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + //this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); + } } else { - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, + SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; //this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); @@ -1053,9 +1052,9 @@ void PowerTable::enterData(int i, int j, int pos) { // loop until we can't calculate any new data while (entries < newEntries) { entries = newEntries; - this->fillTable(); - this->extrapFillTable(); - this->extrapolateDiagonal(); + // this->fillTable(); + // this->extrapFillTable(); + // this->extrapolateDiagonal(); newEntries = getNumEntries(); } } From 1b8d0aa2b1eac1fb580fe10f3ebe684f3a2933a9 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Sat, 22 Feb 2025 13:37:51 -0600 Subject: [PATCH 076/451] defeined PT reading range in settings.h and updated newEntry --- include/settings.h | 4 +++- src/Power_Table.cpp | 41 +++++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/include/settings.h b/include/settings.h index 92c5508f..2654c458 100644 --- a/include/settings.h +++ b/include/settings.h @@ -305,8 +305,10 @@ const char* const DEFAULT_PASSWORD = "password"; // Limit power table size to save memory #define TABLE_DIVISOR 100.0 +#define PT_READING_RANGE 15 + //Max distance a failed neighbor can be horizontally from target position -#define HORIZONTAL_NEIGHBOR_RANGE 30 +#define HORIZONTAL_NEIGHBOR_RANGE 60 //Max distance a failed neighbr can be vertically from target position #define VERTICAL_NEIGHBOR_RANGE 10 diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 959b6f6f..2233c7f0 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -51,21 +51,22 @@ void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, if ((cadence >= (MINIMUM_TABLE_CAD - (POWERTABLE_CAD_INCREMENT / 2))) && (cadence <= (MINIMUM_TABLE_CAD + (POWERTABLE_CAD_INCREMENT * POWERTABLE_CAD_SIZE) - (POWERTABLE_CAD_SIZE / 2))) && (watts.getValue() > 10) && // adding constraints (watts.getValue() < (POWERTABLE_WATT_SIZE * POWERTABLE_WATT_INCREMENT))) { - if (rtConfig->getMaxStep() == DEFAULT_STEPPER_TRAVEL && rtConfig->getMinStep() == -DEFAULT_STEPPER_TRAVEL) { - int totalStep = ((rtConfig->getMaxStep() - rtConfig->getMaxStep() / 2000000)); // stepper distance is 400,000,000 so dividing it by 2,000,000 gives us 200 - calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range - } else if (rtConfig->getHomed()) { - int totalStep = (rtConfig->getMaxStep() / TABLE_DIVISOR); // maxStep should be around 22000 / TABLE_DIVISOR gives us 2000ish - calcStep = totalStep * 0.05; // 5% of that would give us around a 100 positive and negative range - } + + // if (rtConfig->getMaxStep() == DEFAULT_STEPPER_TRAVEL && rtConfig->getMinStep() == -DEFAULT_STEPPER_TRAVEL) { + // int totalStep = ((rtConfig->getMaxStep() - rtConfig->getMaxStep() / 2000000)); // stepper distance is 400,000,000 so dividing it by 2,000,000 gives us 200 + // calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range + // } else if (rtConfig->getHomed()) { + // int totalStep = (rtConfig->getMaxStep() / TABLE_DIVISOR); // maxStep should be around 22000 / TABLE_DIVISOR gives us 2000ish + // calcStep = totalStep * 0.05; // 5% of that would give us around a 100 positive and negative range + // } if (powerBuffer.powerEntry[0].readings == 0) { // we need to make sure stepper position is not negative so it only takes positive resistance values // Take Initial reading powerBuffer.set(0); // Check if the current stepper posistion is within a 5% range of the previous stepper position and that the current position is not negative } - if (((ss2k->getCurrentPosition() / TABLE_DIVISOR) >= ((powerBuffer.powerEntry[0].targetPosition) - calcStep)) && - ((ss2k->getCurrentPosition() / TABLE_DIVISOR) <= ((powerBuffer.powerEntry[0].targetPosition) + calcStep))) { + if (((ss2k->getCurrentPosition() / TABLE_DIVISOR) >= ((powerBuffer.powerEntry[0].targetPosition) - PT_READING_RANGE)) && + ((ss2k->getCurrentPosition() / TABLE_DIVISOR) <= ((powerBuffer.powerEntry[0].targetPosition) + PT_READING_RANGE))) { for (int i = 1; i < POWER_SAMPLES; i++) { if (powerBuffer.powerEntry[i].readings == 0) { SS2K_LOG(POWERTABLE_LOG_TAG, "Success!"); @@ -763,8 +764,8 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { // test which bit fields didn't match if (!testResults.leftNeighbor.passedTest) { - if ((testResults.leftNeighbor.i <= k + POWERTABLE_CAD_INCREMENT && testResults.leftNeighbor.i >= k - POWERTABLE_CAD_INCREMENT) - && (testResults.leftNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE && testResults.leftNeighbor.targetPosition >= targetPosition)) { // check if the cadence is the same and positions are within a set range in this case its 30. + SS2K_LOG(POWERTABLE_LOG_TAG, "k: (%d) leftNeighbor.i: (%d)", k, testResults.leftNeighbor.i); + if (testResults.leftNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE && testResults.leftNeighbor.targetPosition >= targetPosition) { // check if the cadence is the same and positions are within a set range in this case its 30. int avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.leftNeighbor.targetPosition, targetPosition, avgPosition); @@ -823,8 +824,8 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } if (!testResults.rightNeighbor.passedTest) { - if ((testResults.rightNeighbor.i <= k + POWERTABLE_CAD_INCREMENT && testResults.rightNeighbor.i >= k - POWERTABLE_CAD_INCREMENT) && - (testResults.rightNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE && testResults.rightNeighbor.targetPosition <= targetPosition)) { + SS2K_LOG(POWERTABLE_LOG_TAG, "k: (%d) rightNeighbor.i: (%d)", k, testResults.rightNeighbor.i); + if (testResults.rightNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE && testResults.rightNeighbor.targetPosition <= targetPosition) { int avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.rightNeighbor.targetPosition, targetPosition, avgPosition); @@ -885,8 +886,8 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } if (!testResults.topNeighbor.passedTest) { - if ((testResults.topNeighbor.j == i) && (testResults.topNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE - && testResults.topNeighbor.targetPosition <= targetPosition)) { + SS2K_LOG(POWERTABLE_LOG_TAG, "i: (%d) topNeighbor.j: (%d)", i, testResults.topNeighbor.j); + if (testResults.topNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE && testResults.topNeighbor.targetPosition <= targetPosition) { int avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.topNeighbor.targetPosition, targetPosition, avgPosition); @@ -947,8 +948,8 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } if (!testResults.bottomNeighbor.passedTest) { - if ((testResults.bottomNeighbor.j == i) && (testResults.bottomNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE && - testResults.bottomNeighbor.targetPosition >= targetPosition)) { + SS2K_LOG(POWERTABLE_LOG_TAG, "i: (%d) bottomNeighbor.j: (%d)", i, testResults.bottomNeighbor.j); + if (testResults.bottomNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE && testResults.bottomNeighbor.targetPosition >= targetPosition) { int avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.bottomNeighbor.targetPosition, targetPosition, avgPosition); @@ -1052,9 +1053,9 @@ void PowerTable::enterData(int i, int j, int pos) { // loop until we can't calculate any new data while (entries < newEntries) { entries = newEntries; - // this->fillTable(); - // this->extrapFillTable(); - // this->extrapolateDiagonal(); + this->fillTable(); + this->extrapFillTable(); + this->extrapolateDiagonal(); newEntries = getNumEntries(); } } From ab54378a761692a7b5a55d77cfcfec595e15ca39 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Sun, 23 Feb 2025 22:56:07 -0600 Subject: [PATCH 077/451] WIP --- include/settings.h | 2 +- platformio.ini | 2 +- src/Power_Table.cpp | 66 ++++++++++++++++++++------------------------- 3 files changed, 31 insertions(+), 39 deletions(-) diff --git a/include/settings.h b/include/settings.h index 2654c458..62235202 100644 --- a/include/settings.h +++ b/include/settings.h @@ -308,7 +308,7 @@ const char* const DEFAULT_PASSWORD = "password"; #define PT_READING_RANGE 15 //Max distance a failed neighbor can be horizontally from target position -#define HORIZONTAL_NEIGHBOR_RANGE 60 +#define HORIZONTAL_NEIGHBOR_RANGE 30 //Max distance a failed neighbr can be vertically from target position #define VERTICAL_NEIGHBOR_RANGE 10 diff --git a/platformio.ini b/platformio.ini index 3f700599..715a8e79 100644 --- a/platformio.ini +++ b/platformio.ini @@ -71,7 +71,7 @@ lib_compat_mode = soft check_tool = cppcheck check_flags = --enable=all - --suppress=*:*/.pio/* + --suppress=*:*/.pio/*P --suppress=unmatchedSuppression --suppress=missingIncludeSystem check_severity = medium, high diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 2233c7f0..0e3fed2a 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -52,21 +52,17 @@ void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, (cadence <= (MINIMUM_TABLE_CAD + (POWERTABLE_CAD_INCREMENT * POWERTABLE_CAD_SIZE) - (POWERTABLE_CAD_SIZE / 2))) && (watts.getValue() > 10) && // adding constraints (watts.getValue() < (POWERTABLE_WATT_SIZE * POWERTABLE_WATT_INCREMENT))) { - // if (rtConfig->getMaxStep() == DEFAULT_STEPPER_TRAVEL && rtConfig->getMinStep() == -DEFAULT_STEPPER_TRAVEL) { - // int totalStep = ((rtConfig->getMaxStep() - rtConfig->getMaxStep() / 2000000)); // stepper distance is 400,000,000 so dividing it by 2,000,000 gives us 200 - // calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range - // } else if (rtConfig->getHomed()) { - // int totalStep = (rtConfig->getMaxStep() / TABLE_DIVISOR); // maxStep should be around 22000 / TABLE_DIVISOR gives us 2000ish - // calcStep = totalStep * 0.05; // 5% of that would give us around a 100 positive and negative range - // } - if (powerBuffer.powerEntry[0].readings == 0) { // we need to make sure stepper position is not negative so it only takes positive resistance values // Take Initial reading powerBuffer.set(0); // Check if the current stepper posistion is within a 5% range of the previous stepper position and that the current position is not negative } - if (((ss2k->getCurrentPosition() / TABLE_DIVISOR) >= ((powerBuffer.powerEntry[0].targetPosition) - PT_READING_RANGE)) && - ((ss2k->getCurrentPosition() / TABLE_DIVISOR) <= ((powerBuffer.powerEntry[0].targetPosition) + PT_READING_RANGE))) { + + int currentPos = ss2k->getCurrentPosition() / TABLE_DIVISOR; + int targetPos = powerBuffer.powerEntry[0].targetPosition; + int range = PT_READING_RANGE; + + if ( currentPos >= ( targetPos - range) && currentPos <= (targetPos + range)) { for (int i = 1; i < POWER_SAMPLES; i++) { if (powerBuffer.powerEntry[i].readings == 0) { SS2K_LOG(POWERTABLE_LOG_TAG, "Success!"); @@ -762,16 +758,21 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table TestResults testResults = this->testNeighbors(k, i, targetPosition); if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { + + int avgPosition; // test which bit fields didn't match if (!testResults.leftNeighbor.passedTest) { + SS2K_LOG(POWERTABLE_LOG_TAG, "k: (%d) leftNeighbor.i: (%d)", k, testResults.leftNeighbor.i); - if (testResults.leftNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE && testResults.leftNeighbor.targetPosition >= targetPosition) { // check if the cadence is the same and positions are within a set range in this case its 30. + SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed at: (%d) Target pos: (%f)", testResults.leftNeighbor.targetPosition, targetPosition); + + if (testResults.leftNeighbor.targetPosition < targetPosition + HORIZONTAL_NEIGHBOR_RANGE && (int)targetPosition != testResults.leftNeighbor.targetPosition) { // check if the cadence is the same and positions are within a set range in this case its 30. - int avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average + avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.leftNeighbor.targetPosition, targetPosition, avgPosition); - if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) { // check if the current position moved left is valid + if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, (int)targetPosition).allNeighborsPassed) { // check if the current position moved left is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %f", targetPosition); this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); // enter the data } @@ -824,13 +825,15 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } if (!testResults.rightNeighbor.passedTest) { + SS2K_LOG(POWERTABLE_LOG_TAG, "k: (%d) rightNeighbor.i: (%d)", k, testResults.rightNeighbor.i); - if (testResults.rightNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE && testResults.rightNeighbor.targetPosition <= targetPosition) { - int avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; + SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed at: (%d) Target pos: (%f)", testResults.rightNeighbor.targetPosition, targetPosition); + if (testResults.rightNeighbor.targetPosition > targetPosition - VERTICAL_NEIGHBOR_RANGE && (int)targetPosition != testResults.rightNeighbor.targetPosition) { + avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.rightNeighbor.targetPosition, targetPosition, avgPosition); - if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) { + if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, (float)targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved right was valid! Current position: %f", targetPosition); this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); @@ -886,9 +889,11 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } if (!testResults.topNeighbor.passedTest) { + SS2K_LOG(POWERTABLE_LOG_TAG, "i: (%d) topNeighbor.j: (%d)", i, testResults.topNeighbor.j); - if (testResults.topNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE && testResults.topNeighbor.targetPosition <= targetPosition) { - int avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; + SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed at: (%d) Target pos: (%f)", testResults.topNeighbor.targetPosition, targetPosition); + if (testResults.topNeighbor.targetPosition > targetPosition - VERTICAL_NEIGHBOR_RANGE && (int)targetPosition != testResults.topNeighbor.targetPosition) { + avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.topNeighbor.targetPosition, targetPosition, avgPosition); @@ -948,14 +953,16 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } if (!testResults.bottomNeighbor.passedTest) { + SS2K_LOG(POWERTABLE_LOG_TAG, "i: (%d) bottomNeighbor.j: (%d)", i, testResults.bottomNeighbor.j); - if (testResults.bottomNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE && testResults.bottomNeighbor.targetPosition >= targetPosition) { - int avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; + SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed at: (%d) Target pos: (%f)", testResults.bottomNeighbor.targetPosition, targetPosition); + if (testResults.bottomNeighbor.targetPosition < targetPosition + HORIZONTAL_NEIGHBOR_RANGE && (int)targetPosition != testResults.bottomNeighbor.targetPosition) { + avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.bottomNeighbor.targetPosition, targetPosition, avgPosition); if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved down is valid! Current position: %f", targetPosition); this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); @@ -1013,22 +1020,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(k, i, (int)targetPosition); - //this->tableRow[k].tableEntry[i].readings++; - - // Attempt to fill the table with calculated data... - // if (this->getNumEntries() > 4) { - // int entries = 0; - // int newEntries = 1; - // // loop until we can't calculate any new data - // while (entries < newEntries) { - // entries = newEntries; - // this->fillTable(); - // this->extrapFillTable(); - // this->extrapolateDiagonal(); - // newEntries = getNumEntries(); - // } - // } - // Notify connected client of new data + BLE_ss2kCustomCharacteristic::notify(0x27, k); } From 0bf087a70e25a1c208eeaef70ff0f8ce783ce7db Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Mon, 24 Feb 2025 19:05:50 -0600 Subject: [PATCH 078/451] wrote polynomial interpolation/extrapolation. not tested yet --- src/Power_Table.cpp | 677 ++++++++++++++++++++++++++------------------ 1 file changed, 399 insertions(+), 278 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 0e3fed2a..627c663e 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -343,315 +343,435 @@ TestResults PowerTable::testNeighbors(int i, int j, int testValue) { return returnResult; } -void PowerTable::fillTable() { - int tempValue = INT16_MIN; - - // Fill each empty cell by linear interpolation - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - // Interpolate horizontally - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest left and right non-empty cells - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear interpolation - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) * (j - left) / (right - left); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; +double polynomialInterpolation(const std::vector>& data, double x) { + int n = data.size(); + if (n == 0) return std::numeric_limits::quiet_NaN(); // Handle empty data + + double result = 0.0; + for (int i = 0; i < n; ++i) { + double term = data[i].second; // y_i + for (int j = 0; j < n; ++j) { + if (i != j) { + term *= (x - data[j].first) / (data[i].first - data[j].first); // Calculate Lagrange basis polynomial } - } } - } - } - - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - // Interpolate vertically - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top and bottom non-empty cells - int top = i - 1; - while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; - int bottom = i + 1; - while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; - - if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { - // Linear interpolation - tempValue = this->tableRow[top].tableEntry[j].targetPosition + - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) * (i - top) / (bottom - top); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } + result += term; } + return result; } -void PowerTable::extrapFillTable() { - // Find the center of the known data - int sumRow = 0, sumCol = 0, count = 0; - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - sumRow += i; - sumCol += j; - count++; - } - } - } - - // prevent divide by zero - if (count == 0) { - return; - } - - int centerRow = sumRow / count; - int centerCol = sumCol / count; - int tempValue = INT16_MIN; - - // Function to extrapolate a single cell based on its neighbors - auto extrapolateCell = [&](int i, int j) { - // Find nearest left non-empty cell - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - - // Find nearest right non-empty cell - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear extrapolation - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - if (j < left) { - // Extrapolate to the left - tempValue = this->tableRow[i].tableEntry[left].targetPosition - - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } else if (j > right) { - // Extrapolate to the right - tempValue = this->tableRow[i].tableEntry[right].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } else if (left - 1 >= 0) { - // Only left value available, extrapolate to the right - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (right + 1 < POWERTABLE_WATT_SIZE) { - // Only right value available, extrapolate to the left - if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - tempValue = - this->tableRow[i].tableEntry[right].targetPosition - - (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - }; - - // Extrapolate horizontally and vertically starting from the center - for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { - for (int i = centerRow - distance; i <= centerRow + distance; ++i) { - for (int j = centerCol - distance; j <= centerCol + distance; ++j) { - if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - extrapolateCell(i, j); - } - } - } - } - // Extrapolate each empty cell +void PowerTable::fillTable() { for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - // Extrapolate horizontally - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest left non-empty cell - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - - // Find nearest right non-empty cell - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear extrapolation - if (j < left) { - // Extrapolate to the left - tempValue = this->tableRow[i].tableEntry[left].targetPosition - - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + std::vector> data; + + // Gather data points for interpolation (horizontal) + for (int k = 0; k < POWERTABLE_WATT_SIZE; ++k) { + if (this->tableRow[i].tableEntry[k].targetPosition != INT16_MIN) { + data.push_back({static_cast(k * 30), static_cast(this->tableRow[i].tableEntry[k].targetPosition)}); // Power values are multiples of 30 + } } - } else if (j > right) { - // Extrapolate to the right - tempValue = this->tableRow[i].tableEntry[right].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (left >= 1) { - // Only left value available, extrapolate to the right - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (right + 1 < POWERTABLE_WATT_SIZE) { - // Only right value available, extrapolate to the left - if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[right].targetPosition - - (right - j) * - (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + if (!data.empty()) { + double power = j * 30; // Power value for the current cell + double interpValue = polynomialInterpolation(data, power); + + if (!std::isnan(interpValue) && this->testNeighbors(i, j, static_cast(round(interpValue))).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = static_cast(round(interpValue)); + } } - } } - } } - } } + // Vertical Interpolation (similar structure) for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - // Extrapolate vertically - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top non-empty cell - int top = i - 1; - while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; - - // Find nearest bottom non-empty cell - int bottom = i + 1; - while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; - - if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { - // Linear extrapolation - if (i < top) { - // Extrapolate upwards - tempValue = this->tableRow[top].tableEntry[j].targetPosition - - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } else if (i > bottom) { - // Extrapolate downwards - tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (top >= 1) { - // Only top value available, extrapolate downwards - if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { - tempValue = this->tableRow[top].tableEntry[j].targetPosition + - (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } else { - } - } - } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { - // Only bottom value available, extrapolate upwards - if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { - tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - - (bottom - i) * - (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + std::vector> data; + + // Gather data points for interpolation (vertical) + for (int k = 0; k < POWERTABLE_CAD_SIZE; ++k) { + if (this->tableRow[k].tableEntry[j].targetPosition != INT16_MIN) { + data.push_back({static_cast(k), static_cast(this->tableRow[k].tableEntry[j].targetPosition)}); + } + } + + if (!data.empty()) { + double cadence = i; + double interpValue = polynomialInterpolation(data, cadence); + + if (!std::isnan(interpValue) && this->testNeighbors(i, j, static_cast(round(interpValue))).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = static_cast(round(interpValue)); + } + } } - } } - } } } -void PowerTable::extrapolateDiagonal() { - int tempValue = INT16_MIN; +void PowerTable::extrapFillTable() { for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top-left non-empty cell - int topLeftRow = i - 1, topLeftCol = j - 1; - while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { - topLeftRow--; - topLeftCol--; - } - - // Find nearest bottom-right non-empty cell - int bottomRightRow = i + 1, bottomRightCol = j + 1; - while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && - this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { - bottomRightRow++; - bottomRightCol++; - } + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + std::vector> data; + + // Gather data points for extrapolation (horizontal) + for (int k = 0; k < POWERTABLE_WATT_SIZE; ++k) { + if (this->tableRow[i].tableEntry[k].targetPosition != INT16_MIN) { + data.push_back({static_cast(k * 30), static_cast(this->tableRow[i].tableEntry[k].targetPosition)}); + } + } - // Perform diagonal extrapolation (top-left to bottom-right) - if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { - tempValue = - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + - ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / - (bottomRightCol - topLeftCol); + if (!data.empty()) { + double power = j * 30; + double extrapValue = polynomialInterpolation(data, power); - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - - // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left - if (tempValue == INT16_MIN) { - // Find nearest top-right non-empty cell - int topRightRow = i - 1, topRightCol = j + 1; - while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { - topRightRow--; - topRightCol++; + if (!std::isnan(extrapValue) && this->testNeighbors(i, j, static_cast(round(extrapValue))).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = static_cast(round(extrapValue)); + } + } } + } + } - // Find nearest bottom-left non-empty cell - int bottomLeftRow = i + 1, bottomLeftCol = j - 1; - while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { - bottomLeftRow++; - bottomLeftCol--; - } + // Vertical Extrapolation (similar structure) + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + std::vector> data; + + // Gather data points for extrapolation (vertical) + for (int k = 0; k < POWERTABLE_CAD_SIZE; ++k) { + if (this->tableRow[k].tableEntry[j].targetPosition != INT16_MIN) { + data.push_back({static_cast(k), static_cast(this->tableRow[k].tableEntry[j].targetPosition)}); + } + } - // Perform diagonal extrapolation (top-right to bottom-left) - if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { - tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + - ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * - (j - bottomLeftCol)) / - (topRightCol - bottomLeftCol); + if (!data.empty()) { + double cadence = i; + double extrapValue = polynomialInterpolation(data, cadence); - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + if (!std::isnan(extrapValue) && this->testNeighbors(i, j, static_cast(round(extrapValue))).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = static_cast(round(extrapValue)); + } + } } - } } - } } } +// void PowerTable::fillTable() { +// int tempValue = INT16_MIN; + +// // Fill each empty cell by linear interpolation +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// // Interpolate horizontally +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// // Find nearest left and right non-empty cells +// int left = j - 1; +// while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; +// int right = j + 1; +// while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + +// if (left >= 0 && right < POWERTABLE_WATT_SIZE) { +// // Linear interpolation +// tempValue = this->tableRow[i].tableEntry[left].targetPosition + +// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) * (j - left) / (right - left); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } +// } +// } + +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// // Interpolate vertically +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// // Find nearest top and bottom non-empty cells +// int top = i - 1; +// while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; +// int bottom = i + 1; +// while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; + +// if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { +// // Linear interpolation +// tempValue = this->tableRow[top].tableEntry[j].targetPosition + +// (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) * (i - top) / (bottom - top); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } +// } +// } +// } + +// void PowerTable::extrapFillTable() { +// // Find the center of the known data +// int sumRow = 0, sumCol = 0, count = 0; +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { +// sumRow += i; +// sumCol += j; +// count++; +// } +// } +// } + +// // prevent divide by zero +// if (count == 0) { +// return; +// } + +// int centerRow = sumRow / count; +// int centerCol = sumCol / count; +// int tempValue = INT16_MIN; + +// // Function to extrapolate a single cell based on its neighbors +// auto extrapolateCell = [&](int i, int j) { +// // Find nearest left non-empty cell +// int left = j - 1; +// while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + +// // Find nearest right non-empty cell +// int right = j + 1; +// while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + +// if (left >= 0 && right < POWERTABLE_WATT_SIZE) { +// // Linear extrapolation +// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { +// if (j < left) { +// // Extrapolate to the left +// tempValue = this->tableRow[i].tableEntry[left].targetPosition - +// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } else if (j > right) { +// // Extrapolate to the right +// tempValue = this->tableRow[i].tableEntry[right].targetPosition + +// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } +// } else if (left - 1 >= 0) { +// // Only left value available, extrapolate to the right +// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { +// tempValue = this->tableRow[i].tableEntry[left].targetPosition + +// (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } else if (right + 1 < POWERTABLE_WATT_SIZE) { +// // Only right value available, extrapolate to the left +// if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { +// tempValue = +// this->tableRow[i].tableEntry[right].targetPosition - +// (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } +// }; + +// // Extrapolate horizontally and vertically starting from the center +// for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { +// for (int i = centerRow - distance; i <= centerRow + distance; ++i) { +// for (int j = centerCol - distance; j <= centerCol + distance; ++j) { +// if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// extrapolateCell(i, j); +// } +// } +// } +// } +// // Extrapolate each empty cell +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// // Extrapolate horizontally +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// // Find nearest left non-empty cell +// int left = j - 1; +// while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + +// // Find nearest right non-empty cell +// int right = j + 1; +// while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; +// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { +// if (left >= 0 && right < POWERTABLE_WATT_SIZE) { +// // Linear extrapolation +// if (j < left) { +// // Extrapolate to the left +// tempValue = this->tableRow[i].tableEntry[left].targetPosition - +// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } + +// } else if (j > right) { +// // Extrapolate to the right +// tempValue = this->tableRow[i].tableEntry[right].targetPosition + +// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } else if (left >= 1) { +// // Only left value available, extrapolate to the right +// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { +// tempValue = this->tableRow[i].tableEntry[left].targetPosition + +// (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } else if (right + 1 < POWERTABLE_WATT_SIZE) { +// // Only right value available, extrapolate to the left +// if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { +// tempValue = this->tableRow[i].tableEntry[right].targetPosition - +// (right - j) * +// (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } +// } +// } +// } +// } + +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// // Extrapolate vertically +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// // Find nearest top non-empty cell +// int top = i - 1; +// while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; + +// // Find nearest bottom non-empty cell +// int bottom = i + 1; +// while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; + +// if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { +// // Linear extrapolation +// if (i < top) { +// // Extrapolate upwards +// tempValue = this->tableRow[top].tableEntry[j].targetPosition - +// (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } else if (i > bottom) { +// // Extrapolate downwards +// tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + +// (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } else if (top >= 1) { +// // Only top value available, extrapolate downwards +// if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { +// tempValue = this->tableRow[top].tableEntry[j].targetPosition + +// (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } else { +// } +// } +// } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { +// // Only bottom value available, extrapolate upwards +// if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { +// tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - +// (bottom - i) * +// (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } +// } +// } +// } +// } + +// void PowerTable::extrapolateDiagonal() { +// int tempValue = INT16_MIN; + +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// // Find nearest top-left non-empty cell +// int topLeftRow = i - 1, topLeftCol = j - 1; +// while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { +// topLeftRow--; +// topLeftCol--; +// } + +// // Find nearest bottom-right non-empty cell +// int bottomRightRow = i + 1, bottomRightCol = j + 1; +// while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && +// this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { +// bottomRightRow++; +// bottomRightCol++; +// } + +// // Perform diagonal extrapolation (top-left to bottom-right) +// if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { +// tempValue = +// this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + +// ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / +// (bottomRightCol - topLeftCol); + +// if (testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } + +// // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left +// if (tempValue == INT16_MIN) { +// // Find nearest top-right non-empty cell +// int topRightRow = i - 1, topRightCol = j + 1; +// while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { +// topRightRow--; +// topRightCol++; +// } + +// // Find nearest bottom-left non-empty cell +// int bottomLeftRow = i + 1, bottomLeftCol = j - 1; +// while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { +// bottomLeftRow++; +// bottomLeftCol--; +// } + +// // Perform diagonal extrapolation (top-right to bottom-left) +// if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { +// tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + +// ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * +// (j - bottomLeftCol)) / +// (topRightCol - bottomLeftCol); + +// if (testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } +// } +// } +// } +// } + int PowerTable::getNumEntries() { int ret = 0; for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { @@ -772,7 +892,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.leftNeighbor.targetPosition, targetPosition, avgPosition); - if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, (int)targetPosition).allNeighborsPassed) { // check if the current position moved left is valid + if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) { // check if the current position moved left is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %f", targetPosition); this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); // enter the data } @@ -828,6 +948,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "k: (%d) rightNeighbor.i: (%d)", k, testResults.rightNeighbor.i); SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed at: (%d) Target pos: (%f)", testResults.rightNeighbor.targetPosition, targetPosition); + if (testResults.rightNeighbor.targetPosition > targetPosition - VERTICAL_NEIGHBOR_RANGE && (int)targetPosition != testResults.rightNeighbor.targetPosition) { avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.rightNeighbor.targetPosition, targetPosition, avgPosition); From cae992d81e05cb915b653c187a2317ed2346b74e Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Tue, 25 Feb 2025 11:36:59 -0600 Subject: [PATCH 079/451] wrote cubic spline interpolation. still needs testing --- src/Power_Table.cpp | 241 +++++++++++++++++++++++++++++++++----------- 1 file changed, 180 insertions(+), 61 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 627c663e..85c88fa5 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -15,6 +15,7 @@ #include #include #include +#include void PowerBuffer::set(int i) { this->powerEntry[i].readings++; @@ -360,56 +361,56 @@ double polynomialInterpolation(const std::vector>& dat return result; } -void PowerTable::fillTable() { - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - std::vector> data; - - // Gather data points for interpolation (horizontal) - for (int k = 0; k < POWERTABLE_WATT_SIZE; ++k) { - if (this->tableRow[i].tableEntry[k].targetPosition != INT16_MIN) { - data.push_back({static_cast(k * 30), static_cast(this->tableRow[i].tableEntry[k].targetPosition)}); // Power values are multiples of 30 - } - } - - if (!data.empty()) { - double power = j * 30; // Power value for the current cell - double interpValue = polynomialInterpolation(data, power); +// void PowerTable::fillTable() { +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// std::vector> data; + +// // Gather data points for interpolation (horizontal) +// for (int k = 0; k < POWERTABLE_WATT_SIZE; ++k) { +// if (this->tableRow[i].tableEntry[k].targetPosition != INT16_MIN) { +// data.push_back({static_cast(k * 30), static_cast(this->tableRow[i].tableEntry[k].targetPosition)}); // Power values are multiples of 30 +// } +// } - if (!std::isnan(interpValue) && this->testNeighbors(i, j, static_cast(round(interpValue))).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = static_cast(round(interpValue)); - } - } - } - } - } +// if (!data.empty()) { +// double power = j * 30; // Power value for the current cell +// double interpValue = polynomialInterpolation(data, power); - // Vertical Interpolation (similar structure) - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - std::vector> data; +// if (!std::isnan(interpValue) && this->testNeighbors(i, j, static_cast(round(interpValue))).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = static_cast(round(interpValue)); +// } +// } +// } +// } +// } - // Gather data points for interpolation (vertical) - for (int k = 0; k < POWERTABLE_CAD_SIZE; ++k) { - if (this->tableRow[k].tableEntry[j].targetPosition != INT16_MIN) { - data.push_back({static_cast(k), static_cast(this->tableRow[k].tableEntry[j].targetPosition)}); - } - } +// // Vertical Interpolation (similar structure) +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// std::vector> data; + +// // Gather data points for interpolation (vertical) +// for (int k = 0; k < POWERTABLE_CAD_SIZE; ++k) { +// if (this->tableRow[k].tableEntry[j].targetPosition != INT16_MIN) { +// data.push_back({static_cast(k), static_cast(this->tableRow[k].tableEntry[j].targetPosition)}); +// } +// } - if (!data.empty()) { - double cadence = i; - double interpValue = polynomialInterpolation(data, cadence); +// if (!data.empty()) { +// double cadence = i; +// double interpValue = polynomialInterpolation(data, cadence); - if (!std::isnan(interpValue) && this->testNeighbors(i, j, static_cast(round(interpValue))).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = static_cast(round(interpValue)); - } - } - } - } - } -} +// if (!std::isnan(interpValue) && this->testNeighbors(i, j, static_cast(round(interpValue))).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = static_cast(round(interpValue)); +// } +// } +// } +// } +// } +// } void PowerTable::extrapFillTable() { @@ -463,6 +464,107 @@ void PowerTable::extrapFillTable() { } } +struct SplineCoefficients { + std::vector a, b, c, d, x; +}; + +SplineCoefficients computeCubicSpline(const std::vector& x, const std::vector& y) { + int n = x.size() - 1; + std::vector interval_widths(n), alpha(n), l(n + 1), mu(n), z(n + 1); + std::vector a(y), b(n), c(n + 1), d(n); + + for (int i = 0; i < n; ++i) { + interval_widths[i] = x[i + 1] - x[i]; + } + + for (int i = 1; i < n; ++i) { + alpha[i] = (3.0 / interval_widths[i]) * (y[i + 1] - y[i]) - (3.0 / interval_widths[i - 1]) * (y[i] - y[i - 1]); + } + + l[0] = 1.0; + mu[0] = z[0] = 0.0; + + for (int i = 1; i < n; ++i) { + l[i] = 2.0 * (x[i + 1] - x[i - 1]) - interval_widths[i - 1] * mu[i - 1]; + mu[i] = interval_widths[i] / l[i]; + z[i] = (alpha[i] - interval_widths[i - 1] * z[i - 1]) / l[i]; + } + + l[n] = 1.0; + z[n] = c[n] = 0.0; + + for (int j = n - 1; j >= 0; --j) { + c[j] = z[j] - mu[j] * c[j + 1]; + b[j] = (y[j + 1] - y[j]) / interval_widths[j] - interval_widths[j] * (c[j + 1] + 2.0 * c[j]) / 3.0; + d[j] = (c[j + 1] - c[j]) / (3.0 * interval_widths[j]); + } + + return {a, b, c, d, x}; +} + +double interpolateCubicSpline(const SplineCoefficients& spline, double x_val) { + int n = spline.x.size() - 1; + + // Binary search to find the correct interval + auto it = std::lower_bound(spline.x.begin(), spline.x.end(), x_val); + int i = std::distance(spline.x.begin(), it); + if (i > 0) { + i--; + } else if (i == n) { + i--; // Handle the case where x_val is equal to the last x + } + + + double dx = x_val - spline.x[i]; + return spline.a[i] + spline.b[i] * dx + spline.c[i] * dx * dx + spline.d[i] * dx * dx * dx; +} + +void PowerTable::fillTable() { + + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + std::vector x_vals, y_vals; + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + x_vals.push_back(j); + y_vals.push_back(this->tableRow[i].tableEntry[j].targetPosition); + } + } + if (x_vals.size() > 1) { + SplineCoefficients spline = computeCubicSpline(x_vals, y_vals); + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + double interpolated_value = interpolateCubicSpline(spline, j); + if (this->testNeighbors(i, j, static_cast(std::round(interpolated_value))).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(interpolated_value)); + } + } + } + } + } + + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + std::vector x_vals, y_vals; + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + x_vals.push_back(i); + y_vals.push_back(this->tableRow[i].tableEntry[j].targetPosition); + } + } + if (x_vals.size() > 1) { + SplineCoefficients spline = computeCubicSpline(x_vals, y_vals); + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + double interpolated_value = interpolateCubicSpline(spline, i); + if (this->testNeighbors(i, j, static_cast(std::round(interpolated_value))).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(interpolated_value)); + } + } + } + } + } +} + + // void PowerTable::fillTable() { // int tempValue = INT16_MIN; @@ -886,7 +988,8 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "k: (%d) leftNeighbor.i: (%d)", k, testResults.leftNeighbor.i); SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed at: (%d) Target pos: (%f)", testResults.leftNeighbor.targetPosition, targetPosition); - if (testResults.leftNeighbor.targetPosition < targetPosition + HORIZONTAL_NEIGHBOR_RANGE && (int)targetPosition != testResults.leftNeighbor.targetPosition) { // check if the cadence is the same and positions are within a set range in this case its 30. + if (testResults.leftNeighbor.targetPosition < targetPosition + HORIZONTAL_NEIGHBOR_RANGE){ + // && (int)targetPosition != testResults.leftNeighbor.targetPosition) { // check if the cadence is the same and positions are within a set range in this case its 30. avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.leftNeighbor.targetPosition, targetPosition, avgPosition); @@ -949,7 +1052,8 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "k: (%d) rightNeighbor.i: (%d)", k, testResults.rightNeighbor.i); SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed at: (%d) Target pos: (%f)", testResults.rightNeighbor.targetPosition, targetPosition); - if (testResults.rightNeighbor.targetPosition > targetPosition - VERTICAL_NEIGHBOR_RANGE && (int)targetPosition != testResults.rightNeighbor.targetPosition) { + if (testResults.rightNeighbor.targetPosition > targetPosition - VERTICAL_NEIGHBOR_RANGE){ + // && (int)targetPosition != testResults.rightNeighbor.targetPosition) { avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.rightNeighbor.targetPosition, targetPosition, avgPosition); @@ -1013,7 +1117,8 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "i: (%d) topNeighbor.j: (%d)", i, testResults.topNeighbor.j); SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed at: (%d) Target pos: (%f)", testResults.topNeighbor.targetPosition, targetPosition); - if (testResults.topNeighbor.targetPosition > targetPosition - VERTICAL_NEIGHBOR_RANGE && (int)targetPosition != testResults.topNeighbor.targetPosition) { + if (testResults.topNeighbor.targetPosition > targetPosition - VERTICAL_NEIGHBOR_RANGE){ + // && (int)targetPosition != testResults.topNeighbor.targetPosition) { avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.topNeighbor.targetPosition, targetPosition, avgPosition); @@ -1077,7 +1182,8 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "i: (%d) bottomNeighbor.j: (%d)", i, testResults.bottomNeighbor.j); SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed at: (%d) Target pos: (%f)", testResults.bottomNeighbor.targetPosition, targetPosition); - if (testResults.bottomNeighbor.targetPosition < targetPosition + HORIZONTAL_NEIGHBOR_RANGE && (int)targetPosition != testResults.bottomNeighbor.targetPosition) { + if (testResults.bottomNeighbor.targetPosition < targetPosition + HORIZONTAL_NEIGHBOR_RANGE){ + // && (int)targetPosition != testResults.bottomNeighbor.targetPosition) { avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.bottomNeighbor.targetPosition, targetPosition, avgPosition); @@ -1142,6 +1248,19 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(k, i, (int)targetPosition); + if (this->getNumEntries() > 4) { + int entries = 0; + int newEntries = 1; + // loop until we can't calculate any new data + while (entries < newEntries) { + entries = newEntries; + this->fillTable(); + this->extrapFillTable(); + //this->extrapolateDiagonal(); + newEntries = getNumEntries(); + } + } + BLE_ss2kCustomCharacteristic::notify(0x27, k); } @@ -1160,18 +1279,18 @@ void PowerTable::enterData(int i, int j, int pos) { } this->tableRow[i].tableEntry[j].readings++; - if (this->getNumEntries() > 4) { - int entries = 0; - int newEntries = 1; - // loop until we can't calculate any new data - while (entries < newEntries) { - entries = newEntries; - this->fillTable(); - this->extrapFillTable(); - this->extrapolateDiagonal(); - newEntries = getNumEntries(); - } - } + // if (this->getNumEntries() > 4) { + // int entries = 0; + // int newEntries = 1; + // // loop until we can't calculate any new data + // while (entries < newEntries) { + // entries = newEntries; + // this->fillTable(); + // this->extrapFillTable(); + // this->extrapolateDiagonal(); + // newEntries = getNumEntries(); + // } + // } } void PowerTable::downVoteData(int i, int j, float target, int neighbor){ From 67a7ca4bb27f50324574d492ef85379c0d641302 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Tue, 25 Feb 2025 17:07:54 -0600 Subject: [PATCH 080/451] cleaned up newEntry --- src/Power_Table.cpp | 87 ++++++++------------------------------------- 1 file changed, 14 insertions(+), 73 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 85c88fa5..81f0aa5d 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -992,18 +992,13 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { // && (int)targetPosition != testResults.leftNeighbor.targetPosition) { // check if the cadence is the same and positions are within a set range in this case its 30. avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average - SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.leftNeighbor.targetPosition, targetPosition, avgPosition); - if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) { // check if the current position moved left is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %f", targetPosition); + this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); // enter the data - } - // else { - // this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - - // } + } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { // checks if the avg position with the current watts and cadence is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); @@ -1011,23 +1006,15 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(k, i, avgPosition); } - // else { - - // this->tableRow[k].tableEntry[i].readings--; - - // } if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition) .allNeighborsPassed) { // checks if the failed nighbor is valid with the right neighbors cadence and watts SS2K_LOG(POWERTABLE_LOG_TAG, "Left Neighbors position was valid with Right Neighbors cadence and watts! Left Neighbor Position: %d", testResults.leftNeighbor.targetPosition); + this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition); + } - // else { - - // this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - - // } //still downvote data if all the tests fail if(!((this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) || @@ -1049,14 +1036,13 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (!testResults.rightNeighbor.passedTest) { + avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; + SS2K_LOG(POWERTABLE_LOG_TAG, "k: (%d) rightNeighbor.i: (%d)", k, testResults.rightNeighbor.i); SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed at: (%d) Target pos: (%f)", testResults.rightNeighbor.targetPosition, targetPosition); if (testResults.rightNeighbor.targetPosition > targetPosition - VERTICAL_NEIGHBOR_RANGE){ - // && (int)targetPosition != testResults.rightNeighbor.targetPosition) { - avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; - SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.rightNeighbor.targetPosition, targetPosition, avgPosition); - + // && (int)targetPosition != testResults.rightNeighbor.targetPosition) { if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, (float)targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved right was valid! Current position: %f", targetPosition); @@ -1064,11 +1050,6 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); } - // else { - - // this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - - // } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); @@ -1076,11 +1057,6 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(k, i, avgPosition); } - // else { - - // this->tableRow[k].tableEntry[i].readings--; - - // } if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Right Neighbors position was valid with Left Neighbors cadence and watts! Right Neighbor Position: %d", @@ -1089,11 +1065,6 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition); } - // else { - - // this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - - // } // still downvote data if all the tests fail if(!((this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) || @@ -1115,13 +1086,13 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (!testResults.topNeighbor.passedTest) { + avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; + SS2K_LOG(POWERTABLE_LOG_TAG, "i: (%d) topNeighbor.j: (%d)", i, testResults.topNeighbor.j); SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed at: (%d) Target pos: (%f)", testResults.topNeighbor.targetPosition, targetPosition); + if (testResults.topNeighbor.targetPosition > targetPosition - VERTICAL_NEIGHBOR_RANGE){ - // && (int)targetPosition != testResults.topNeighbor.targetPosition) { - avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; - SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.topNeighbor.targetPosition, targetPosition, avgPosition); - + // && (int)targetPosition != testResults.topNeighbor.targetPosition) { if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); @@ -1129,11 +1100,6 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); } - // else { - - // this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - - // } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); @@ -1141,11 +1107,6 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(k, i, avgPosition); } - // else { - - // this->tableRow[k].tableEntry[i].readings--; - - // } if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Top Neighbors position was valid with Bottom Neighbors cadence and watts! Top Neighbor Position: %d", @@ -1154,11 +1115,6 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); } - // else { - - // this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - - // } //still downvote data if all the tests fail if(!((this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) || @@ -1180,25 +1136,20 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { if (!testResults.bottomNeighbor.passedTest) { + avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; + SS2K_LOG(POWERTABLE_LOG_TAG, "i: (%d) bottomNeighbor.j: (%d)", i, testResults.bottomNeighbor.j); SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed at: (%d) Target pos: (%f)", testResults.bottomNeighbor.targetPosition, targetPosition); + if (testResults.bottomNeighbor.targetPosition < targetPosition + HORIZONTAL_NEIGHBOR_RANGE){ // && (int)targetPosition != testResults.bottomNeighbor.targetPosition) { - avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; - SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.bottomNeighbor.targetPosition, targetPosition, avgPosition); - if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved down is valid! Current position: %f", targetPosition); this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); } - // else { - - // this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - - // } if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); @@ -1206,11 +1157,6 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(k, i, avgPosition); } - // else { - - // this->tableRow[k].tableEntry[i].readings--; - - // } if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom Neighbors position was valid with Top Neighbors cadence and watts! Bottom Neighbor Position: %d", @@ -1219,11 +1165,6 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition); } - // else { - - // this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - - // } // still downvote data if all the tests fail if(!((this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) || From 2eae63b5f2bb4f690f29ea4df3d62bf48639e111 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Tue, 25 Feb 2025 20:06:28 -0600 Subject: [PATCH 081/451] testing out different quadratic extrapolation --- src/Power_Table.cpp | 312 +++++++++++++++++++++++++++++++++----------- 1 file changed, 234 insertions(+), 78 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 81f0aa5d..acdc8148 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -520,7 +520,6 @@ double interpolateCubicSpline(const SplineCoefficients& spline, double x_val) { } void PowerTable::fillTable() { - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { std::vector x_vals, y_vals; for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { @@ -808,72 +807,229 @@ void PowerTable::fillTable() { // } // } -// void PowerTable::extrapolateDiagonal() { -// int tempValue = INT16_MIN; +// void PowerTable::extrapFillTable() { +// int sumRow = 0, sumCol = 0, count = 0; +// // Find the center of known data points // for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// // Find nearest top-left non-empty cell -// int topLeftRow = i - 1, topLeftCol = j - 1; -// while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { -// topLeftRow--; -// topLeftCol--; -// } +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { +// sumRow += i; +// sumCol += j; +// count++; +// } +// } +// } -// // Find nearest bottom-right non-empty cell -// int bottomRightRow = i + 1, bottomRightCol = j + 1; -// while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && -// this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { -// bottomRightRow++; -// bottomRightCol++; -// } +// if (count == 0) return; // No valid data, nothing to extrapolate -// // Perform diagonal extrapolation (top-left to bottom-right) -// if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { -// tempValue = -// this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + -// ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / -// (bottomRightCol - topLeftCol); +// int centerRow = sumRow / count; +// int centerCol = sumCol / count; -// if (testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// // Lambda function to perform linear extrapolation +// auto extrapolate = [&](int i, int j, bool horizontal) { +// int low = horizontal ? j - 1 : i - 1; +// int high = horizontal ? j + 1 : i + 1; +// int size = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; + +// // Find nearest non-empty cells +// while (low >= 0 && (horizontal ? this->tableRow[i].tableEntry[low].targetPosition : this->tableRow[low].tableEntry[j].targetPosition) == INT16_MIN) --low; +// while (high < size && (horizontal ? this->tableRow[i].tableEntry[high].targetPosition : this->tableRow[high].tableEntry[j].targetPosition) == INT16_MIN) ++high; + +// if (low >= 0 && high < size) { +// // Interpolation using both sides +// int lowVal = horizontal ? this->tableRow[i].tableEntry[low].targetPosition : this->tableRow[low].tableEntry[j].targetPosition; +// int highVal = horizontal ? this->tableRow[i].tableEntry[high].targetPosition : this->tableRow[high].tableEntry[j].targetPosition; +// int extrapolatedValue = lowVal + (highVal - lowVal) * (horizontal ? (j - low) : (i - low)) / (high - low); + +// if (this->testNeighbors(i, j, extrapolatedValue).allNeighborsPassed) { +// if (horizontal) this->tableRow[i].tableEntry[j].targetPosition = extrapolatedValue; +// else this->tableRow[i].tableEntry[j].targetPosition = extrapolatedValue; // } -// } - -// // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left -// if (tempValue == INT16_MIN) { -// // Find nearest top-right non-empty cell -// int topRightRow = i - 1, topRightCol = j + 1; -// while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { -// topRightRow--; -// topRightCol++; +// } else if (low >= 1) { +// // Extrapolate from left/top if only one side is available +// int lowVal = horizontal ? this->tableRow[i].tableEntry[low].targetPosition : this->tableRow[low].tableEntry[j].targetPosition; +// int prevLowVal = horizontal ? this->tableRow[i].tableEntry[low - 1].targetPosition : this->tableRow[low - 1].tableEntry[j].targetPosition; +// int extrapolatedValue = lowVal + (lowVal - prevLowVal) * (horizontal ? (j - low) : (i - low)); + +// if (this->testNeighbors(i, j, extrapolatedValue).allNeighborsPassed) { +// if (horizontal) this->tableRow[i].tableEntry[j].targetPosition = extrapolatedValue; +// else this->tableRow[i].tableEntry[j].targetPosition = extrapolatedValue; +// } +// } else if (high + 1 < size) { +// // Extrapolate from right/bottom if only one side is available +// int highVal = horizontal ? this->tableRow[i].tableEntry[high].targetPosition : this->tableRow[high].tableEntry[j].targetPosition; +// int nextHighVal = horizontal ? this->tableRow[i].tableEntry[high + 1].targetPosition : this->tableRow[high + 1].tableEntry[j].targetPosition; +// int extrapolatedValue = highVal - (nextHighVal - highVal) * (horizontal ? (high - j) : (high - i)); + +// if (this->testNeighbors(i, j, extrapolatedValue).allNeighborsPassed) { +// if (horizontal) this->tableRow[i].tableEntry[j].targetPosition = extrapolatedValue; +// else this->tableRow[i].tableEntry[j].targetPosition = extrapolatedValue; // } +// } +// }; -// // Find nearest bottom-left non-empty cell -// int bottomLeftRow = i + 1, bottomLeftCol = j - 1; -// while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { -// bottomLeftRow++; -// bottomLeftCol--; +// // Start from the center and fill missing values in an expanding manner +// for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { +// for (int i = std::max(0, centerRow - distance); i < std::min(POWERTABLE_CAD_SIZE, centerRow + distance + 1); ++i) { +// for (int j = std::max(0, centerCol - distance); j < std::min(POWERTABLE_WATT_SIZE, centerCol + distance + 1); ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// extrapolate(i, j, true); // Try horizontal extrapolation +// extrapolate(i, j, false); // Try vertical extrapolation +// } // } +// } +// } +// } -// // Perform diagonal extrapolation (top-right to bottom-left) -// if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { -// tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + -// ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * -// (j - bottomLeftCol)) / -// (topRightCol - bottomLeftCol); -// if (testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } +void PowerTable::extrapolateDiagonal() { + int tempValue = INT16_MIN; + + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest top-left non-empty cell + int topLeftRow = i - 1, topLeftCol = j - 1; + while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { + topLeftRow--; + topLeftCol--; + } + + // Find nearest bottom-right non-empty cell + int bottomRightRow = i + 1, bottomRightCol = j + 1; + while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && + this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { + bottomRightRow++; + bottomRightCol++; + } + + // Perform diagonal extrapolation (top-left to bottom-right) + if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { + tempValue = + this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + + ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / + (bottomRightCol - topLeftCol); + + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + + // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left + if (tempValue == INT16_MIN) { + // Find nearest top-right non-empty cell + int topRightRow = i - 1, topRightCol = j + 1; + while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { + topRightRow--; + topRightCol++; + } + + // Find nearest bottom-left non-empty cell + int bottomLeftRow = i + 1, bottomLeftCol = j - 1; + while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { + bottomLeftRow++; + bottomLeftCol--; + } + + // Perform diagonal extrapolation (top-right to bottom-left) + if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { + tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + + ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * + (j - bottomLeftCol)) / + (topRightCol - bottomLeftCol); + + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } + } + } +} + +// double polynomialExtrapolation(const std::vector& x, const std::vector& y, double x_new, int order = 1) { +// if (x.size() != y.size() || x.size() < order + 1 || order < 0) { +// return std::numeric_limits::quiet_NaN(); // Return NaN for invalid input +// } + +// if (order == 1) { // Linear +// // Simple linear interpolation (same as before) +// return y[0] + (y[1] - y[0]) * (x_new - x[0]) / (x[1] - x[0]); //Assumes x values are in increasing order +// } else if (order == 2) { // Quadratic +// // Use Lagrange interpolation for quadratic +// if (x.size() < 3) return std::numeric_limits::quiet_NaN(); +// double y_new = 0.0; +// for (int i = 0; i < 3; ++i) { +// double term = y[i]; +// for (int j = 0; j < 3; ++j) { +// if (i != j) { +// term *= (x_new - x[j]) / (x[i] - x[j]); // } // } +// y_new += term; // } -// } +// return y_new; +// } else { +// return std::numeric_limits::quiet_NaN(); // Invalid order // } // } +// void PowerTable::extrapolateDiagonal() { +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// double tempValue = INT16_MIN; + +// // Top-left to bottom-right extrapolation +// std::vector x, y; +// int row = i; +// int col = j; + +// //Find points along the diagonal +// for(int k = 0; k < 3 && row >= 0 && col >= 0 && row < POWERTABLE_CAD_SIZE && col < POWERTABLE_WATT_SIZE; k++){ +// if(this->tableRow[row].tableEntry[col].targetPosition != INT16_MIN){ +// x.push_back(col); +// y.push_back(this->tableRow[row].tableEntry[col].targetPosition); +// } +// row--; +// col--; +// } + +// if (x.size() >= 2) { //Need at least 2 points for linear, 3 for quadratic +// tempValue = polynomialExtrapolation(x, y, j, 2); // Use quadratic. Change to 1 for linear. +// if (!std::isnan(tempValue) && testNeighbors(i, j, static_cast(tempValue)).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = static_cast(tempValue); +// } +// } + + +// // Top-right to bottom-left extrapolation (if the first one failed) +// if (tempValue == INT16_MIN) { +// x.clear(); +// y.clear(); +// row = i; +// col = j; +// for(int k = 0; k < 3 && row >= 0 && col >= 0 && row < POWERTABLE_CAD_SIZE && col < POWERTABLE_WATT_SIZE; k++){ +// if(this->tableRow[row].tableEntry[col].targetPosition != INT16_MIN){ +// x.push_back(col); +// y.push_back(this->tableRow[row].tableEntry[col].targetPosition); +// } +// row--; +// col++; +// } +// if (x.size() >= 2) { //Need at least 2 points for linear, 3 for quadratic +// tempValue = polynomialExtrapolation(x, y, j, 2); // Use quadratic. Change to 1 for linear. +// if (!std::isnan(tempValue) && testNeighbors(i, j, static_cast(tempValue)).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = static_cast(tempValue); +// } +// } +// } +// } +// } +// } +// } int PowerTable::getNumEntries() { int ret = 0; for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { @@ -988,7 +1144,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "k: (%d) leftNeighbor.i: (%d)", k, testResults.leftNeighbor.i); SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed at: (%d) Target pos: (%f)", testResults.leftNeighbor.targetPosition, targetPosition); - if (testResults.leftNeighbor.targetPosition < targetPosition + HORIZONTAL_NEIGHBOR_RANGE){ + if (testResults.leftNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE){ // && (int)targetPosition != testResults.leftNeighbor.targetPosition) { // check if the cadence is the same and positions are within a set range in this case its 30. avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average @@ -1041,7 +1197,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "k: (%d) rightNeighbor.i: (%d)", k, testResults.rightNeighbor.i); SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed at: (%d) Target pos: (%f)", testResults.rightNeighbor.targetPosition, targetPosition); - if (testResults.rightNeighbor.targetPosition > targetPosition - VERTICAL_NEIGHBOR_RANGE){ + if (testResults.rightNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE){ // && (int)targetPosition != testResults.rightNeighbor.targetPosition) { if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, (float)targetPosition).allNeighborsPassed) { @@ -1091,7 +1247,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "i: (%d) topNeighbor.j: (%d)", i, testResults.topNeighbor.j); SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed at: (%d) Target pos: (%f)", testResults.topNeighbor.targetPosition, targetPosition); - if (testResults.topNeighbor.targetPosition > targetPosition - VERTICAL_NEIGHBOR_RANGE){ + if (testResults.topNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE){ // && (int)targetPosition != testResults.topNeighbor.targetPosition) { if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) { @@ -1141,7 +1297,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "i: (%d) bottomNeighbor.j: (%d)", i, testResults.bottomNeighbor.j); SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed at: (%d) Target pos: (%f)", testResults.bottomNeighbor.targetPosition, targetPosition); - if (testResults.bottomNeighbor.targetPosition < targetPosition + HORIZONTAL_NEIGHBOR_RANGE){ + if (testResults.bottomNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE){ // && (int)targetPosition != testResults.bottomNeighbor.targetPosition) { if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) { @@ -1189,18 +1345,18 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(k, i, (int)targetPosition); - if (this->getNumEntries() > 4) { - int entries = 0; - int newEntries = 1; - // loop until we can't calculate any new data - while (entries < newEntries) { - entries = newEntries; - this->fillTable(); - this->extrapFillTable(); - //this->extrapolateDiagonal(); - newEntries = getNumEntries(); - } - } + // if (this->getNumEntries() > 4) { + // int entries = 0; + // int newEntries = 1; + // // loop until we can't calculate any new data + // while (entries < newEntries) { + // entries = newEntries; + // this->fillTable(); + // this->extrapFillTable(); + // this->extrapolateDiagonal(); + // newEntries = getNumEntries(); + // } + // } BLE_ss2kCustomCharacteristic::notify(0x27, k); } @@ -1220,18 +1376,18 @@ void PowerTable::enterData(int i, int j, int pos) { } this->tableRow[i].tableEntry[j].readings++; - // if (this->getNumEntries() > 4) { - // int entries = 0; - // int newEntries = 1; - // // loop until we can't calculate any new data - // while (entries < newEntries) { - // entries = newEntries; - // this->fillTable(); - // this->extrapFillTable(); - // this->extrapolateDiagonal(); - // newEntries = getNumEntries(); - // } - // } + if (this->getNumEntries() > 4) { + int entries = 0; + int newEntries = 1; + // loop until we can't calculate any new data + while (entries < newEntries) { + entries = newEntries; + this->fillTable(); + this->extrapFillTable(); + this->extrapolateDiagonal(); + newEntries = getNumEntries(); + } + } } void PowerTable::downVoteData(int i, int j, float target, int neighbor){ From 3b94fadacdde443a7a0598b1b29c23ec5033bc7f Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Tue, 25 Feb 2025 21:07:18 -0600 Subject: [PATCH 082/451] added calculation for neighbor range --- include/settings.h | 7 ++-- src/Power_Table.cpp | 98 +++++++++++++++++++++++---------------------- 2 files changed, 55 insertions(+), 50 deletions(-) diff --git a/include/settings.h b/include/settings.h index 62235202..474fea15 100644 --- a/include/settings.h +++ b/include/settings.h @@ -305,13 +305,14 @@ const char* const DEFAULT_PASSWORD = "password"; // Limit power table size to save memory #define TABLE_DIVISOR 100.0 -#define PT_READING_RANGE 15 +// Adds onto ERG_SENSITIVITY +#define PT_READING_RANGE 10.0 //Max distance a failed neighbor can be horizontally from target position -#define HORIZONTAL_NEIGHBOR_RANGE 30 +#define HORIZONTAL_NEIGHBOR_RANGE 0.6 //Max distance a failed neighbr can be vertically from target position -#define VERTICAL_NEIGHBOR_RANGE 10 +#define VERTICAL_NEIGHBOR_RANGE 0.8 // Temperature of the ESP32 at which to start reducing the power output of the stepper motor driver. #define THROTTLE_TEMP 90 diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index acdc8148..21c69910 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -61,7 +61,7 @@ void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, int currentPos = ss2k->getCurrentPosition() / TABLE_DIVISOR; int targetPos = powerBuffer.powerEntry[0].targetPosition; - int range = PT_READING_RANGE; + int range = PT_READING_RANGE + ERG_SENSITIVITY; if ( currentPos >= ( targetPos - range) && currentPos <= (targetPos + range)) { for (int i = 1; i < POWER_SAMPLES; i++) { @@ -1089,6 +1089,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { float watts = 0; float cad = 0; float targetPosition = 0; + int avgPosition = 0; // First, take the power buffer and average all of the samples together. int validEntries = 0; @@ -1137,17 +1138,24 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { TestResults testResults = this->testNeighbors(k, i, targetPosition); if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { - int avgPosition; // test which bit fields didn't match if (!testResults.leftNeighbor.passedTest) { - SS2K_LOG(POWERTABLE_LOG_TAG, "k: (%d) leftNeighbor.i: (%d)", k, testResults.leftNeighbor.i); - SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed at: (%d) Target pos: (%f)", testResults.leftNeighbor.targetPosition, targetPosition); + avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average + + SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.leftNeighbor.targetPosition, targetPosition, avgPosition); - if (testResults.leftNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE){ + if (testResults.leftNeighbor.targetPosition <= targetPosition + (500 * pow(TABLE_DIVISOR, -HORIZONTAL_NEIGHBOR_RANGE))){ // && (int)targetPosition != testResults.leftNeighbor.targetPosition) { // check if the cadence is the same and positions are within a set range in this case its 30. - avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average + SS2K_LOG(POWERTABLE_LOG_TAG, "Range: (%f)", (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE))); + + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { // checks if the avg position with the current watts and cadence is valid + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); + + this->enterData(k, i, avgPosition); + + } if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) { // check if the current position moved left is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %f", targetPosition); @@ -1156,13 +1164,6 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } - if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { // checks if the avg position with the current watts and cadence is valid - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - - this->enterData(k, i, avgPosition); - - } - if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition) .allNeighborsPassed) { // checks if the failed nighbor is valid with the right neighbors cadence and watts SS2K_LOG(POWERTABLE_LOG_TAG, "Left Neighbors position was valid with Right Neighbors cadence and watts! Left Neighbor Position: %d", @@ -1194,11 +1195,19 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; - SS2K_LOG(POWERTABLE_LOG_TAG, "k: (%d) rightNeighbor.i: (%d)", k, testResults.rightNeighbor.i); - SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed at: (%d) Target pos: (%f)", testResults.rightNeighbor.targetPosition, targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.rightNeighbor.targetPosition, targetPosition, avgPosition); - if (testResults.rightNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE){ - // && (int)targetPosition != testResults.rightNeighbor.targetPosition) { + if (testResults.rightNeighbor.targetPosition >= targetPosition - (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE))){ + // && (int)targetPosition != testResults.rightNeighbor.targetPosition) { + + SS2K_LOG(POWERTABLE_LOG_TAG, "Range: (%f)", (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE))); + + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); + + this->enterData(k, i, avgPosition); + + } if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, (float)targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved right was valid! Current position: %f", targetPosition); @@ -1207,13 +1216,6 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } - if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - - this->enterData(k, i, avgPosition); - - } - if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Right Neighbors position was valid with Left Neighbors cadence and watts! Right Neighbor Position: %d", testResults.rightNeighbor.targetPosition); @@ -1244,19 +1246,13 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; - SS2K_LOG(POWERTABLE_LOG_TAG, "i: (%d) topNeighbor.j: (%d)", i, testResults.topNeighbor.j); - SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed at: (%d) Target pos: (%f)", testResults.topNeighbor.targetPosition, targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.topNeighbor.targetPosition, targetPosition, avgPosition); - if (testResults.topNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE){ - // && (int)targetPosition != testResults.topNeighbor.targetPosition) { - - if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); - - this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); - - } + if (testResults.topNeighbor.targetPosition >= targetPosition - (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE))){ + // && (int)targetPosition != testResults.topNeighbor.targetPosition) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Range: (%f)", (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE))); + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); @@ -1264,11 +1260,18 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } + if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); + + this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); + + } + if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Top Neighbors position was valid with Bottom Neighbors cadence and watts! Top Neighbor Position: %d", testResults.topNeighbor.targetPosition); - this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); + this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); } @@ -1294,18 +1297,12 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; - SS2K_LOG(POWERTABLE_LOG_TAG, "i: (%d) bottomNeighbor.j: (%d)", i, testResults.bottomNeighbor.j); - SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed at: (%d) Target pos: (%f)", testResults.bottomNeighbor.targetPosition, targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.bottomNeighbor.targetPosition, targetPosition, avgPosition); - if (testResults.bottomNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE){ + if (testResults.bottomNeighbor.targetPosition <= targetPosition + (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE))){ // && (int)targetPosition != testResults.bottomNeighbor.targetPosition) { - - if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved down is valid! Current position: %f", targetPosition); - - this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); - - } + + SS2K_LOG(POWERTABLE_LOG_TAG, "Range: (%f)", (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE))); if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); @@ -1313,6 +1310,13 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(k, i, avgPosition); } + + if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved down is valid! Current position: %f", targetPosition); + + this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); + + } if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom Neighbors position was valid with Top Neighbors cadence and watts! Bottom Neighbor Position: %d", @@ -1397,7 +1401,7 @@ void PowerTable::downVoteData(int i, int j, float target, int neighbor){ // make sure downvotes isn't at max if (this->tableRow[i].tableEntry[j].readings > MAX_NEIGHBOR_WEIGHT) { this->tableRow[i].tableEntry[j].readings = MAX_NEIGHBOR_WEIGHT; - penalty = 0; + penalty = 0; } this->tableRow[i].tableEntry[j].readings -= penalty; SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed (%d)(%d)(%d), readings (%d)", i, j, From 5b7adb7ba109ea446cb59a4a40a21b8184c5b34b Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Tue, 25 Feb 2025 21:21:52 -0600 Subject: [PATCH 083/451] implemented new constraint for getting readings and deleted old version --- include/settings.h | 11 +++++++---- src/Power_Table.cpp | 18 +++++++----------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/include/settings.h b/include/settings.h index ebed625e..c772c9b3 100644 --- a/include/settings.h +++ b/include/settings.h @@ -305,11 +305,14 @@ const char* const DEFAULT_PASSWORD = "password"; // Limit power table size to save memory #define TABLE_DIVISOR 100.0 -//Max distance a failed neighbor can be horizontally from target position -#define HORIZONTAL_NEIGHBOR_RANGE 20 +// Adds onto ERG_SENSITIVITY +#define PT_READING_RANGE 10.0 -//Max distance a failed neighbor can be vertically from target position -#define VERTICAL_NEIGHBOR_RANGE 10 +//Max distance a failed neighbor can be horizontally from target position +#define HORIZONTAL_NEIGHBOR_RANGE 0.6 + +//Max distance a failed neighbr can be vertically from target position +#define VERTICAL_NEIGHBOR_RANGE 0.8 // Temperature of the ESP32 at which to start reducing the power output of the stepper motor driver. #define THROTTLE_TEMP 90 diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 47d5611d..fb06fbf3 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -44,27 +44,23 @@ int PowerBuffer::getReadings() { } void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, - Measurement watts) { // this basically checks the constaraints and if everything is good it adds it into the powerbuffer. no need to change - static int calcStep; // calcStep is the percentage range of the stepper motor + Measurement watts) { if ((cadence >= (MINIMUM_TABLE_CAD - (POWERTABLE_CAD_INCREMENT / 2))) && (cadence <= (MINIMUM_TABLE_CAD + (POWERTABLE_CAD_INCREMENT * POWERTABLE_CAD_SIZE) - (POWERTABLE_CAD_SIZE / 2))) && (watts.getValue() > 10) && // adding constraints (watts.getValue() < (POWERTABLE_WATT_SIZE * POWERTABLE_WATT_INCREMENT))) { - if (rtConfig->getMaxStep() == DEFAULT_STEPPER_TRAVEL && rtConfig->getMinStep() == -DEFAULT_STEPPER_TRAVEL) { - int totalStep = ((rtConfig->getMaxStep() - rtConfig->getMaxStep() / 2000000)); // stepper distance is 400,000,000 so dividing it by 2,000,000 gives us 200 - calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range - } else if (rtConfig->getHomed()) { - int totalStep = (rtConfig->getMaxStep() / TABLE_DIVISOR); // maxStep should be around 22000 / TABLE_DIVISOR gives us 200ish - calcStep = totalStep * 0.05; // 5% of that would give us around a 10 positive and negative range - } if (powerBuffer.powerEntry[0].readings == 0) { // we need to make sure stepper position is not negative so it only takes positive resistance values // Take Initial reading powerBuffer.set(0); // Check if the current stepper posistion is within a 5% range of the previous stepper position and that the current position is not negative } - if (((ss2k->getCurrentPosition() / TABLE_DIVISOR) >= ((powerBuffer.powerEntry[0].targetPosition) - calcStep)) && - ((ss2k->getCurrentPosition() / TABLE_DIVISOR) <= ((powerBuffer.powerEntry[0].targetPosition) + calcStep))) { + + int currentPos = ss2k->getCurrentPosition() / TABLE_DIVISOR; + int targetPos = powerBuffer.powerEntry[0].targetPosition; + int range = PT_READING_RANGE + ERG_SENSITIVITY; + + if ( currentPos >= ( targetPos - range) && currentPos <= (targetPos + range)) { for (int i = 1; i < POWER_SAMPLES; i++) { if (powerBuffer.powerEntry[i].readings == 0) { SS2K_LOG(POWERTABLE_LOG_TAG, "Success!"); From a03d5436159a26048a08837d2260055c269ea3ca Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Wed, 26 Feb 2025 12:27:22 -0600 Subject: [PATCH 084/451] rewrote newEntry with revised neighbor moving --- src/Power_Table.cpp | 232 +++++++++++++++++++++----------------------- 1 file changed, 112 insertions(+), 120 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index fb06fbf3..51aaebf4 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -708,6 +708,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { float watts = 0; float cad = 0; float targetPosition = 0; + int avgPosition = 0; // First, take the power buffer and average all of the samples together. int validEntries = 0; @@ -755,205 +756,198 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table TestResults testResults = this->testNeighbors(k, i, targetPosition); if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { + // test which bit fields didn't match if (!testResults.leftNeighbor.passedTest) { - if (testResults.leftNeighbor.i == k && - (testResults.leftNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE && - testResults.leftNeighbor.targetPosition >= targetPosition)) { // check if the cadence is the same and positions are within a set range in this case its 30. - SS2K_LOG(POWERTABLE_LOG_TAG, "Cadence is the same and targetPosition is within range"); - int avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); + avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average + + SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.leftNeighbor.targetPosition, targetPosition, avgPosition); + + if (testResults.leftNeighbor.targetPosition <= targetPosition + (500 * pow(TABLE_DIVISOR, -HORIZONTAL_NEIGHBOR_RANGE)) && (int)targetPosition != testResults.leftNeighbor.targetPosition) { // check if the cadence is the same and positions are within a set range in this case its 30. + + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { // checks if the avg position with the current watts and cadence is valid + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); + + this->enterData(k, i, avgPosition); + } + if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) { // check if the current position moved left is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %f", targetPosition); - this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); // enter the data - } - // else { - // if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings != 0) - // { - // this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - // } - // } - - if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { // checks if the avg position with the current watts and cadence is valid - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - this->enterData(k, i, avgPosition); // enter the data + + this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); // enter the data + } - // else { - // if(this->tableRow[k].tableEntry[i].readings != 0){ - // this->tableRow[k].tableEntry[i].readings--; - // } - // } if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition) .allNeighborsPassed) { // checks if the failed nighbor is valid with the right neighbors cadence and watts SS2K_LOG(POWERTABLE_LOG_TAG, "Left Neighbors position was valid with Right Neighbors cadence and watts! Left Neighbor Position: %d", testResults.leftNeighbor.targetPosition); - this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition); + + this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition); + } - // else { - // if(this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings != 0){ - // this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - // } - // } - // still downvote data if all the tests fail + //still downvote data if all the tests fail if(!((this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) || (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition).allNeighborsPassed))) { - this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, + testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + //this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); } } else { - this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, + testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + //this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); } } if (!testResults.rightNeighbor.passedTest) { - if (testResults.rightNeighbor.i == k && (testResults.rightNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE - && testResults.rightNeighbor.targetPosition <= targetPosition)) { - int avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) { + avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; + + SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.rightNeighbor.targetPosition, targetPosition, avgPosition); + + if (testResults.rightNeighbor.targetPosition >= targetPosition - (500 * pow(TABLE_DIVISOR, -HORIZONTAL_NEIGHBOR_RANGE)) && (int)targetPosition != testResults.rightNeighbor.targetPosition) { + + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); + + this->enterData(k, i, avgPosition); + + } + + if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, (float)targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved right was valid! Current position: %f", targetPosition); - this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); - } - // else { - // if(this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings != 0){ - // this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - // } - // } - if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - this->enterData(k, i, avgPosition); + this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); + } - // else { - // if(this->tableRow[k].tableEntry[i].readings != 0){ - // this->tableRow[k].tableEntry[i].readings--; - // } - // } if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Right Neighbors position was valid with Left Neighbors cadence and watts! Right Neighbor Position: %d", testResults.rightNeighbor.targetPosition); - this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition); + + this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition); + } - // else { - // if(this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings != 0){ - // this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - // } - // } - // still downvote data if all the tests fail + // still downvote data if all the tests fail if(!((this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) || (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed))) { - this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, + testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + //this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); } } else { - this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, + testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + //this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); } } if (!testResults.topNeighbor.passedTest) { - if (testResults.topNeighbor.j == i && (testResults.topNeighbor.targetPosition >= targetPosition - VERTICAL_NEIGHBOR_RANGE - && testResults.topNeighbor.targetPosition <= targetPosition)) { - int avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); - this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); - } - // else { - // if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings != 0){ - // this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - // } - // } + avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; + SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.topNeighbor.targetPosition, targetPosition, avgPosition); + + if (testResults.topNeighbor.targetPosition >= targetPosition - (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE)) && (int)targetPosition != testResults.topNeighbor.targetPosition) { + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - this->enterData(k, i, avgPosition); + + this->enterData(k, i, avgPosition); + } - // else { - // if(this->tableRow[k].tableEntry[i].readings != 0){ - // this->tableRow[k].tableEntry[i].readings--; - // } - // } + + if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); + + this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); + + } if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Top Neighbors position was valid with Bottom Neighbors cadence and watts! Top Neighbor Position: %d", testResults.topNeighbor.targetPosition); - this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); + + this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); + } - // else { - // if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings != 0){ - // this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - // } - // } - // still downvote data if all the tests fail + //still downvote data if all the tests fail if(!((this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) || (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed))) { - this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, + testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + //this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); } } else { - this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, + testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + //this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); } } if (!testResults.bottomNeighbor.passedTest) { - if (testResults.bottomNeighbor.j == i && (testResults.bottomNeighbor.targetPosition <= targetPosition + HORIZONTAL_NEIGHBOR_RANGE && - testResults.bottomNeighbor.targetPosition >= targetPosition)) { - int avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg position: %d", avgPosition); - if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); - this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); - } - // else { - // if(this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings != 0){ - // this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - // } - // } + avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; + + SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.bottomNeighbor.targetPosition, targetPosition, avgPosition); + + if (testResults.bottomNeighbor.targetPosition <= targetPosition + (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE)) && (int)targetPosition != testResults.bottomNeighbor.targetPosition) { if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - this->enterData(k, i, avgPosition); + + this->enterData(k, i, avgPosition); + + } + + if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved down is valid! Current position: %f", targetPosition); + + this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); + } - // else { - // if(this->tableRow[k].tableEntry[i].readings != 0){ - // this->tableRow[k].tableEntry[i].readings--; - // } - // } if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom Neighbors position was valid with Top Neighbors cadence and watts! Bottom Neighbor Position: %d", testResults.topNeighbor.targetPosition); - this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition); + + this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition); + } - // else { - // if(this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings != 0){ - // this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - // } - // } - // still downvote data if all the tests fail + // still downvote data if all the tests fail if(!((this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) || (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed))) { - this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed bottom (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, + testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + //this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); } } else { - this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); + SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, + testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + //this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); } } return; @@ -961,9 +955,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { this->enterData(k, i, (int)targetPosition); - //this->tableRow[k].tableEntry[i].readings++; - // Attempt to fill the table with calculated data... // if (this->getNumEntries() > 4) { // int entries = 0; // int newEntries = 1; @@ -976,7 +968,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { // newEntries = getNumEntries(); // } // } - // Notify connected client of new data + BLE_ss2kCustomCharacteristic::notify(0x27, k); } From 8392cef338db8a41e23794a855088fc568ea3e98 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Wed, 26 Feb 2025 17:11:07 -0600 Subject: [PATCH 085/451] rewrote cubic spline interpolation using spine.h library --- include/spline.h | 683 +++++++++++++++++++++++++++++++++++ src/Power_Table.cpp | 855 ++++++++++++++++++++------------------------ 2 files changed, 1069 insertions(+), 469 deletions(-) create mode 100644 include/spline.h diff --git a/include/spline.h b/include/spline.h new file mode 100644 index 00000000..4922c442 --- /dev/null +++ b/include/spline.h @@ -0,0 +1,683 @@ +/* + * spline.h + * + * simple cubic spline interpolation library without external + * dependencies + * + * --------------------------------------------------------------------- + * Copyright (C) 2011, 2014, 2016, 2021 Tino Kluge (ttk448 at gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * --------------------------------------------------------------------- + * + */ + + + #ifndef TK_SPLINE_H + #define TK_SPLINE_H + + #include + #include + #include + #include + #include + #ifdef HAVE_SSTREAM + #include + #include + #endif // HAVE_SSTREAM + + // not ideal but disable unused-function warnings + // (we get them because we have implementations in the header file, + // and this is because we want to be able to quickly separate them + // into a cpp file if necessary) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-function" + + // unnamed namespace only because the implementation is in this + // header file and we don't want to export symbols to the obj files + namespace + { + + namespace tk + { + + // spline interpolation + class spline + { + public: + // spline types + enum spline_type { + linear = 10, // linear interpolation + cspline = 30, // cubic splines (classical C^2) + cspline_hermite = 31 // cubic hermite splines (local, only C^1) + }; + + // boundary condition type for the spline end-points + enum bd_type { + first_deriv = 1, + second_deriv = 2 + }; + + protected: + std::vector m_x,m_y; // x,y coordinates of points + // interpolation parameters + // f(x) = a_i + b_i*(x-x_i) + c_i*(x-x_i)^2 + d_i*(x-x_i)^3 + // where a_i = y_i, or else it won't go through grid points + std::vector m_b,m_c,m_d; // spline coefficients + double m_c0; // for left extrapolation + spline_type m_type; + bd_type m_left, m_right; + double m_left_value, m_right_value; + bool m_made_monotonic; + void set_coeffs_from_b(); // calculate c_i, d_i from b_i + size_t find_closest(double x) const; // closest idx so that m_x[idx]<=x + + public: + // default constructor: set boundary condition to be zero curvature + // at both ends, i.e. natural splines + spline(): m_type(cspline), + m_left(second_deriv), m_right(second_deriv), + m_left_value(0.0), m_right_value(0.0), m_made_monotonic(false) + { + ; + } + spline(const std::vector& X, const std::vector& Y, + spline_type type = cspline, + bool make_monotonic = false, + bd_type left = second_deriv, double left_value = 0.0, + bd_type right = second_deriv, double right_value = 0.0 + ): + m_type(type), + m_left(left), m_right(right), + m_left_value(left_value), m_right_value(right_value), + m_made_monotonic(false) // false correct here: make_monotonic() sets it + { + this->set_points(X,Y,m_type); + if(make_monotonic) { + this->make_monotonic(); + } + } + + + // modify boundary conditions: if called it must be before set_points() + void set_boundary(bd_type left, double left_value, + bd_type right, double right_value); + + // set all data points (cubic_spline=false means linear interpolation) + void set_points(const std::vector& x, + const std::vector& y, + spline_type type=cspline); + + // adjust coefficients so that the spline becomes piecewise monotonic + // where possible + // this is done by adjusting slopes at grid points by a non-negative + // factor and this will break C^2 + // this can also break boundary conditions if adjustments need to + // be made at the boundary points + // returns false if no adjustments have been made, true otherwise + bool make_monotonic(); + + // evaluates the spline at point x + double operator() (double x) const; + double deriv(int order, double x) const; + + // returns the input data points + std::vector get_x() const { return m_x; } + std::vector get_y() const { return m_y; } + double get_x_min() const { assert(!m_x.empty()); return m_x.front(); } + double get_x_max() const { assert(!m_x.empty()); return m_x.back(); } + + #ifdef HAVE_SSTREAM + // spline info string, i.e. spline type, boundary conditions etc. + std::string info() const; + #endif // HAVE_SSTREAM + + }; + + + + namespace internal + { + + // band matrix solver + class band_matrix + { + private: + std::vector< std::vector > m_upper; // upper band + std::vector< std::vector > m_lower; // lower band + public: + band_matrix() {}; // constructor + band_matrix(int dim, int n_u, int n_l); // constructor + ~band_matrix() {}; // destructor + void resize(int dim, int n_u, int n_l); // init with dim,n_u,n_l + int dim() const; // matrix dimension + int num_upper() const + { + return (int)m_upper.size()-1; + } + int num_lower() const + { + return (int)m_lower.size()-1; + } + // access operator + double & operator () (int i, int j); // write + double operator () (int i, int j) const; // read + // we can store an additional diagonal (in m_lower) + double& saved_diag(int i); + double saved_diag(int i) const; + void lu_decompose(); + std::vector r_solve(const std::vector& b) const; + std::vector l_solve(const std::vector& b) const; + std::vector lu_solve(const std::vector& b, + bool is_lu_decomposed=false); + + }; + + } // namespace internal + + + + + // --------------------------------------------------------------------- + // implementation part, which could be separated into a cpp file + // --------------------------------------------------------------------- + + // spline implementation + // ----------------------- + + void spline::set_boundary(spline::bd_type left, double left_value, + spline::bd_type right, double right_value) + { + assert(m_x.size()==0); // set_points() must not have happened yet + m_left=left; + m_right=right; + m_left_value=left_value; + m_right_value=right_value; + } + + + void spline::set_coeffs_from_b() + { + assert(m_x.size()==m_y.size()); + assert(m_x.size()==m_b.size()); + assert(m_x.size()>2); + size_t n=m_b.size(); + if(m_c.size()!=n) + m_c.resize(n); + if(m_d.size()!=n) + m_d.resize(n); + + for(size_t i=0; i& x, + const std::vector& y, + spline_type type) + { + assert(x.size()==y.size()); + assert(x.size()>2); + m_type=type; + m_made_monotonic=false; + m_x=x; + m_y=y; + int n = (int) x.size(); + // check strict monotonicity of input vector x + for(int i=0; i rhs(n); + for(int i=1; i2); + bool modified = false; + const int n=(int)m_x.size(); + // make sure: input data monotonic increasing --> b_i>=0 + // input data monotonic decreasing --> b_i<=0 + for(int i=0; i=m_y[i]) && (m_y[i]>=m_y[ip1]) && m_b[i]>0.0) ) { + modified=true; + m_b[i]=0.0; + } + } + // if input data is monotonic (b[i], b[i+1], avg have all the same sign) + // ensure a sufficient criteria for monotonicity is satisfied: + // sqrt(b[i]^2+b[i+1]^2) <= 3 |avg|, with avg=(y[i+1]-y[i])/h, + for(int i=0; i=0.0 && m_b[i+1]>=0.0 && avg>0.0) || + (m_b[i]<=0.0 && m_b[i+1]<=0.0 && avg<0.0) ) { + // input data is monotonic + double r = sqrt(m_b[i]*m_b[i]+m_b[i+1]*m_b[i+1])/std::fabs(avg); + if(r>3.0) { + // sufficient criteria for monotonicity: r<=3 + // adjust b[i] and b[i+1] + modified=true; + m_b[i] *= (3.0/r); + m_b[i+1] *= (3.0/r); + } + } + } + + if(modified==true) { + set_coeffs_from_b(); + m_made_monotonic=true; + } + + return modified; + } + + // return the closest idx so that m_x[idx] <= x (return 0 if x::const_iterator it; + it=std::upper_bound(m_x.begin(),m_x.end(),x); // *it > x + size_t idx = std::max( int(it-m_x.begin())-1, 0); // m_x[idx] <= x + return idx; + } + + double spline::operator() (double x) const + { + // polynomial evaluation using Horner's scheme + // TODO: consider more numerically accurate algorithms, e.g.: + // - Clenshaw + // - Even-Odd method by A.C.R. Newbery + // - Compensated Horner Scheme + size_t n=m_x.size(); + size_t idx=find_closest(x); + + double h=x-m_x[idx]; + double interpol; + if(xm_x[n-1]) { + // extrapolation to the right + interpol=(m_c[n-1]*h + m_b[n-1])*h + m_y[n-1]; + } else { + // interpolation + interpol=((m_d[idx]*h + m_c[idx])*h + m_b[idx])*h + m_y[idx]; + } + return interpol; + } + + double spline::deriv(int order, double x) const + { + assert(order>0); + size_t n=m_x.size(); + size_t idx = find_closest(x); + + double h=x-m_x[idx]; + double interpol; + if(xm_x[n-1]) { + // extrapolation to the right + switch(order) { + case 1: + interpol=2.0*m_c[n-1]*h + m_b[n-1]; + break; + case 2: + interpol=2.0*m_c[n-1]; + break; + default: + interpol=0.0; + break; + } + } else { + // interpolation + switch(order) { + case 1: + interpol=(3.0*m_d[idx]*h + 2.0*m_c[idx])*h + m_b[idx]; + break; + case 2: + interpol=6.0*m_d[idx]*h + 2.0*m_c[idx]; + break; + case 3: + interpol=6.0*m_d[idx]; + break; + default: + interpol=0.0; + break; + } + } + return interpol; + } + + #ifdef HAVE_SSTREAM + std::string spline::info() const + { + std::stringstream ss; + ss << "type " << m_type << ", left boundary deriv " << m_left << " = "; + ss << m_left_value << ", right boundary deriv " << m_right << " = "; + ss << m_right_value << std::endl; + if(m_made_monotonic) { + ss << "(spline has been adjusted for piece-wise monotonicity)"; + } + return ss.str(); + } + #endif // HAVE_SSTREAM + + + namespace internal + { + + // band_matrix implementation + // ------------------------- + + band_matrix::band_matrix(int dim, int n_u, int n_l) + { + resize(dim, n_u, n_l); + } + void band_matrix::resize(int dim, int n_u, int n_l) + { + assert(dim>0); + assert(n_u>=0); + assert(n_l>=0); + m_upper.resize(n_u+1); + m_lower.resize(n_l+1); + for(size_t i=0; i0) { + return m_upper[0].size(); + } else { + return 0; + } + } + + + // defines the new operator (), so that we can access the elements + // by A(i,j), index going from i=0,...,dim()-1 + double & band_matrix::operator () (int i, int j) + { + int k=j-i; // what band is the entry + assert( (i>=0) && (i=0) && (j diagonal, k<0 lower left part, k>0 upper right part + if(k>=0) return m_upper[k][i]; + else return m_lower[-k][i]; + } + double band_matrix::operator () (int i, int j) const + { + int k=j-i; // what band is the entry + assert( (i>=0) && (i=0) && (j diagonal, k<0 lower left part, k>0 upper right part + if(k>=0) return m_upper[k][i]; + else return m_lower[-k][i]; + } + // second diag (used in LU decomposition), saved in m_lower + double band_matrix::saved_diag(int i) const + { + assert( (i>=0) && (i=0) && (idim(); i++) { + assert(this->operator()(i,i)!=0.0); + this->saved_diag(i)=1.0/this->operator()(i,i); + j_min=std::max(0,i-this->num_lower()); + j_max=std::min(this->dim()-1,i+this->num_upper()); + for(int j=j_min; j<=j_max; j++) { + this->operator()(i,j) *= this->saved_diag(i); + } + this->operator()(i,i)=1.0; // prevents rounding errors + } + + // Gauss LR-Decomposition + for(int k=0; kdim(); k++) { + i_max=std::min(this->dim()-1,k+this->num_lower()); // num_lower not a mistake! + for(int i=k+1; i<=i_max; i++) { + assert(this->operator()(k,k)!=0.0); + x=-this->operator()(i,k)/this->operator()(k,k); + this->operator()(i,k)=-x; // assembly part of L + j_max=std::min(this->dim()-1,k+this->num_upper()); + for(int j=k+1; j<=j_max; j++) { + // assembly part of R + this->operator()(i,j)=this->operator()(i,j)+x*this->operator()(k,j); + } + } + } + } + // solves Ly=b + std::vector band_matrix::l_solve(const std::vector& b) const + { + assert( this->dim()==(int)b.size() ); + std::vector x(this->dim()); + int j_start; + double sum; + for(int i=0; idim(); i++) { + sum=0; + j_start=std::max(0,i-this->num_lower()); + for(int j=j_start; joperator()(i,j)*x[j]; + x[i]=(b[i]*this->saved_diag(i)) - sum; + } + return x; + } + // solves Rx=y + std::vector band_matrix::r_solve(const std::vector& b) const + { + assert( this->dim()==(int)b.size() ); + std::vector x(this->dim()); + int j_stop; + double sum; + for(int i=this->dim()-1; i>=0; i--) { + sum=0; + j_stop=std::min(this->dim()-1,i+this->num_upper()); + for(int j=i+1; j<=j_stop; j++) sum += this->operator()(i,j)*x[j]; + x[i]=( b[i] - sum ) / this->operator()(i,i); + } + return x; + } + + std::vector band_matrix::lu_solve(const std::vector& b, + bool is_lu_decomposed) + { + assert( this->dim()==(int)b.size() ); + std::vector x,y; + if(is_lu_decomposed==false) { + this->lu_decompose(); + } + y=this->l_solve(b); + x=this->r_solve(y); + return x; + } + + } // namespace internal + + + } // namespace tk + + + } // namespace + + #pragma GCC diagnostic pop + + #endif /* TK_SPLINE_H */ \ No newline at end of file diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 21c69910..ce261057 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -9,6 +9,7 @@ #include "SS2KLog.h" #include "BLE_Custom_Characteristic.h" #include +#include #include #include #include @@ -344,67 +345,98 @@ TestResults PowerTable::testNeighbors(int i, int j, int testValue) { return returnResult; } -double polynomialInterpolation(const std::vector>& data, double x) { - int n = data.size(); - if (n == 0) return std::numeric_limits::quiet_NaN(); // Handle empty data +// struct SplineCoefficients { +// std::vector a, b, c, d, x; +// }; - double result = 0.0; - for (int i = 0; i < n; ++i) { - double term = data[i].second; // y_i - for (int j = 0; j < n; ++j) { - if (i != j) { - term *= (x - data[j].first) / (data[i].first - data[j].first); // Calculate Lagrange basis polynomial - } - } - result += term; - } - return result; -} +// SplineCoefficients computeCubicSpline(const std::vector& x, const std::vector& y) { +// int n = x.size() - 1; +// std::vector interval_widths(n), alpha(n), l(n + 1), mu(n), z(n + 1); +// std::vector a(y), b(n), c(n + 1), d(n); -// void PowerTable::fillTable() { -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// std::vector> data; +// for (int i = 0; i < n; ++i) { +// interval_widths[i] = x[i + 1] - x[i]; +// } -// // Gather data points for interpolation (horizontal) -// for (int k = 0; k < POWERTABLE_WATT_SIZE; ++k) { -// if (this->tableRow[i].tableEntry[k].targetPosition != INT16_MIN) { -// data.push_back({static_cast(k * 30), static_cast(this->tableRow[i].tableEntry[k].targetPosition)}); // Power values are multiples of 30 -// } -// } +// for (int i = 1; i < n; ++i) { +// alpha[i] = (3.0 / interval_widths[i]) * (y[i + 1] - y[i]) - (3.0 / interval_widths[i - 1]) * (y[i] - y[i - 1]); +// } + +// l[0] = 1.0; +// mu[0] = z[0] = 0.0; + +// for (int i = 1; i < n; ++i) { +// l[i] = 2.0 * (x[i + 1] - x[i - 1]) - interval_widths[i - 1] * mu[i - 1]; +// mu[i] = interval_widths[i] / l[i]; +// z[i] = (alpha[i] - interval_widths[i - 1] * z[i - 1]) / l[i]; +// } + +// l[n] = 1.0; +// z[n] = c[n] = 0.0; -// if (!data.empty()) { -// double power = j * 30; // Power value for the current cell -// double interpValue = polynomialInterpolation(data, power); +// for (int j = n - 1; j >= 0; --j) { +// c[j] = z[j] - mu[j] * c[j + 1]; +// b[j] = (y[j + 1] - y[j]) / interval_widths[j] - interval_widths[j] * (c[j + 1] + 2.0 * c[j]) / 3.0; +// d[j] = (c[j + 1] - c[j]) / (3.0 * interval_widths[j]); +// } + +// return {a, b, c, d, x}; +// } + +// double interpolateCubicSpline(const SplineCoefficients& spline, double x_val) { +// int n = spline.x.size() - 1; + +// // Binary search to find the correct interval +// auto it = std::lower_bound(spline.x.begin(), spline.x.end(), x_val); +// int i = std::distance(spline.x.begin(), it); +// if (i > 0) { +// i--; +// } else if (i == n) { +// i--; // Handle the case where x_val is equal to the last x +// } -// if (!std::isnan(interpValue) && this->testNeighbors(i, j, static_cast(round(interpValue))).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = static_cast(round(interpValue)); + +// double dx = x_val - spline.x[i]; +// return spline.a[i] + spline.b[i] * dx + spline.c[i] * dx * dx + spline.d[i] * dx * dx * dx; +// } + +// void PowerTable::fillTable() { +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// std::vector x_vals, y_vals; +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { +// x_vals.push_back(j); +// y_vals.push_back(this->tableRow[i].tableEntry[j].targetPosition); +// } +// } +// if (x_vals.size() > 1) { +// SplineCoefficients spline = computeCubicSpline(x_vals, y_vals); +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// double interpolated_value = interpolateCubicSpline(spline, j); +// if (this->testNeighbors(i, j, static_cast(std::round(interpolated_value))).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(interpolated_value)); // } // } // } // } // } -// // Vertical Interpolation (similar structure) // for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// std::vector x_vals, y_vals; // for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// std::vector> data; - -// // Gather data points for interpolation (vertical) -// for (int k = 0; k < POWERTABLE_CAD_SIZE; ++k) { -// if (this->tableRow[k].tableEntry[j].targetPosition != INT16_MIN) { -// data.push_back({static_cast(k), static_cast(this->tableRow[k].tableEntry[j].targetPosition)}); -// } -// } - -// if (!data.empty()) { -// double cadence = i; -// double interpValue = polynomialInterpolation(data, cadence); - -// if (!std::isnan(interpValue) && this->testNeighbors(i, j, static_cast(round(interpValue))).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = static_cast(round(interpValue)); +// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { +// x_vals.push_back(i); +// y_vals.push_back(this->tableRow[i].tableEntry[j].targetPosition); +// } +// } +// if (x_vals.size() > 1) { +// SplineCoefficients spline = computeCubicSpline(x_vals, y_vals); +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// double interpolated_value = interpolateCubicSpline(spline, i); +// if (this->testNeighbors(i, j, static_cast(std::round(interpolated_value))).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(interpolated_value)); // } // } // } @@ -412,150 +444,57 @@ double polynomialInterpolation(const std::vector>& dat // } // } - -void PowerTable::extrapFillTable() { - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - std::vector> data; - - // Gather data points for extrapolation (horizontal) - for (int k = 0; k < POWERTABLE_WATT_SIZE; ++k) { - if (this->tableRow[i].tableEntry[k].targetPosition != INT16_MIN) { - data.push_back({static_cast(k * 30), static_cast(this->tableRow[i].tableEntry[k].targetPosition)}); - } - } - - if (!data.empty()) { - double power = j * 30; - double extrapValue = polynomialInterpolation(data, power); - - if (!std::isnan(extrapValue) && this->testNeighbors(i, j, static_cast(round(extrapValue))).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = static_cast(round(extrapValue)); - } - } - } - } - } - - // Vertical Extrapolation (similar structure) - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - std::vector> data; - - // Gather data points for extrapolation (vertical) - for (int k = 0; k < POWERTABLE_CAD_SIZE; ++k) { - if (this->tableRow[k].tableEntry[j].targetPosition != INT16_MIN) { - data.push_back({static_cast(k), static_cast(this->tableRow[k].tableEntry[j].targetPosition)}); - } - } - - if (!data.empty()) { - double cadence = i; - double extrapValue = polynomialInterpolation(data, cadence); - - if (!std::isnan(extrapValue) && this->testNeighbors(i, j, static_cast(round(extrapValue))).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = static_cast(round(extrapValue)); - } - } - } - } - } -} - -struct SplineCoefficients { - std::vector a, b, c, d, x; -}; - -SplineCoefficients computeCubicSpline(const std::vector& x, const std::vector& y) { - int n = x.size() - 1; - std::vector interval_widths(n), alpha(n), l(n + 1), mu(n), z(n + 1); - std::vector a(y), b(n), c(n + 1), d(n); - - for (int i = 0; i < n; ++i) { - interval_widths[i] = x[i + 1] - x[i]; - } - - for (int i = 1; i < n; ++i) { - alpha[i] = (3.0 / interval_widths[i]) * (y[i + 1] - y[i]) - (3.0 / interval_widths[i - 1]) * (y[i] - y[i - 1]); - } - - l[0] = 1.0; - mu[0] = z[0] = 0.0; - - for (int i = 1; i < n; ++i) { - l[i] = 2.0 * (x[i + 1] - x[i - 1]) - interval_widths[i - 1] * mu[i - 1]; - mu[i] = interval_widths[i] / l[i]; - z[i] = (alpha[i] - interval_widths[i - 1] * z[i - 1]) / l[i]; - } - - l[n] = 1.0; - z[n] = c[n] = 0.0; - - for (int j = n - 1; j >= 0; --j) { - c[j] = z[j] - mu[j] * c[j + 1]; - b[j] = (y[j + 1] - y[j]) / interval_widths[j] - interval_widths[j] * (c[j + 1] + 2.0 * c[j]) / 3.0; - d[j] = (c[j + 1] - c[j]) / (3.0 * interval_widths[j]); - } - - return {a, b, c, d, x}; -} - -double interpolateCubicSpline(const SplineCoefficients& spline, double x_val) { - int n = spline.x.size() - 1; - - // Binary search to find the correct interval - auto it = std::lower_bound(spline.x.begin(), spline.x.end(), x_val); - int i = std::distance(spline.x.begin(), it); - if (i > 0) { - i--; - } else if (i == n) { - i--; // Handle the case where x_val is equal to the last x - } - - - double dx = x_val - spline.x[i]; - return spline.a[i] + spline.b[i] * dx + spline.c[i] * dx * dx + spline.d[i] * dx * dx * dx; -} - void PowerTable::fillTable() { + tk::spline spline_interpolator; // Declare spline object once + + // Perform horizontal cubic spline interpolation for each row for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { std::vector x_vals, y_vals; + x_vals.reserve(POWERTABLE_WATT_SIZE); + y_vals.reserve(POWERTABLE_WATT_SIZE); + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { x_vals.push_back(j); y_vals.push_back(this->tableRow[i].tableEntry[j].targetPosition); } } - if (x_vals.size() > 1) { - SplineCoefficients spline = computeCubicSpline(x_vals, y_vals); + + if (x_vals.size() > 1) { // Only interpolate if we have enough points. might turn into 2 + spline_interpolator.set_points(x_vals, y_vals); + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - double interpolated_value = interpolateCubicSpline(spline, j); - if (this->testNeighbors(i, j, static_cast(std::round(interpolated_value))).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(interpolated_value)); + double interpolated_value = spline_interpolator(j); + if (this->testNeighbors(i, j, interpolated_value).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = static_cast(interpolated_value); } } } } } + // Perform vertical cubic spline interpolation for each column for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { std::vector x_vals, y_vals; + x_vals.reserve(POWERTABLE_CAD_SIZE); + y_vals.reserve(POWERTABLE_CAD_SIZE); + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { x_vals.push_back(i); y_vals.push_back(this->tableRow[i].tableEntry[j].targetPosition); } } - if (x_vals.size() > 1) { - SplineCoefficients spline = computeCubicSpline(x_vals, y_vals); + + if (x_vals.size() > 1) { // Only interpolate if we have enough points + spline_interpolator.set_points(x_vals, y_vals); + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - double interpolated_value = interpolateCubicSpline(spline, i); - if (this->testNeighbors(i, j, static_cast(std::round(interpolated_value))).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(interpolated_value)); + double interpolated_value = spline_interpolator(i); + if (this->testNeighbors(i, j, interpolated_value).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = static_cast(interpolated_value); } } } @@ -563,6 +502,63 @@ void PowerTable::fillTable() { } } +// void PowerTable::fillTable() { +// // Horizontal Interpolation using spline.h +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// std::vector x, y; +// std::vector emptyIndices; + +// // Collect existing data points and empty indices +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { +// x.push_back(j); +// y.push_back(this->tableRow[i].tableEntry[j].targetPosition); +// } else { +// emptyIndices.push_back(j); +// } +// } + +// if (x.size() > 2) { // Need at least three points for cubic spline +// tk::spline s(x, y); + +// // Interpolate and fill empty cells +// for (int j : emptyIndices) { +// int tempValue = static_cast(std::round(s(j))); // Use rounding to avoid truncation errors +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } +// } + +// // Vertical Interpolation using spline.h +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// std::vector x, y; +// std::vector emptyIndices; + +// // Collect existing data points and empty indices +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { +// x.push_back(i); +// y.push_back(this->tableRow[i].tableEntry[j].targetPosition); +// } else { +// emptyIndices.push_back(i); +// } +// } + +// if (x.size() > 2) { // Need at least three points for cubic spline +// tk::spline s(x, y); + +// // Interpolate and fill empty cells +// for (int i : emptyIndices) { +// int tempValue = static_cast(std::round(s(i))); // Use rounding to avoid truncation errors +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } +// } +// } // void PowerTable::fillTable() { // int tempValue = INT16_MIN; @@ -613,275 +609,199 @@ void PowerTable::fillTable() { // } // } -// void PowerTable::extrapFillTable() { -// // Find the center of the known data -// int sumRow = 0, sumCol = 0, count = 0; -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { -// sumRow += i; -// sumCol += j; -// count++; -// } -// } -// } - -// // prevent divide by zero -// if (count == 0) { -// return; -// } - -// int centerRow = sumRow / count; -// int centerCol = sumCol / count; -// int tempValue = INT16_MIN; - -// // Function to extrapolate a single cell based on its neighbors -// auto extrapolateCell = [&](int i, int j) { -// // Find nearest left non-empty cell -// int left = j - 1; -// while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - -// // Find nearest right non-empty cell -// int right = j + 1; -// while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - -// if (left >= 0 && right < POWERTABLE_WATT_SIZE) { -// // Linear extrapolation -// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { -// if (j < left) { -// // Extrapolate to the left -// tempValue = this->tableRow[i].tableEntry[left].targetPosition - -// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } else if (j > right) { -// // Extrapolate to the right -// tempValue = this->tableRow[i].tableEntry[right].targetPosition + -// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// } else if (left - 1 >= 0) { -// // Only left value available, extrapolate to the right -// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { -// tempValue = this->tableRow[i].tableEntry[left].targetPosition + -// (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } else if (right + 1 < POWERTABLE_WATT_SIZE) { -// // Only right value available, extrapolate to the left -// if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { -// tempValue = -// this->tableRow[i].tableEntry[right].targetPosition - -// (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// }; - -// // Extrapolate horizontally and vertically starting from the center -// for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { -// for (int i = centerRow - distance; i <= centerRow + distance; ++i) { -// for (int j = centerCol - distance; j <= centerCol + distance; ++j) { -// if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// extrapolateCell(i, j); -// } -// } -// } -// } -// // Extrapolate each empty cell -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// // Extrapolate horizontally -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// // Find nearest left non-empty cell -// int left = j - 1; -// while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - -// // Find nearest right non-empty cell -// int right = j + 1; -// while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; -// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { -// if (left >= 0 && right < POWERTABLE_WATT_SIZE) { -// // Linear extrapolation -// if (j < left) { -// // Extrapolate to the left -// tempValue = this->tableRow[i].tableEntry[left].targetPosition - -// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } - -// } else if (j > right) { -// // Extrapolate to the right -// tempValue = this->tableRow[i].tableEntry[right].targetPosition + -// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } else if (left >= 1) { -// // Only left value available, extrapolate to the right -// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { -// tempValue = this->tableRow[i].tableEntry[left].targetPosition + -// (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } else if (right + 1 < POWERTABLE_WATT_SIZE) { -// // Only right value available, extrapolate to the left -// if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { -// tempValue = this->tableRow[i].tableEntry[right].targetPosition - -// (right - j) * -// (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// } -// } -// } -// } - -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// // Extrapolate vertically -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// // Find nearest top non-empty cell -// int top = i - 1; -// while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; - -// // Find nearest bottom non-empty cell -// int bottom = i + 1; -// while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; - -// if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { -// // Linear extrapolation -// if (i < top) { -// // Extrapolate upwards -// tempValue = this->tableRow[top].tableEntry[j].targetPosition - -// (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } else if (i > bottom) { -// // Extrapolate downwards -// tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + -// (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } else if (top >= 1) { -// // Only top value available, extrapolate downwards -// if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { -// tempValue = this->tableRow[top].tableEntry[j].targetPosition + -// (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } else { -// } -// } -// } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { -// // Only bottom value available, extrapolate upwards -// if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { -// tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - -// (bottom - i) * -// (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// } -// } -// } -// } - -// void PowerTable::extrapFillTable() { -// int sumRow = 0, sumCol = 0, count = 0; - -// // Find the center of known data points -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { -// sumRow += i; -// sumCol += j; -// count++; -// } -// } -// } - -// if (count == 0) return; // No valid data, nothing to extrapolate - -// int centerRow = sumRow / count; -// int centerCol = sumCol / count; - -// // Lambda function to perform linear extrapolation -// auto extrapolate = [&](int i, int j, bool horizontal) { -// int low = horizontal ? j - 1 : i - 1; -// int high = horizontal ? j + 1 : i + 1; -// int size = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; +void PowerTable::extrapFillTable() { + // Find the center of the known data + int sumRow = 0, sumCol = 0, count = 0; + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + sumRow += i; + sumCol += j; + count++; + } + } + } -// // Find nearest non-empty cells -// while (low >= 0 && (horizontal ? this->tableRow[i].tableEntry[low].targetPosition : this->tableRow[low].tableEntry[j].targetPosition) == INT16_MIN) --low; -// while (high < size && (horizontal ? this->tableRow[i].tableEntry[high].targetPosition : this->tableRow[high].tableEntry[j].targetPosition) == INT16_MIN) ++high; + // prevent divide by zero + if (count == 0) { + return; + } -// if (low >= 0 && high < size) { -// // Interpolation using both sides -// int lowVal = horizontal ? this->tableRow[i].tableEntry[low].targetPosition : this->tableRow[low].tableEntry[j].targetPosition; -// int highVal = horizontal ? this->tableRow[i].tableEntry[high].targetPosition : this->tableRow[high].tableEntry[j].targetPosition; -// int extrapolatedValue = lowVal + (highVal - lowVal) * (horizontal ? (j - low) : (i - low)) / (high - low); + int centerRow = sumRow / count; + int centerCol = sumCol / count; + int tempValue = INT16_MIN; -// if (this->testNeighbors(i, j, extrapolatedValue).allNeighborsPassed) { -// if (horizontal) this->tableRow[i].tableEntry[j].targetPosition = extrapolatedValue; -// else this->tableRow[i].tableEntry[j].targetPosition = extrapolatedValue; -// } -// } else if (low >= 1) { -// // Extrapolate from left/top if only one side is available -// int lowVal = horizontal ? this->tableRow[i].tableEntry[low].targetPosition : this->tableRow[low].tableEntry[j].targetPosition; -// int prevLowVal = horizontal ? this->tableRow[i].tableEntry[low - 1].targetPosition : this->tableRow[low - 1].tableEntry[j].targetPosition; -// int extrapolatedValue = lowVal + (lowVal - prevLowVal) * (horizontal ? (j - low) : (i - low)); - -// if (this->testNeighbors(i, j, extrapolatedValue).allNeighborsPassed) { -// if (horizontal) this->tableRow[i].tableEntry[j].targetPosition = extrapolatedValue; -// else this->tableRow[i].tableEntry[j].targetPosition = extrapolatedValue; -// } -// } else if (high + 1 < size) { -// // Extrapolate from right/bottom if only one side is available -// int highVal = horizontal ? this->tableRow[i].tableEntry[high].targetPosition : this->tableRow[high].tableEntry[j].targetPosition; -// int nextHighVal = horizontal ? this->tableRow[i].tableEntry[high + 1].targetPosition : this->tableRow[high + 1].tableEntry[j].targetPosition; -// int extrapolatedValue = highVal - (nextHighVal - highVal) * (horizontal ? (high - j) : (high - i)); - -// if (this->testNeighbors(i, j, extrapolatedValue).allNeighborsPassed) { -// if (horizontal) this->tableRow[i].tableEntry[j].targetPosition = extrapolatedValue; -// else this->tableRow[i].tableEntry[j].targetPosition = extrapolatedValue; -// } -// } -// }; + // Function to extrapolate a single cell based on its neighbors + auto extrapolateCell = [&](int i, int j) { + // Find nearest left non-empty cell + int left = j - 1; + while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + + // Find nearest right non-empty cell + int right = j + 1; + while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + + if (left >= 0 && right < POWERTABLE_WATT_SIZE) { + // Linear extrapolation + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + if (j < left) { + // Extrapolate to the left + tempValue = this->tableRow[i].tableEntry[left].targetPosition - + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } else if (j > right) { + // Extrapolate to the right + tempValue = this->tableRow[i].tableEntry[right].targetPosition + + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } else if (left - 1 >= 0) { + // Only left value available, extrapolate to the right + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { + tempValue = this->tableRow[i].tableEntry[left].targetPosition + + (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (right + 1 < POWERTABLE_WATT_SIZE) { + // Only right value available, extrapolate to the left + if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + tempValue = + this->tableRow[i].tableEntry[right].targetPosition - + (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + }; + + // Extrapolate horizontally and vertically starting from the center + for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { + for (int i = centerRow - distance; i <= centerRow + distance; ++i) { + for (int j = centerCol - distance; j <= centerCol + distance; ++j) { + if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + extrapolateCell(i, j); + } + } + } + } + // Extrapolate each empty cell + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + // Extrapolate horizontally + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest left non-empty cell + int left = j - 1; + while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + + // Find nearest right non-empty cell + int right = j + 1; + while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + if (left >= 0 && right < POWERTABLE_WATT_SIZE) { + // Linear extrapolation + if (j < left) { + // Extrapolate to the left + tempValue = this->tableRow[i].tableEntry[left].targetPosition - + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } -// // Start from the center and fill missing values in an expanding manner -// for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { -// for (int i = std::max(0, centerRow - distance); i < std::min(POWERTABLE_CAD_SIZE, centerRow + distance + 1); ++i) { -// for (int j = std::max(0, centerCol - distance); j < std::min(POWERTABLE_WATT_SIZE, centerCol + distance + 1); ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// extrapolate(i, j, true); // Try horizontal extrapolation -// extrapolate(i, j, false); // Try vertical extrapolation -// } -// } -// } -// } -// } + } else if (j > right) { + // Extrapolate to the right + tempValue = this->tableRow[i].tableEntry[right].targetPosition + + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (left >= 1) { + // Only left value available, extrapolate to the right + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { + tempValue = this->tableRow[i].tableEntry[left].targetPosition + + (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (right + 1 < POWERTABLE_WATT_SIZE) { + // Only right value available, extrapolate to the left + if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { + tempValue = this->tableRow[i].tableEntry[right].targetPosition - + (right - j) * + (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } + } + } + } + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + // Extrapolate vertically + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest top non-empty cell + int top = i - 1; + while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; + + // Find nearest bottom non-empty cell + int bottom = i + 1; + while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; + + if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { + // Linear extrapolation + if (i < top) { + // Extrapolate upwards + tempValue = this->tableRow[top].tableEntry[j].targetPosition - + (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } else if (i > bottom) { + // Extrapolate downwards + tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + + (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (top >= 1) { + // Only top value available, extrapolate downwards + if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { + tempValue = this->tableRow[top].tableEntry[j].targetPosition + + (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } else { + } + } + } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { + // Only bottom value available, extrapolate upwards + if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { + tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - + (bottom - i) * + (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } + } + } +} void PowerTable::extrapolateDiagonal() { int tempValue = INT16_MIN; @@ -1054,36 +974,6 @@ void PowerTable::clean() { } } -// function for weighted downvoting -int weightedDownVote(int targetValue, int neighborValue) { - // calculate diff between target and neighbor - int delta = abs(targetValue - neighborValue); - int penalty; - float penaltyFactor = 0.2; - - // currently consistently getting a 0 for neighbor value... - SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Target Value: (%d), NeighborValue: (%f)", targetValue, neighborValue); - - // we have a few different options for penalty calculations here, will need to test which works best: - - // linear function, low agression - penalty = round(delta * penaltyFactor); - - // quadratic function, high aggression - // penalty = penaltyFactor * (delta * delta) - - // log function, medium aggression - // penalty = penaltyFactor * log(delta + 1); - - // max penalty is 10 - if (penalty > MAX_NEIGHBOR_WEIGHT) { - penalty = MAX_NEIGHBOR_WEIGHT; - } - - SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Delta: (%d), Penalty: (%f)", delta, penalty); - return penalty; -} - void PowerTable::newEntry(PowerBuffer& powerBuffer) { // these are floats so that we make sure division works correctly. float watts = 0; @@ -1145,10 +1035,9 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.leftNeighbor.targetPosition, targetPosition, avgPosition); - if (testResults.leftNeighbor.targetPosition <= targetPosition + (500 * pow(TABLE_DIVISOR, -HORIZONTAL_NEIGHBOR_RANGE))){ - // && (int)targetPosition != testResults.leftNeighbor.targetPosition) { // check if the cadence is the same and positions are within a set range in this case its 30. + if (testResults.leftNeighbor.targetPosition <= targetPosition + (500 * pow(TABLE_DIVISOR, -HORIZONTAL_NEIGHBOR_RANGE)) && (int)targetPosition != testResults.leftNeighbor.targetPosition) { // check if the cadence is the same and positions are within a set range in this case its 30. - SS2K_LOG(POWERTABLE_LOG_TAG, "Range: (%f)", (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE))); + SS2K_LOG(POWERTABLE_LOG_TAG, "Range: (%f)", (500 * pow(TABLE_DIVISOR, -HORIZONTAL_NEIGHBOR_RANGE))); if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { // checks if the avg position with the current watts and cadence is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); @@ -1197,10 +1086,9 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.rightNeighbor.targetPosition, targetPosition, avgPosition); - if (testResults.rightNeighbor.targetPosition >= targetPosition - (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE))){ - // && (int)targetPosition != testResults.rightNeighbor.targetPosition) { + if (testResults.rightNeighbor.targetPosition >= targetPosition - (500 * pow(TABLE_DIVISOR, -HORIZONTAL_NEIGHBOR_RANGE)) && (int)targetPosition != testResults.rightNeighbor.targetPosition) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Range: (%f)", (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE))); + SS2K_LOG(POWERTABLE_LOG_TAG, "Range: (%f)", (500 * pow(TABLE_DIVISOR, -HORIZONTAL_NEIGHBOR_RANGE))); if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); @@ -1248,8 +1136,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.topNeighbor.targetPosition, targetPosition, avgPosition); - if (testResults.topNeighbor.targetPosition >= targetPosition - (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE))){ - // && (int)targetPosition != testResults.topNeighbor.targetPosition) { + if (testResults.topNeighbor.targetPosition >= targetPosition - (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE)) && (int)targetPosition != testResults.topNeighbor.targetPosition) { SS2K_LOG(POWERTABLE_LOG_TAG, "Range: (%f)", (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE))); @@ -1299,8 +1186,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.bottomNeighbor.targetPosition, targetPosition, avgPosition); - if (testResults.bottomNeighbor.targetPosition <= targetPosition + (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE))){ - // && (int)targetPosition != testResults.bottomNeighbor.targetPosition) { + if (testResults.bottomNeighbor.targetPosition <= targetPosition + (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE)) && (int)targetPosition != testResults.bottomNeighbor.targetPosition) { SS2K_LOG(POWERTABLE_LOG_TAG, "Range: (%f)", (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE))); @@ -1394,6 +1280,37 @@ void PowerTable::enterData(int i, int j, int pos) { } } +// function for weighted downvoting +int weightedDownVote(int targetValue, int neighborValue) { + // calculate diff between target and neighbor + int delta = abs(targetValue - neighborValue); + int penalty; + float penaltyFactor = 0.2; + + // currently consistently getting a 0 for neighbor value... + SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Target Value: (%d), NeighborValue: (%f)", targetValue, neighborValue); + + // we have a few different options for penalty calculations here, will need to test which works best: + + // linear function, low agression + penalty = round(delta * penaltyFactor); + + // quadratic function, high aggression + // penalty = penaltyFactor * (delta * delta) + + // log function, medium aggression + // penalty = penaltyFactor * log(delta + 1); + + // max penalty is 10 + if (penalty > MAX_NEIGHBOR_WEIGHT) { + penalty = MAX_NEIGHBOR_WEIGHT; + } + + SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Delta: (%d), Penalty: (%f)", delta, penalty); + return penalty; +} + + void PowerTable::downVoteData(int i, int j, float target, int neighbor){ // determine penalty amount before applying to failed neighbor int penalty = weightedDownVote(target, neighbor); From b9dd308a5dacc0759589e8f0652c0d04c02018d2 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Wed, 26 Feb 2025 17:19:45 -0600 Subject: [PATCH 086/451] updated spline.h library --- include/spline.h | 270 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 267 insertions(+), 3 deletions(-) diff --git a/include/spline.h b/include/spline.h index 4922c442..5e78a5ab 100644 --- a/include/spline.h +++ b/include/spline.h @@ -66,7 +66,8 @@ // boundary condition type for the spline end-points enum bd_type { first_deriv = 1, - second_deriv = 2 + second_deriv = 2, + not_a_knot = 3 }; protected: @@ -132,6 +133,9 @@ double operator() (double x) const; double deriv(int order, double x) const; + // solves for all x so that: spline(x) = y + std::vector solve(double y, bool ignore_extrapolation=true) const; + // returns the input data points std::vector get_x() const { return m_x; } std::vector get_y() const { return m_y; } @@ -184,6 +188,11 @@ }; + double get_eps(); + + std::vector solve_cubic(double a, double b, double c, double d, + int newton_iter=0); + } // namespace internal @@ -235,7 +244,10 @@ spline_type type) { assert(x.size()==y.size()); - assert(x.size()>2); + assert(x.size()>=3); + // not-a-knot with 3 points has many solutions + if(m_left==not_a_knot || m_right==not_a_knot) + assert(x.size()>=4); m_type=type; m_made_monotonic=false; m_x=x; @@ -267,7 +279,9 @@ // setting up the matrix and right hand side of the equation system // for the parameters b[] - internal::band_matrix A(n,1,1); + int n_upper = (m_left == spline::not_a_knot) ? 2 : 1; + int n_lower = (m_right == spline::not_a_knot) ? 2 : 1; + internal::band_matrix A(n,n_upper,n_lower); std::vector rhs(n); for(int i=1; i spline::solve(double y, bool ignore_extrapolation) const + { + std::vector x; // roots for the entire spline + std::vector root; // roots for each piecewise cubic + const size_t n=m_x.size(); + + // left extrapolation + if(ignore_extrapolation==false) { + root = internal::solve_cubic(m_y[0]-y,m_b[0],m_c0,0.0,1); + for(size_t j=0; j0) ? (m_x[i]-m_x[i-1]) : 0.0; + double eps = internal::get_eps()*512.0*std::min(h,1.0); + if( (-eps<=root[j]) && (root[j]0 && x.back()+eps > new_root) { + x.back()=new_root; // avoid spurious duplicate roots + } else { + x.push_back(new_root); + } + } + } + } + + // right extrapolation + if(ignore_extrapolation==false) { + root = internal::solve_cubic(m_y[n-1]-y,m_b[n-1],m_c[n-1],0.0,1); + for(size_t j=0; j::epsilon(); // __DBL_EPSILON__ + return 2.2204460492503131e-16; // 2^-52 + } + + // solutions for a + b*x = 0 + std::vector solve_linear(double a, double b) + { + std::vector x; // roots + if(b==0.0) { + if(a==0.0) { + // 0*x = 0 + x.resize(1); + x[0] = 0.0; // any x solves it but we need to pick one + return x; + } else { + // 0*x + ... = 0, no solution + return x; + } + } else { + x.resize(1); + x[0] = -a/b; + return x; + } + } + + // solutions for a + b*x + c*x^2 = 0 + std::vector solve_quadratic(double a, double b, double c, + int newton_iter=0) + { + if(c==0.0) { + return solve_linear(a,b); + } + // rescale so that we solve x^2 + 2p x + q = (x+p)^2 + q - p^2 = 0 + double p=0.5*b/c; + double q=a/c; + double discr = p*p-q; + const double eps=0.5*internal::get_eps(); + double discr_err = (6.0*(p*p)+3.0*fabs(q)+fabs(discr))*eps; + + std::vector x; // roots + if(fabs(discr)<=discr_err) { + // discriminant is zero --> one root + x.resize(1); + x[0] = -p; + } else if(discr<0) { + // no root + } else { + // two roots + x.resize(2); + x[0] = -p - sqrt(discr); + x[1] = -p + sqrt(discr); + } + + // improve solution via newton steps + for(size_t i=0; i1e-8) { + x[i] -= f/f1; + } + } + } + + return x; + } + + // solutions for the cubic equation: a + b*x +c*x^2 + d*x^3 = 0 + // this is a naive implementation of the analytic solution without + // optimisation for speed or numerical accuracy + // newton_iter: number of newton iterations to improve analytical solution + // see also + // gsl: gsl_poly_solve_cubic() in solve_cubic.c + // octave: roots.m - via eigenvalues of the Frobenius companion matrix + std::vector solve_cubic(double a, double b, double c, double d, + int newton_iter) + { + if(d==0.0) { + return solve_quadratic(a,b,c,newton_iter); + } + + // convert to normalised form: a + bx + cx^2 + x^3 = 0 + if(d!=1.0) { + a/=d; + b/=d; + c/=d; + } + + // convert to depressed cubic: z^3 - 3pz - 2q = 0 + // via substitution: z = x + c/3 + std::vector z; // roots of the depressed cubic + double p = -(1.0/3.0)*b + (1.0/9.0)*(c*c); + double r = 2.0*(c*c)-9.0*b; + double q = -0.5*a - (1.0/54.0)*(c*r); + double discr=p*p*p-q*q; // discriminant + // calculating numerical round-off errors with assumptions: + // - each operation is precise but each intermediate result x + // when stored has max error of x*eps + // - only multiplication with a power of 2 introduces no new error + // - a,b,c,d and some fractions (e.g. 1/3) have rounding errors eps + // - p_err << |p|, q_err << |q|, ... (this is violated in rare cases) + // would be more elegant to use boost::numeric::interval + const double eps = internal::get_eps(); + double p_err = eps*((3.0/3.0)*fabs(b)+(4.0/9.0)*(c*c)+fabs(p)); + double r_err = eps*(6.0*(c*c)+18.0*fabs(b)+fabs(r)); + double q_err = 0.5*fabs(a)*eps + (1.0/54.0)*fabs(c)*(r_err+fabs(r)*3.0*eps) + + fabs(q)*eps; + double discr_err = (p*p) * (3.0*p_err + fabs(p)*2.0*eps) + + fabs(q) * (2.0*q_err + fabs(q)*eps) + fabs(discr)*eps; + + // depending on the discriminant we get different solutions + if(fabs(discr)<=discr_err) { + // discriminant zero: one or two real roots + if(fabs(p)<=p_err) { + // p and q are zero: single root + z.resize(1); + z[0] = 0.0; // triple root + } else { + z.resize(2); + z[0] = 2.0*q/p; // single root + z[1] = -0.5*z[0]; // double root + } + } else if(discr>0) { + // three real roots: via trigonometric solution + z.resize(3); + double ac = (1.0/3.0) * acos( q/(p*sqrt(p)) ); + double sq = 2.0*sqrt(p); + z[0] = sq * cos(ac); + z[1] = sq * cos(ac-2.0*M_PI/3.0); + z[2] = sq * cos(ac-4.0*M_PI/3.0); + } else if (discr<0.0) { + // single real root: via Cardano's fromula + z.resize(1); + double sgnq = (q >= 0 ? 1 : -1); + double basis = fabs(q) + sqrt(-discr); + double C = sgnq * pow(basis, 1.0/3.0); // c++11 has std::cbrt() + z[0] = C + p/C; + } + for(size_t i=0; i1e-8) { + z[i] -= f/f1; + } + } + } + // ensure if a=0 we get exactly x=0 as root + // TODO: remove this fudge + if(a==0.0) { + assert(z.size()>0); // cubic should always have at least one root + double xmin=fabs(z[0]); + size_t imin=0; + for(size_t i=1; ifabs(z[i])) { + xmin=fabs(z[i]); + imin=i; + } + } + z[imin]=0.0; // replace the smallest absolute value with 0 + } + std::sort(z.begin(), z.end()); + return z; + } + + } // namespace internal From 90b97ba8b23870eb2ccb4cc944072d85bebb56e6 Mon Sep 17 00:00:00 2001 From: ddtomic Date: Thu, 27 Feb 2025 11:32:05 -0600 Subject: [PATCH 087/451] adjusted weighted dv function --- src/Power_Table.cpp | 249 +++++++++++++++++++------------------------- 1 file changed, 105 insertions(+), 144 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 51aaebf4..67632813 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -43,24 +43,21 @@ int PowerBuffer::getReadings() { return ret; } -void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, - Measurement watts) { - +void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, Measurement watts) { if ((cadence >= (MINIMUM_TABLE_CAD - (POWERTABLE_CAD_INCREMENT / 2))) && (cadence <= (MINIMUM_TABLE_CAD + (POWERTABLE_CAD_INCREMENT * POWERTABLE_CAD_SIZE) - (POWERTABLE_CAD_SIZE / 2))) && (watts.getValue() > 10) && // adding constraints (watts.getValue() < (POWERTABLE_WATT_SIZE * POWERTABLE_WATT_INCREMENT))) { - if (powerBuffer.powerEntry[0].readings == 0) { // we need to make sure stepper position is not negative so it only takes positive resistance values // Take Initial reading powerBuffer.set(0); // Check if the current stepper posistion is within a 5% range of the previous stepper position and that the current position is not negative } - int currentPos = ss2k->getCurrentPosition() / TABLE_DIVISOR; - int targetPos = powerBuffer.powerEntry[0].targetPosition; - int range = PT_READING_RANGE + ERG_SENSITIVITY; + int currentPos = ss2k->getCurrentPosition() / TABLE_DIVISOR; + int targetPos = powerBuffer.powerEntry[0].targetPosition; + int range = PT_READING_RANGE + ERG_SENSITIVITY; - if ( currentPos >= ( targetPos - range) && currentPos <= (targetPos + range)) { + if (currentPos >= (targetPos - range) && currentPos <= (targetPos + range)) { for (int i = 1; i < POWER_SAMPLES; i++) { if (powerBuffer.powerEntry[i].readings == 0) { SS2K_LOG(POWERTABLE_LOG_TAG, "Success!"); @@ -683,22 +680,8 @@ int weightedDownVote(int targetValue, int neighborValue) { // currently consistently getting a 0 for neighbor value... SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Target Value: (%d), NeighborValue: (%f)", targetValue, neighborValue); - // we have a few different options for penalty calculations here, will need to test which works best: - - // linear function, low agression penalty = round(delta * penaltyFactor); - // quadratic function, high aggression - // penalty = penaltyFactor * (delta * delta) - - // log function, medium aggression - // penalty = penaltyFactor * log(delta + 1); - - // max penalty is 10 - if (penalty > MAX_NEIGHBOR_WEIGHT) { - penalty = MAX_NEIGHBOR_WEIGHT; - } - SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Delta: (%d), Penalty: (%f)", delta, penalty); return penalty; } @@ -708,7 +691,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { float watts = 0; float cad = 0; float targetPosition = 0; - int avgPosition = 0; + int avgPosition = 0; // First, take the power buffer and average all of the samples together. int validEntries = 0; @@ -756,203 +739,182 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table TestResults testResults = this->testNeighbors(k, i, targetPosition); if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { - // test which bit fields didn't match if (!testResults.leftNeighbor.passedTest) { - avgPosition = (targetPosition + testResults.leftNeighbor.targetPosition) / 2; // calculate the average SS2K_LOG(POWERTABLE_LOG_TAG, "Left failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.leftNeighbor.targetPosition, targetPosition, avgPosition); - - if (testResults.leftNeighbor.targetPosition <= targetPosition + (500 * pow(TABLE_DIVISOR, -HORIZONTAL_NEIGHBOR_RANGE)) && (int)targetPosition != testResults.leftNeighbor.targetPosition) { // check if the cadence is the same and positions are within a set range in this case its 30. - if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { // checks if the avg position with the current watts and cadence is valid - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); + if (testResults.leftNeighbor.targetPosition <= targetPosition + (500 * pow(TABLE_DIVISOR, -HORIZONTAL_NEIGHBOR_RANGE)) && + (int)targetPosition != testResults.leftNeighbor.targetPosition) { // check if the cadence is the same and positions are within a set range in this case its 30. + + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { // checks if the avg position with the current watts and cadence is valid + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); this->enterData(k, i, avgPosition); + } - } - if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) { // check if the current position moved left is valid SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved left was valid! Current position: %f", targetPosition); - this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); // enter the data - - } + this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition); // enter the data + } if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition) .allNeighborsPassed) { // checks if the failed nighbor is valid with the right neighbors cadence and watts SS2K_LOG(POWERTABLE_LOG_TAG, "Left Neighbors position was valid with Right Neighbors cadence and watts! Left Neighbor Position: %d", testResults.leftNeighbor.targetPosition); - this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition); - - } + this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition); + } - //still downvote data if all the tests fail - if(!((this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) || - (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || - (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition).allNeighborsPassed))) - { + // still downvote data if all the tests fail + if (!((this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition).allNeighborsPassed) || + (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition).allNeighborsPassed))) { SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, - testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - //this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); + testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + // this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); } } else { SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, - testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - //this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); + testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); + this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + // this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); } } if (!testResults.rightNeighbor.passedTest) { - avgPosition = (targetPosition + testResults.rightNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Right failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.rightNeighbor.targetPosition, targetPosition, avgPosition); - - if (testResults.rightNeighbor.targetPosition >= targetPosition - (500 * pow(TABLE_DIVISOR, -HORIZONTAL_NEIGHBOR_RANGE)) && (int)targetPosition != testResults.rightNeighbor.targetPosition) { - - if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - - this->enterData(k, i, avgPosition); - } + if (testResults.rightNeighbor.targetPosition >= targetPosition - (500 * pow(TABLE_DIVISOR, -HORIZONTAL_NEIGHBOR_RANGE)) && + (int)targetPosition != testResults.rightNeighbor.targetPosition) { + if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); + + this->enterData(k, i, avgPosition); + } if (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, (float)targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved right was valid! Current position: %f", targetPosition); - this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); - - } + this->enterData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition); + } if (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Right Neighbors position was valid with Left Neighbors cadence and watts! Right Neighbor Position: %d", testResults.rightNeighbor.targetPosition); - - this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition); - - } - - // still downvote data if all the tests fail - if(!((this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) || - (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || - (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed))) - { + + this->enterData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition); + } + + // still downvote data if all the tests fail + if (!((this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition).allNeighborsPassed) || + (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed))) { SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, - testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - //this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); + testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + // this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); } } else { SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, - testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - //this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); + testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); + this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + // this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); } } if (!testResults.topNeighbor.passedTest) { - - avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; + avgPosition = (targetPosition + testResults.topNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Top failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.topNeighbor.targetPosition, targetPosition, avgPosition); - if (testResults.topNeighbor.targetPosition >= targetPosition - (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE)) && (int)targetPosition != testResults.topNeighbor.targetPosition) { - + if (testResults.topNeighbor.targetPosition >= targetPosition - (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE)) && + (int)targetPosition != testResults.topNeighbor.targetPosition) { if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - - this->enterData(k, i, avgPosition); - + + this->enterData(k, i, avgPosition); } if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved up was valid! Current position: %f", targetPosition); - - this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); - - } + + this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition); + } if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Top Neighbors position was valid with Bottom Neighbors cadence and watts! Top Neighbor Position: %d", testResults.topNeighbor.targetPosition); - - this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); - + + this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition); } - //still downvote data if all the tests fail - if(!((this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) || - (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || - (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed))) - { + // still downvote data if all the tests fail + if (!((this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition).allNeighborsPassed) || + (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed))) { SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, - testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - //this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); + testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + // this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); } } else { SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, - testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - //this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); + testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + // this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); } } if (!testResults.bottomNeighbor.passedTest) { - avgPosition = (targetPosition + testResults.bottomNeighbor.targetPosition) / 2; SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom failed at: (%d) Target pos: (%f) Avg pos: (%d)", testResults.bottomNeighbor.targetPosition, targetPosition, avgPosition); - if (testResults.bottomNeighbor.targetPosition <= targetPosition + (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE)) && (int)targetPosition != testResults.bottomNeighbor.targetPosition) { - + if (testResults.bottomNeighbor.targetPosition <= targetPosition + (500 * pow(TABLE_DIVISOR, -VERTICAL_NEIGHBOR_RANGE)) && + (int)targetPosition != testResults.bottomNeighbor.targetPosition) { if (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Avg postion is valid with current cadence and watts! Avg position: %d", avgPosition); - - this->enterData(k, i, avgPosition); - - } - + + this->enterData(k, i, avgPosition); + } + if (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Current Position moved down is valid! Current position: %f", targetPosition); - - this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); - - } + + this->enterData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition); + } if (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed) { SS2K_LOG(POWERTABLE_LOG_TAG, "Bottom Neighbors position was valid with Top Neighbors cadence and watts! Bottom Neighbor Position: %d", testResults.topNeighbor.targetPosition); - - this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition); - - } - - // still downvote data if all the tests fail - if(!((this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) || - (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || - (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed))) - { + + this->enterData(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition); + } + + // still downvote data if all the tests fail + if (!((this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition).allNeighborsPassed) || + (this->testNeighbors(k, i, avgPosition).allNeighborsPassed) || + (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed))) { SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed bottom (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, - testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - //this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); + testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + // this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); } } else { SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, - testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - //this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); + testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); + this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + // this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); } } return; } - this->enterData(k, i, (int)targetPosition); @@ -1001,18 +963,17 @@ void PowerTable::enterData(int i, int j, int pos) { } } -void PowerTable::downVoteData(int i, int j, float target, int neighbor){ - // determine penalty amount before applying to failed neighbor - int penalty = weightedDownVote(target, neighbor); - - // make sure downvotes isn't at max - if (this->tableRow[i].tableEntry[j].readings > MAX_NEIGHBOR_WEIGHT) { - this->tableRow[i].tableEntry[j].readings = MAX_NEIGHBOR_WEIGHT; - penalty = 0; - } - this->tableRow[i].tableEntry[j].readings -= penalty; - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed (%d)(%d)(%d), readings (%d)", i, j, - neighbor, this->tableRow[i].tableEntry[j].readings); +void PowerTable::downVoteData(int i, int j, float target, int neighbor) { + // determine penalty amount before applying to failed neighbor + int penalty = weightedDownVote(target, neighbor); + + // make sure downvotes isn't at max + if (this->tableRow[i].tableEntry[j].readings > MAX_NEIGHBOR_WEIGHT) { + this->tableRow[i].tableEntry[j].readings = MAX_NEIGHBOR_WEIGHT; + penalty = 0; + } + this->tableRow[i].tableEntry[j].readings -= penalty; + SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed (%d)(%d)(%d), readings (%d)", i, j, neighbor, this->tableRow[i].tableEntry[j].readings); } bool PowerTable::_manageSaveState(bool canSkipReliabilityChecks) { @@ -1293,7 +1254,7 @@ bool PowerTable::reset() { } void PowerTable::toLog() { - #ifdef DEBUG_POWERTABLE +#ifdef DEBUG_POWERTABLE int maxLen = 4; // Find the longest integer to dynamically size the table for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { @@ -1331,7 +1292,7 @@ void PowerTable::toLog() { } SS2K_LOG(POWERTABLE_LOG_TAG, "%s", logString.c_str()); } - #endif +#endif } int PowerTable::getNumReadings() { From 41ce6147acce411d6276f9ba317fd82109bcbb6c Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Thu, 27 Feb 2025 13:03:54 -0600 Subject: [PATCH 088/451] weightedDownVote tested and working --- src/Power_Table.cpp | 64 ++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 67632813..3c7dc447 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -670,22 +670,6 @@ void PowerTable::clean() { } } -// function for weighted downvoting -int weightedDownVote(int targetValue, int neighborValue) { - // calculate diff between target and neighbor - int delta = abs(targetValue - neighborValue); - int penalty; - float penaltyFactor = 0.2; - - // currently consistently getting a 0 for neighbor value... - SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Target Value: (%d), NeighborValue: (%f)", targetValue, neighborValue); - - penalty = round(delta * penaltyFactor); - - SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Delta: (%d), Penalty: (%f)", delta, penalty); - return penalty; -} - void PowerTable::newEntry(PowerBuffer& powerBuffer) { // these are floats so that we make sure division works correctly. float watts = 0; @@ -774,14 +758,14 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition).allNeighborsPassed))) { SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - // this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); + //this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); } } else { SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); - this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; - // this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); + //this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; + this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); } } @@ -817,14 +801,14 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed))) { SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - // this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); + //this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); } } else { SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); - this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; - // this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); + // this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; + this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); } } @@ -860,14 +844,14 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed))) { SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - // this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); + //this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); } } else { SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; - // this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); + //this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; + this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); } } @@ -903,14 +887,14 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed))) { SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed bottom (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - // this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); + // this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); } } else { SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); - this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; - // this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); + // this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; + this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); } } return; @@ -963,6 +947,22 @@ void PowerTable::enterData(int i, int j, int pos) { } } +// function for weighted downvoting +int weightedDownVote(int targetValue, int neighborValue) { + // calculate diff between target and neighbor + int delta = abs(targetValue - neighborValue); + int penalty; + float penaltyFactor = 0.2; + + // currently consistently getting a 0 for neighbor value... + SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Target Value: (%d), NeighborValue: (%d)", targetValue, neighborValue); + + penalty = (delta * penaltyFactor); + + SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Delta: (%d), Penalty: (%d)", delta, penalty); + return penalty; +} + void PowerTable::downVoteData(int i, int j, float target, int neighbor) { // determine penalty amount before applying to failed neighbor int penalty = weightedDownVote(target, neighbor); From f8786bba00a8517e30c8098813c1ed7b12d9fd66 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Thu, 27 Feb 2025 15:21:36 -0600 Subject: [PATCH 089/451] working cubic spline interpolation --- include/spline.h | 1842 +++++++++++++++++++++---------------------- src/Power_Table.cpp | 275 ++++--- 2 files changed, 1079 insertions(+), 1038 deletions(-) diff --git a/include/spline.h b/include/spline.h index 5e78a5ab..e5b186d7 100644 --- a/include/spline.h +++ b/include/spline.h @@ -24,924 +24,924 @@ */ - #ifndef TK_SPLINE_H - #define TK_SPLINE_H - - #include - #include - #include - #include - #include - #ifdef HAVE_SSTREAM - #include - #include - #endif // HAVE_SSTREAM - - // not ideal but disable unused-function warnings - // (we get them because we have implementations in the header file, - // and this is because we want to be able to quickly separate them - // into a cpp file if necessary) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wunused-function" - - // unnamed namespace only because the implementation is in this - // header file and we don't want to export symbols to the obj files - namespace - { - - namespace tk - { - - // spline interpolation - class spline - { - public: - // spline types - enum spline_type { - linear = 10, // linear interpolation - cspline = 30, // cubic splines (classical C^2) - cspline_hermite = 31 // cubic hermite splines (local, only C^1) - }; - - // boundary condition type for the spline end-points - enum bd_type { - first_deriv = 1, - second_deriv = 2, - not_a_knot = 3 - }; - - protected: - std::vector m_x,m_y; // x,y coordinates of points - // interpolation parameters - // f(x) = a_i + b_i*(x-x_i) + c_i*(x-x_i)^2 + d_i*(x-x_i)^3 - // where a_i = y_i, or else it won't go through grid points - std::vector m_b,m_c,m_d; // spline coefficients - double m_c0; // for left extrapolation - spline_type m_type; - bd_type m_left, m_right; - double m_left_value, m_right_value; - bool m_made_monotonic; - void set_coeffs_from_b(); // calculate c_i, d_i from b_i - size_t find_closest(double x) const; // closest idx so that m_x[idx]<=x - - public: - // default constructor: set boundary condition to be zero curvature - // at both ends, i.e. natural splines - spline(): m_type(cspline), - m_left(second_deriv), m_right(second_deriv), - m_left_value(0.0), m_right_value(0.0), m_made_monotonic(false) - { - ; - } - spline(const std::vector& X, const std::vector& Y, - spline_type type = cspline, - bool make_monotonic = false, - bd_type left = second_deriv, double left_value = 0.0, - bd_type right = second_deriv, double right_value = 0.0 - ): - m_type(type), - m_left(left), m_right(right), - m_left_value(left_value), m_right_value(right_value), - m_made_monotonic(false) // false correct here: make_monotonic() sets it - { - this->set_points(X,Y,m_type); - if(make_monotonic) { - this->make_monotonic(); - } - } - - - // modify boundary conditions: if called it must be before set_points() - void set_boundary(bd_type left, double left_value, - bd_type right, double right_value); - - // set all data points (cubic_spline=false means linear interpolation) - void set_points(const std::vector& x, - const std::vector& y, - spline_type type=cspline); - - // adjust coefficients so that the spline becomes piecewise monotonic - // where possible - // this is done by adjusting slopes at grid points by a non-negative - // factor and this will break C^2 - // this can also break boundary conditions if adjustments need to - // be made at the boundary points - // returns false if no adjustments have been made, true otherwise - bool make_monotonic(); - - // evaluates the spline at point x - double operator() (double x) const; - double deriv(int order, double x) const; - - // solves for all x so that: spline(x) = y - std::vector solve(double y, bool ignore_extrapolation=true) const; - - // returns the input data points - std::vector get_x() const { return m_x; } - std::vector get_y() const { return m_y; } - double get_x_min() const { assert(!m_x.empty()); return m_x.front(); } - double get_x_max() const { assert(!m_x.empty()); return m_x.back(); } - - #ifdef HAVE_SSTREAM - // spline info string, i.e. spline type, boundary conditions etc. - std::string info() const; - #endif // HAVE_SSTREAM - - }; - - - - namespace internal - { - - // band matrix solver - class band_matrix - { - private: - std::vector< std::vector > m_upper; // upper band - std::vector< std::vector > m_lower; // lower band - public: - band_matrix() {}; // constructor - band_matrix(int dim, int n_u, int n_l); // constructor - ~band_matrix() {}; // destructor - void resize(int dim, int n_u, int n_l); // init with dim,n_u,n_l - int dim() const; // matrix dimension - int num_upper() const - { - return (int)m_upper.size()-1; - } - int num_lower() const - { - return (int)m_lower.size()-1; - } - // access operator - double & operator () (int i, int j); // write - double operator () (int i, int j) const; // read - // we can store an additional diagonal (in m_lower) - double& saved_diag(int i); - double saved_diag(int i) const; - void lu_decompose(); - std::vector r_solve(const std::vector& b) const; - std::vector l_solve(const std::vector& b) const; - std::vector lu_solve(const std::vector& b, - bool is_lu_decomposed=false); - - }; - - double get_eps(); - - std::vector solve_cubic(double a, double b, double c, double d, - int newton_iter=0); - - } // namespace internal - - - - - // --------------------------------------------------------------------- - // implementation part, which could be separated into a cpp file - // --------------------------------------------------------------------- - - // spline implementation - // ----------------------- - - void spline::set_boundary(spline::bd_type left, double left_value, - spline::bd_type right, double right_value) - { - assert(m_x.size()==0); // set_points() must not have happened yet - m_left=left; - m_right=right; - m_left_value=left_value; - m_right_value=right_value; - } - - - void spline::set_coeffs_from_b() - { - assert(m_x.size()==m_y.size()); - assert(m_x.size()==m_b.size()); - assert(m_x.size()>2); - size_t n=m_b.size(); - if(m_c.size()!=n) - m_c.resize(n); - if(m_d.size()!=n) - m_d.resize(n); - - for(size_t i=0; i& x, - const std::vector& y, - spline_type type) - { - assert(x.size()==y.size()); - assert(x.size()>=3); - // not-a-knot with 3 points has many solutions - if(m_left==not_a_knot || m_right==not_a_knot) - assert(x.size()>=4); - m_type=type; - m_made_monotonic=false; - m_x=x; - m_y=y; - int n = (int) x.size(); - // check strict monotonicity of input vector x - for(int i=0; i rhs(n); - for(int i=1; i2); - bool modified = false; - const int n=(int)m_x.size(); - // make sure: input data monotonic increasing --> b_i>=0 - // input data monotonic decreasing --> b_i<=0 - for(int i=0; i=m_y[i]) && (m_y[i]>=m_y[ip1]) && m_b[i]>0.0) ) { - modified=true; - m_b[i]=0.0; - } - } - // if input data is monotonic (b[i], b[i+1], avg have all the same sign) - // ensure a sufficient criteria for monotonicity is satisfied: - // sqrt(b[i]^2+b[i+1]^2) <= 3 |avg|, with avg=(y[i+1]-y[i])/h, - for(int i=0; i=0.0 && m_b[i+1]>=0.0 && avg>0.0) || - (m_b[i]<=0.0 && m_b[i+1]<=0.0 && avg<0.0) ) { - // input data is monotonic - double r = sqrt(m_b[i]*m_b[i]+m_b[i+1]*m_b[i+1])/std::fabs(avg); - if(r>3.0) { - // sufficient criteria for monotonicity: r<=3 - // adjust b[i] and b[i+1] - modified=true; - m_b[i] *= (3.0/r); - m_b[i+1] *= (3.0/r); - } - } - } - - if(modified==true) { - set_coeffs_from_b(); - m_made_monotonic=true; - } - - return modified; - } - - // return the closest idx so that m_x[idx] <= x (return 0 if x::const_iterator it; - it=std::upper_bound(m_x.begin(),m_x.end(),x); // *it > x - size_t idx = std::max( int(it-m_x.begin())-1, 0); // m_x[idx] <= x - return idx; - } - - double spline::operator() (double x) const - { - // polynomial evaluation using Horner's scheme - // TODO: consider more numerically accurate algorithms, e.g.: - // - Clenshaw - // - Even-Odd method by A.C.R. Newbery - // - Compensated Horner Scheme - size_t n=m_x.size(); - size_t idx=find_closest(x); - - double h=x-m_x[idx]; - double interpol; - if(xm_x[n-1]) { - // extrapolation to the right - interpol=(m_c[n-1]*h + m_b[n-1])*h + m_y[n-1]; - } else { - // interpolation - interpol=((m_d[idx]*h + m_c[idx])*h + m_b[idx])*h + m_y[idx]; - } - return interpol; - } - - double spline::deriv(int order, double x) const - { - assert(order>0); - size_t n=m_x.size(); - size_t idx = find_closest(x); - - double h=x-m_x[idx]; - double interpol; - if(xm_x[n-1]) { - // extrapolation to the right - switch(order) { - case 1: - interpol=2.0*m_c[n-1]*h + m_b[n-1]; - break; - case 2: - interpol=2.0*m_c[n-1]; - break; - default: - interpol=0.0; - break; - } - } else { - // interpolation - switch(order) { - case 1: - interpol=(3.0*m_d[idx]*h + 2.0*m_c[idx])*h + m_b[idx]; - break; - case 2: - interpol=6.0*m_d[idx]*h + 2.0*m_c[idx]; - break; - case 3: - interpol=6.0*m_d[idx]; - break; - default: - interpol=0.0; - break; - } - } - return interpol; - } - - std::vector spline::solve(double y, bool ignore_extrapolation) const - { - std::vector x; // roots for the entire spline - std::vector root; // roots for each piecewise cubic - const size_t n=m_x.size(); - - // left extrapolation - if(ignore_extrapolation==false) { - root = internal::solve_cubic(m_y[0]-y,m_b[0],m_c0,0.0,1); - for(size_t j=0; j0) ? (m_x[i]-m_x[i-1]) : 0.0; - double eps = internal::get_eps()*512.0*std::min(h,1.0); - if( (-eps<=root[j]) && (root[j]0 && x.back()+eps > new_root) { - x.back()=new_root; // avoid spurious duplicate roots - } else { - x.push_back(new_root); - } - } - } - } - - // right extrapolation - if(ignore_extrapolation==false) { - root = internal::solve_cubic(m_y[n-1]-y,m_b[n-1],m_c[n-1],0.0,1); - for(size_t j=0; j0); - assert(n_u>=0); - assert(n_l>=0); - m_upper.resize(n_u+1); - m_lower.resize(n_l+1); - for(size_t i=0; i0) { - return m_upper[0].size(); - } else { - return 0; - } - } - - - // defines the new operator (), so that we can access the elements - // by A(i,j), index going from i=0,...,dim()-1 - double & band_matrix::operator () (int i, int j) - { - int k=j-i; // what band is the entry - assert( (i>=0) && (i=0) && (j diagonal, k<0 lower left part, k>0 upper right part - if(k>=0) return m_upper[k][i]; - else return m_lower[-k][i]; - } - double band_matrix::operator () (int i, int j) const - { - int k=j-i; // what band is the entry - assert( (i>=0) && (i=0) && (j diagonal, k<0 lower left part, k>0 upper right part - if(k>=0) return m_upper[k][i]; - else return m_lower[-k][i]; - } - // second diag (used in LU decomposition), saved in m_lower - double band_matrix::saved_diag(int i) const - { - assert( (i>=0) && (i=0) && (idim(); i++) { - assert(this->operator()(i,i)!=0.0); - this->saved_diag(i)=1.0/this->operator()(i,i); - j_min=std::max(0,i-this->num_lower()); - j_max=std::min(this->dim()-1,i+this->num_upper()); - for(int j=j_min; j<=j_max; j++) { - this->operator()(i,j) *= this->saved_diag(i); - } - this->operator()(i,i)=1.0; // prevents rounding errors - } - - // Gauss LR-Decomposition - for(int k=0; kdim(); k++) { - i_max=std::min(this->dim()-1,k+this->num_lower()); // num_lower not a mistake! - for(int i=k+1; i<=i_max; i++) { - assert(this->operator()(k,k)!=0.0); - x=-this->operator()(i,k)/this->operator()(k,k); - this->operator()(i,k)=-x; // assembly part of L - j_max=std::min(this->dim()-1,k+this->num_upper()); - for(int j=k+1; j<=j_max; j++) { - // assembly part of R - this->operator()(i,j)=this->operator()(i,j)+x*this->operator()(k,j); - } - } - } - } - // solves Ly=b - std::vector band_matrix::l_solve(const std::vector& b) const - { - assert( this->dim()==(int)b.size() ); - std::vector x(this->dim()); - int j_start; - double sum; - for(int i=0; idim(); i++) { - sum=0; - j_start=std::max(0,i-this->num_lower()); - for(int j=j_start; joperator()(i,j)*x[j]; - x[i]=(b[i]*this->saved_diag(i)) - sum; - } - return x; - } - // solves Rx=y - std::vector band_matrix::r_solve(const std::vector& b) const - { - assert( this->dim()==(int)b.size() ); - std::vector x(this->dim()); - int j_stop; - double sum; - for(int i=this->dim()-1; i>=0; i--) { - sum=0; - j_stop=std::min(this->dim()-1,i+this->num_upper()); - for(int j=i+1; j<=j_stop; j++) sum += this->operator()(i,j)*x[j]; - x[i]=( b[i] - sum ) / this->operator()(i,i); - } - return x; - } - - std::vector band_matrix::lu_solve(const std::vector& b, - bool is_lu_decomposed) - { - assert( this->dim()==(int)b.size() ); - std::vector x,y; - if(is_lu_decomposed==false) { - this->lu_decompose(); - } - y=this->l_solve(b); - x=this->r_solve(y); - return x; - } - - // machine precision of a double, i.e. the successor of 1 is 1+eps - double get_eps() - { - //return std::numeric_limits::epsilon(); // __DBL_EPSILON__ - return 2.2204460492503131e-16; // 2^-52 - } - - // solutions for a + b*x = 0 - std::vector solve_linear(double a, double b) - { - std::vector x; // roots - if(b==0.0) { - if(a==0.0) { - // 0*x = 0 - x.resize(1); - x[0] = 0.0; // any x solves it but we need to pick one - return x; - } else { - // 0*x + ... = 0, no solution - return x; - } - } else { - x.resize(1); - x[0] = -a/b; - return x; - } - } - - // solutions for a + b*x + c*x^2 = 0 - std::vector solve_quadratic(double a, double b, double c, - int newton_iter=0) - { - if(c==0.0) { - return solve_linear(a,b); - } - // rescale so that we solve x^2 + 2p x + q = (x+p)^2 + q - p^2 = 0 - double p=0.5*b/c; - double q=a/c; - double discr = p*p-q; - const double eps=0.5*internal::get_eps(); - double discr_err = (6.0*(p*p)+3.0*fabs(q)+fabs(discr))*eps; - - std::vector x; // roots - if(fabs(discr)<=discr_err) { - // discriminant is zero --> one root - x.resize(1); - x[0] = -p; - } else if(discr<0) { - // no root - } else { - // two roots - x.resize(2); - x[0] = -p - sqrt(discr); - x[1] = -p + sqrt(discr); - } - - // improve solution via newton steps - for(size_t i=0; i1e-8) { - x[i] -= f/f1; - } - } - } - - return x; - } - - // solutions for the cubic equation: a + b*x +c*x^2 + d*x^3 = 0 - // this is a naive implementation of the analytic solution without - // optimisation for speed or numerical accuracy - // newton_iter: number of newton iterations to improve analytical solution - // see also - // gsl: gsl_poly_solve_cubic() in solve_cubic.c - // octave: roots.m - via eigenvalues of the Frobenius companion matrix - std::vector solve_cubic(double a, double b, double c, double d, - int newton_iter) - { - if(d==0.0) { - return solve_quadratic(a,b,c,newton_iter); - } - - // convert to normalised form: a + bx + cx^2 + x^3 = 0 - if(d!=1.0) { - a/=d; - b/=d; - c/=d; - } - - // convert to depressed cubic: z^3 - 3pz - 2q = 0 - // via substitution: z = x + c/3 - std::vector z; // roots of the depressed cubic - double p = -(1.0/3.0)*b + (1.0/9.0)*(c*c); - double r = 2.0*(c*c)-9.0*b; - double q = -0.5*a - (1.0/54.0)*(c*r); - double discr=p*p*p-q*q; // discriminant - // calculating numerical round-off errors with assumptions: - // - each operation is precise but each intermediate result x - // when stored has max error of x*eps - // - only multiplication with a power of 2 introduces no new error - // - a,b,c,d and some fractions (e.g. 1/3) have rounding errors eps - // - p_err << |p|, q_err << |q|, ... (this is violated in rare cases) - // would be more elegant to use boost::numeric::interval - const double eps = internal::get_eps(); - double p_err = eps*((3.0/3.0)*fabs(b)+(4.0/9.0)*(c*c)+fabs(p)); - double r_err = eps*(6.0*(c*c)+18.0*fabs(b)+fabs(r)); - double q_err = 0.5*fabs(a)*eps + (1.0/54.0)*fabs(c)*(r_err+fabs(r)*3.0*eps) - + fabs(q)*eps; - double discr_err = (p*p) * (3.0*p_err + fabs(p)*2.0*eps) - + fabs(q) * (2.0*q_err + fabs(q)*eps) + fabs(discr)*eps; - - // depending on the discriminant we get different solutions - if(fabs(discr)<=discr_err) { - // discriminant zero: one or two real roots - if(fabs(p)<=p_err) { - // p and q are zero: single root - z.resize(1); - z[0] = 0.0; // triple root - } else { - z.resize(2); - z[0] = 2.0*q/p; // single root - z[1] = -0.5*z[0]; // double root - } - } else if(discr>0) { - // three real roots: via trigonometric solution - z.resize(3); - double ac = (1.0/3.0) * acos( q/(p*sqrt(p)) ); - double sq = 2.0*sqrt(p); - z[0] = sq * cos(ac); - z[1] = sq * cos(ac-2.0*M_PI/3.0); - z[2] = sq * cos(ac-4.0*M_PI/3.0); - } else if (discr<0.0) { - // single real root: via Cardano's fromula - z.resize(1); - double sgnq = (q >= 0 ? 1 : -1); - double basis = fabs(q) + sqrt(-discr); - double C = sgnq * pow(basis, 1.0/3.0); // c++11 has std::cbrt() - z[0] = C + p/C; - } - for(size_t i=0; i1e-8) { - z[i] -= f/f1; - } - } - } - // ensure if a=0 we get exactly x=0 as root - // TODO: remove this fudge - if(a==0.0) { - assert(z.size()>0); // cubic should always have at least one root - double xmin=fabs(z[0]); - size_t imin=0; - for(size_t i=1; ifabs(z[i])) { - xmin=fabs(z[i]); - imin=i; - } - } - z[imin]=0.0; // replace the smallest absolute value with 0 - } - std::sort(z.begin(), z.end()); - return z; - } - - - } // namespace internal - - - } // namespace tk - - - } // namespace - - #pragma GCC diagnostic pop - - #endif /* TK_SPLINE_H */ \ No newline at end of file +#ifndef TK_SPLINE_H +#define TK_SPLINE_H + +#include +#include +#include +#include +#include +#ifdef HAVE_SSTREAM +#include +#include +#endif // HAVE_SSTREAM + +// not ideal but disable unused-function warnings +// (we get them because we have implementations in the header file, +// and this is because we want to be able to quickly separate them +// into a cpp file if necessary) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" + +// unnamed namespace only because the implementation is in this +// header file and we don't want to export symbols to the obj files +namespace +{ + +namespace tk +{ + +// spline interpolation +class spline +{ +public: + // spline types + enum spline_type { + linear = 10, // linear interpolation + cspline = 30, // cubic splines (classical C^2) + cspline_hermite = 31 // cubic hermite splines (local, only C^1) + }; + + // boundary condition type for the spline end-points + enum bd_type { + first_deriv = 1, + second_deriv = 2, + not_a_knot = 3 + }; + +protected: + std::vector m_x,m_y; // x,y coordinates of points + // interpolation parameters + // f(x) = a_i + b_i*(x-x_i) + c_i*(x-x_i)^2 + d_i*(x-x_i)^3 + // where a_i = y_i, or else it won't go through grid points + std::vector m_b,m_c,m_d; // spline coefficients + double m_c0; // for left extrapolation + spline_type m_type; + bd_type m_left, m_right; + double m_left_value, m_right_value; + bool m_made_monotonic; + void set_coeffs_from_b(); // calculate c_i, d_i from b_i + size_t find_closest(double x) const; // closest idx so that m_x[idx]<=x + +public: + // default constructor: set boundary condition to be zero curvature + // at both ends, i.e. natural splines + spline(): m_type(cspline), + m_left(second_deriv), m_right(second_deriv), + m_left_value(0.0), m_right_value(0.0), m_made_monotonic(false) + { + ; + } + spline(const std::vector& X, const std::vector& Y, + spline_type type = cspline, + bool make_monotonic = false, + bd_type left = second_deriv, double left_value = 0.0, + bd_type right = second_deriv, double right_value = 0.0 + ): + m_type(type), + m_left(left), m_right(right), + m_left_value(left_value), m_right_value(right_value), + m_made_monotonic(false) // false correct here: make_monotonic() sets it + { + this->set_points(X,Y,m_type); + if(make_monotonic) { + this->make_monotonic(); + } + } + + + // modify boundary conditions: if called it must be before set_points() + void set_boundary(bd_type left, double left_value, + bd_type right, double right_value); + + // set all data points (cubic_spline=false means linear interpolation) + void set_points(const std::vector& x, + const std::vector& y, + spline_type type=cspline); + + // adjust coefficients so that the spline becomes piecewise monotonic + // where possible + // this is done by adjusting slopes at grid points by a non-negative + // factor and this will break C^2 + // this can also break boundary conditions if adjustments need to + // be made at the boundary points + // returns false if no adjustments have been made, true otherwise + bool make_monotonic(); + + // evaluates the spline at point x + double operator() (double x) const; + double deriv(int order, double x) const; + + // solves for all x so that: spline(x) = y + std::vector solve(double y, bool ignore_extrapolation=true) const; + + // returns the input data points + std::vector get_x() const { return m_x; } + std::vector get_y() const { return m_y; } + double get_x_min() const { assert(!m_x.empty()); return m_x.front(); } + double get_x_max() const { assert(!m_x.empty()); return m_x.back(); } + +#ifdef HAVE_SSTREAM + // spline info string, i.e. spline type, boundary conditions etc. + std::string info() const; +#endif // HAVE_SSTREAM + +}; + + + +namespace internal +{ + +// band matrix solver +class band_matrix +{ +private: + std::vector< std::vector > m_upper; // upper band + std::vector< std::vector > m_lower; // lower band +public: + band_matrix() {}; // constructor + band_matrix(int dim, int n_u, int n_l); // constructor + ~band_matrix() {}; // destructor + void resize(int dim, int n_u, int n_l); // init with dim,n_u,n_l + int dim() const; // matrix dimension + int num_upper() const + { + return (int)m_upper.size()-1; + } + int num_lower() const + { + return (int)m_lower.size()-1; + } + // access operator + double & operator () (int i, int j); // write + double operator () (int i, int j) const; // read + // we can store an additional diagonal (in m_lower) + double& saved_diag(int i); + double saved_diag(int i) const; + void lu_decompose(); + std::vector r_solve(const std::vector& b) const; + std::vector l_solve(const std::vector& b) const; + std::vector lu_solve(const std::vector& b, + bool is_lu_decomposed=false); + +}; + +double get_eps(); + +std::vector solve_cubic(double a, double b, double c, double d, + int newton_iter=0); + +} // namespace internal + + + + +// --------------------------------------------------------------------- +// implementation part, which could be separated into a cpp file +// --------------------------------------------------------------------- + +// spline implementation +// ----------------------- + +void spline::set_boundary(spline::bd_type left, double left_value, + spline::bd_type right, double right_value) +{ + assert(m_x.size()==0); // set_points() must not have happened yet + m_left=left; + m_right=right; + m_left_value=left_value; + m_right_value=right_value; +} + + +void spline::set_coeffs_from_b() +{ + assert(m_x.size()==m_y.size()); + assert(m_x.size()==m_b.size()); + assert(m_x.size()>2); + size_t n=m_b.size(); + if(m_c.size()!=n) + m_c.resize(n); + if(m_d.size()!=n) + m_d.resize(n); + + for(size_t i=0; i& x, + const std::vector& y, + spline_type type) +{ + assert(x.size()==y.size()); + assert(x.size()>=3); + // not-a-knot with 3 points has many solutions + if(m_left==not_a_knot || m_right==not_a_knot) + assert(x.size()>=4); + m_type=type; + m_made_monotonic=false; + m_x=x; + m_y=y; + int n = (int) x.size(); + // check strict monotonicity of input vector x + for(int i=0; i rhs(n); + for(int i=1; i2); + bool modified = false; + const int n=(int)m_x.size(); + // make sure: input data monotonic increasing --> b_i>=0 + // input data monotonic decreasing --> b_i<=0 + for(int i=0; i=m_y[i]) && (m_y[i]>=m_y[ip1]) && m_b[i]>0.0) ) { + modified=true; + m_b[i]=0.0; + } + } + // if input data is monotonic (b[i], b[i+1], avg have all the same sign) + // ensure a sufficient criteria for monotonicity is satisfied: + // sqrt(b[i]^2+b[i+1]^2) <= 3 |avg|, with avg=(y[i+1]-y[i])/h, + for(int i=0; i=0.0 && m_b[i+1]>=0.0 && avg>0.0) || + (m_b[i]<=0.0 && m_b[i+1]<=0.0 && avg<0.0) ) { + // input data is monotonic + double r = sqrt(m_b[i]*m_b[i]+m_b[i+1]*m_b[i+1])/std::fabs(avg); + if(r>3.0) { + // sufficient criteria for monotonicity: r<=3 + // adjust b[i] and b[i+1] + modified=true; + m_b[i] *= (3.0/r); + m_b[i+1] *= (3.0/r); + } + } + } + + if(modified==true) { + set_coeffs_from_b(); + m_made_monotonic=true; + } + + return modified; +} + +// return the closest idx so that m_x[idx] <= x (return 0 if x::const_iterator it; + it=std::upper_bound(m_x.begin(),m_x.end(),x); // *it > x + size_t idx = std::max( int(it-m_x.begin())-1, 0); // m_x[idx] <= x + return idx; +} + +double spline::operator() (double x) const +{ + // polynomial evaluation using Horner's scheme + // TODO: consider more numerically accurate algorithms, e.g.: + // - Clenshaw + // - Even-Odd method by A.C.R. Newbery + // - Compensated Horner Scheme + size_t n=m_x.size(); + size_t idx=find_closest(x); + + double h=x-m_x[idx]; + double interpol; + if(xm_x[n-1]) { + // extrapolation to the right + interpol=(m_c[n-1]*h + m_b[n-1])*h + m_y[n-1]; + } else { + // interpolation + interpol=((m_d[idx]*h + m_c[idx])*h + m_b[idx])*h + m_y[idx]; + } + return interpol; +} + +double spline::deriv(int order, double x) const +{ + assert(order>0); + size_t n=m_x.size(); + size_t idx = find_closest(x); + + double h=x-m_x[idx]; + double interpol; + if(xm_x[n-1]) { + // extrapolation to the right + switch(order) { + case 1: + interpol=2.0*m_c[n-1]*h + m_b[n-1]; + break; + case 2: + interpol=2.0*m_c[n-1]; + break; + default: + interpol=0.0; + break; + } + } else { + // interpolation + switch(order) { + case 1: + interpol=(3.0*m_d[idx]*h + 2.0*m_c[idx])*h + m_b[idx]; + break; + case 2: + interpol=6.0*m_d[idx]*h + 2.0*m_c[idx]; + break; + case 3: + interpol=6.0*m_d[idx]; + break; + default: + interpol=0.0; + break; + } + } + return interpol; +} + +std::vector spline::solve(double y, bool ignore_extrapolation) const +{ + std::vector x; // roots for the entire spline + std::vector root; // roots for each piecewise cubic + const size_t n=m_x.size(); + + // left extrapolation + if(ignore_extrapolation==false) { + root = internal::solve_cubic(m_y[0]-y,m_b[0],m_c0,0.0,1); + for(size_t j=0; j0) ? (m_x[i]-m_x[i-1]) : 0.0; + double eps = internal::get_eps()*512.0*std::min(h,1.0); + if( (-eps<=root[j]) && (root[j]0 && x.back()+eps > new_root) { + x.back()=new_root; // avoid spurious duplicate roots + } else { + x.push_back(new_root); + } + } + } + } + + // right extrapolation + if(ignore_extrapolation==false) { + root = internal::solve_cubic(m_y[n-1]-y,m_b[n-1],m_c[n-1],0.0,1); + for(size_t j=0; j0); + assert(n_u>=0); + assert(n_l>=0); + m_upper.resize(n_u+1); + m_lower.resize(n_l+1); + for(size_t i=0; i0) { + return m_upper[0].size(); + } else { + return 0; + } +} + + +// defines the new operator (), so that we can access the elements +// by A(i,j), index going from i=0,...,dim()-1 +double & band_matrix::operator () (int i, int j) +{ + int k=j-i; // what band is the entry + assert( (i>=0) && (i=0) && (j diagonal, k<0 lower left part, k>0 upper right part + if(k>=0) return m_upper[k][i]; + else return m_lower[-k][i]; +} +double band_matrix::operator () (int i, int j) const +{ + int k=j-i; // what band is the entry + assert( (i>=0) && (i=0) && (j diagonal, k<0 lower left part, k>0 upper right part + if(k>=0) return m_upper[k][i]; + else return m_lower[-k][i]; +} +// second diag (used in LU decomposition), saved in m_lower +double band_matrix::saved_diag(int i) const +{ + assert( (i>=0) && (i=0) && (idim(); i++) { + assert(this->operator()(i,i)!=0.0); + this->saved_diag(i)=1.0/this->operator()(i,i); + j_min=std::max(0,i-this->num_lower()); + j_max=std::min(this->dim()-1,i+this->num_upper()); + for(int j=j_min; j<=j_max; j++) { + this->operator()(i,j) *= this->saved_diag(i); + } + this->operator()(i,i)=1.0; // prevents rounding errors + } + + // Gauss LR-Decomposition + for(int k=0; kdim(); k++) { + i_max=std::min(this->dim()-1,k+this->num_lower()); // num_lower not a mistake! + for(int i=k+1; i<=i_max; i++) { + assert(this->operator()(k,k)!=0.0); + x=-this->operator()(i,k)/this->operator()(k,k); + this->operator()(i,k)=-x; // assembly part of L + j_max=std::min(this->dim()-1,k+this->num_upper()); + for(int j=k+1; j<=j_max; j++) { + // assembly part of R + this->operator()(i,j)=this->operator()(i,j)+x*this->operator()(k,j); + } + } + } +} +// solves Ly=b +std::vector band_matrix::l_solve(const std::vector& b) const +{ + assert( this->dim()==(int)b.size() ); + std::vector x(this->dim()); + int j_start; + double sum; + for(int i=0; idim(); i++) { + sum=0; + j_start=std::max(0,i-this->num_lower()); + for(int j=j_start; joperator()(i,j)*x[j]; + x[i]=(b[i]*this->saved_diag(i)) - sum; + } + return x; +} +// solves Rx=y +std::vector band_matrix::r_solve(const std::vector& b) const +{ + assert( this->dim()==(int)b.size() ); + std::vector x(this->dim()); + int j_stop; + double sum; + for(int i=this->dim()-1; i>=0; i--) { + sum=0; + j_stop=std::min(this->dim()-1,i+this->num_upper()); + for(int j=i+1; j<=j_stop; j++) sum += this->operator()(i,j)*x[j]; + x[i]=( b[i] - sum ) / this->operator()(i,i); + } + return x; +} + +std::vector band_matrix::lu_solve(const std::vector& b, + bool is_lu_decomposed) +{ + assert( this->dim()==(int)b.size() ); + std::vector x,y; + if(is_lu_decomposed==false) { + this->lu_decompose(); + } + y=this->l_solve(b); + x=this->r_solve(y); + return x; +} + +// machine precision of a double, i.e. the successor of 1 is 1+eps +double get_eps() +{ + //return std::numeric_limits::epsilon(); // __DBL_EPSILON__ + return 2.2204460492503131e-16; // 2^-52 +} + +// solutions for a + b*x = 0 +std::vector solve_linear(double a, double b) +{ + std::vector x; // roots + if(b==0.0) { + if(a==0.0) { + // 0*x = 0 + x.resize(1); + x[0] = 0.0; // any x solves it but we need to pick one + return x; + } else { + // 0*x + ... = 0, no solution + return x; + } + } else { + x.resize(1); + x[0] = -a/b; + return x; + } +} + +// solutions for a + b*x + c*x^2 = 0 +std::vector solve_quadratic(double a, double b, double c, + int newton_iter=0) +{ + if(c==0.0) { + return solve_linear(a,b); + } + // rescale so that we solve x^2 + 2p x + q = (x+p)^2 + q - p^2 = 0 + double p=0.5*b/c; + double q=a/c; + double discr = p*p-q; + const double eps=0.5*internal::get_eps(); + double discr_err = (6.0*(p*p)+3.0*fabs(q)+fabs(discr))*eps; + + std::vector x; // roots + if(fabs(discr)<=discr_err) { + // discriminant is zero --> one root + x.resize(1); + x[0] = -p; + } else if(discr<0) { + // no root + } else { + // two roots + x.resize(2); + x[0] = -p - sqrt(discr); + x[1] = -p + sqrt(discr); + } + + // improve solution via newton steps + for(size_t i=0; i1e-8) { + x[i] -= f/f1; + } + } + } + + return x; +} + +// solutions for the cubic equation: a + b*x +c*x^2 + d*x^3 = 0 +// this is a naive implementation of the analytic solution without +// optimisation for speed or numerical accuracy +// newton_iter: number of newton iterations to improve analytical solution +// see also +// gsl: gsl_poly_solve_cubic() in solve_cubic.c +// octave: roots.m - via eigenvalues of the Frobenius companion matrix +std::vector solve_cubic(double a, double b, double c, double d, + int newton_iter) +{ + if(d==0.0) { + return solve_quadratic(a,b,c,newton_iter); + } + + // convert to normalised form: a + bx + cx^2 + x^3 = 0 + if(d!=1.0) { + a/=d; + b/=d; + c/=d; + } + + // convert to depressed cubic: z^3 - 3pz - 2q = 0 + // via substitution: z = x + c/3 + std::vector z; // roots of the depressed cubic + double p = -(1.0/3.0)*b + (1.0/9.0)*(c*c); + double r = 2.0*(c*c)-9.0*b; + double q = -0.5*a - (1.0/54.0)*(c*r); + double discr=p*p*p-q*q; // discriminant + // calculating numerical round-off errors with assumptions: + // - each operation is precise but each intermediate result x + // when stored has max error of x*eps + // - only multiplication with a power of 2 introduces no new error + // - a,b,c,d and some fractions (e.g. 1/3) have rounding errors eps + // - p_err << |p|, q_err << |q|, ... (this is violated in rare cases) + // would be more elegant to use boost::numeric::interval + const double eps = internal::get_eps(); + double p_err = eps*((3.0/3.0)*fabs(b)+(4.0/9.0)*(c*c)+fabs(p)); + double r_err = eps*(6.0*(c*c)+18.0*fabs(b)+fabs(r)); + double q_err = 0.5*fabs(a)*eps + (1.0/54.0)*fabs(c)*(r_err+fabs(r)*3.0*eps) + + fabs(q)*eps; + double discr_err = (p*p) * (3.0*p_err + fabs(p)*2.0*eps) + + fabs(q) * (2.0*q_err + fabs(q)*eps) + fabs(discr)*eps; + + // depending on the discriminant we get different solutions + if(fabs(discr)<=discr_err) { + // discriminant zero: one or two real roots + if(fabs(p)<=p_err) { + // p and q are zero: single root + z.resize(1); + z[0] = 0.0; // triple root + } else { + z.resize(2); + z[0] = 2.0*q/p; // single root + z[1] = -0.5*z[0]; // double root + } + } else if(discr>0) { + // three real roots: via trigonometric solution + z.resize(3); + double ac = (1.0/3.0) * acos( q/(p*sqrt(p)) ); + double sq = 2.0*sqrt(p); + z[0] = sq * cos(ac); + z[1] = sq * cos(ac-2.0*M_PI/3.0); + z[2] = sq * cos(ac-4.0*M_PI/3.0); + } else if (discr<0.0) { + // single real root: via Cardano's fromula + z.resize(1); + double sgnq = (q >= 0 ? 1 : -1); + double basis = fabs(q) + sqrt(-discr); + double C = sgnq * pow(basis, 1.0/3.0); // c++11 has std::cbrt() + z[0] = C + p/C; + } + for(size_t i=0; i1e-8) { + z[i] -= f/f1; + } + } + } + // ensure if a=0 we get exactly x=0 as root + // TODO: remove this fudge + if(a==0.0) { + assert(z.size()>0); // cubic should always have at least one root + double xmin=fabs(z[0]); + size_t imin=0; + for(size_t i=1; ifabs(z[i])) { + xmin=fabs(z[i]); + imin=i; + } + } + z[imin]=0.0; // replace the smallest absolute value with 0 + } + std::sort(z.begin(), z.end()); + return z; +} + + +} // namespace internal + + +} // namespace tk + + +} // namespace + +#pragma GCC diagnostic pop + +#endif /* TK_SPLINE_H */ diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index ce261057..696cc280 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -8,8 +8,8 @@ #include "Power_Table.h" #include "SS2KLog.h" #include "BLE_Custom_Characteristic.h" +#include "spline.h" #include -#include #include #include #include @@ -444,170 +444,175 @@ TestResults PowerTable::testNeighbors(int i, int j, int testValue) { // } // } -void PowerTable::fillTable() { - tk::spline spline_interpolator; // Declare spline object once +// void PowerTable::fillTable() { +// tk::spline spline_interpolator; + +// // Perform horizontal cubic spline interpolation for each row +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// std::vector x_vals, y_vals; +// x_vals.reserve(POWERTABLE_WATT_SIZE); +// y_vals.reserve(POWERTABLE_WATT_SIZE); + +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { +// x_vals.push_back(j); +// y_vals.push_back(this->tableRow[i].tableEntry[j].targetPosition); +// } +// } + +// if (x_vals.size() > 2) { // Only interpolate if we have 3 points. (Cubic) +// spline_interpolator.set_points(x_vals, y_vals); + +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// int tempValue = static_cast(std::round(spline_interpolator(j))); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } +// } +// } + +// // Perform vertical cubic spline interpolation for each column +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// std::vector x_vals, y_vals; +// x_vals.reserve(POWERTABLE_CAD_SIZE); +// y_vals.reserve(POWERTABLE_CAD_SIZE); + +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { +// x_vals.push_back(i); +// y_vals.push_back(this->tableRow[i].tableEntry[j].targetPosition); +// } +// } + +// if (x_vals.size() > 2) { // Only interpolate if we have 3 points(cubic) +// spline_interpolator.set_points(x_vals, y_vals); + +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// int tempValue = static_cast(std::round(spline_interpolator(i))); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } +// } +// } +// } - // Perform horizontal cubic spline interpolation for each row +void PowerTable::fillTable() { + // Horizontal Interpolation for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - std::vector x_vals, y_vals; - x_vals.reserve(POWERTABLE_WATT_SIZE); - y_vals.reserve(POWERTABLE_WATT_SIZE); + std::vector x, y; + std::vector emptyIndices; + // Collect existing data points and empty indices for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - x_vals.push_back(j); - y_vals.push_back(this->tableRow[i].tableEntry[j].targetPosition); + x.push_back(j); + y.push_back(this->tableRow[i].tableEntry[j].targetPosition); + } else { + emptyIndices.push_back(j); } } - if (x_vals.size() > 1) { // Only interpolate if we have enough points. might turn into 2 - spline_interpolator.set_points(x_vals, y_vals); + if (x.size() > 2) { // Need 3 points + tk::spline s(x, y); - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - double interpolated_value = spline_interpolator(j); - if (this->testNeighbors(i, j, interpolated_value).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = static_cast(interpolated_value); - } + // Interpolate and fill empty cells + for (int j : emptyIndices) { + int tempValue = static_cast(std::round(s(j))); // Round to make more accurete + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } } } - // Perform vertical cubic spline interpolation for each column + // Vertical Interpolation for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - std::vector x_vals, y_vals; - x_vals.reserve(POWERTABLE_CAD_SIZE); - y_vals.reserve(POWERTABLE_CAD_SIZE); + std::vector x, y; + std::vector emptyIndices; + // Collect existing data points and empty indices for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - x_vals.push_back(i); - y_vals.push_back(this->tableRow[i].tableEntry[j].targetPosition); + x.push_back(i); + y.push_back(this->tableRow[i].tableEntry[j].targetPosition); + } else { + emptyIndices.push_back(i); } } - if (x_vals.size() > 1) { // Only interpolate if we have enough points - spline_interpolator.set_points(x_vals, y_vals); + if (x.size() > 2) { // Need 3 points + tk::spline s(x, y); - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - double interpolated_value = spline_interpolator(i); - if (this->testNeighbors(i, j, interpolated_value).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = static_cast(interpolated_value); - } + // Interpolate and fill empty cells + for (int i : emptyIndices) { + int tempValue = static_cast(std::round(s(i))); // Round to make more accurate + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } } } } -// void PowerTable::fillTable() { -// // Horizontal Interpolation using spline.h -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// std::vector x, y; -// std::vector emptyIndices; -// // Collect existing data points and empty indices +// void PowerTable::extrapFillTable() { +// // Extract known data points for each row +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// std::vector x_vals, y_vals; // for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { // if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { -// x.push_back(j); -// y.push_back(this->tableRow[i].tableEntry[j].targetPosition); -// } else { -// emptyIndices.push_back(j); +// x_vals.push_back(j); +// y_vals.push_back(this->tableRow[i].tableEntry[j].targetPosition); // } // } - -// if (x.size() > 2) { // Need at least three points for cubic spline -// tk::spline s(x, y); - -// // Interpolate and fill empty cells -// for (int j : emptyIndices) { -// int tempValue = static_cast(std::round(s(j))); // Use rounding to avoid truncation errors -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; + +// if (x_vals.size() > 2) { // Need at least two points for spline +// tk::spline spline_interp; +// spline_interp.set_points(x_vals, y_vals, tk::spline::cspline); // Cubic spline interpolation + +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// double extrapolatedValue = spline_interp(j); +// if (this->testNeighbors(i, j, extrapolatedValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = extrapolatedValue; +// } // } // } // } // } - -// // Vertical Interpolation using spline.h + +// // Extract known data points for each column // for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// std::vector x, y; -// std::vector emptyIndices; - -// // Collect existing data points and empty indices +// std::vector x_vals, y_vals; // for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { // if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { -// x.push_back(i); -// y.push_back(this->tableRow[i].tableEntry[j].targetPosition); -// } else { -// emptyIndices.push_back(i); +// x_vals.push_back(i); +// y_vals.push_back(this->tableRow[i].tableEntry[j].targetPosition); // } // } - -// if (x.size() > 2) { // Need at least three points for cubic spline -// tk::spline s(x, y); - -// // Interpolate and fill empty cells -// for (int i : emptyIndices) { -// int tempValue = static_cast(std::round(s(i))); // Use rounding to avoid truncation errors -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; + +// if (x_vals.size() > 2) { +// tk::spline spline_interp; +// spline_interp.set_points(x_vals, y_vals, tk::spline::cspline); + +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// double extrapolatedValue = spline_interp(i); +// if (this->testNeighbors(i, j, extrapolatedValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = extrapolatedValue; +// } // } // } // } // } // } -// void PowerTable::fillTable() { -// int tempValue = INT16_MIN; - -// // Fill each empty cell by linear interpolation -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// // Interpolate horizontally -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// // Find nearest left and right non-empty cells -// int left = j - 1; -// while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; -// int right = j + 1; -// while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - -// if (left >= 0 && right < POWERTABLE_WATT_SIZE) { -// // Linear interpolation -// tempValue = this->tableRow[i].tableEntry[left].targetPosition + -// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) * (j - left) / (right - left); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// } -// } - -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// // Interpolate vertically -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// // Find nearest top and bottom non-empty cells -// int top = i - 1; -// while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; -// int bottom = i + 1; -// while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; - -// if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { -// // Linear interpolation -// tempValue = this->tableRow[top].tableEntry[j].targetPosition + -// (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) * (i - top) / (bottom - top); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// } -// } -// } void PowerTable::extrapFillTable() { // Find the center of the known data @@ -869,6 +874,42 @@ void PowerTable::extrapolateDiagonal() { } } +// void PowerTable::extrapolateDiagonal() { +// for (int diag = -POWERTABLE_CAD_SIZE + 1; diag < POWERTABLE_WATT_SIZE; ++diag) { +// std::vector x, y; +// std::vector indices; + +// // Collect known data points along the diagonal +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// int j = i + diag; +// if (j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { +// x.push_back(i); +// y.push_back(this->tableRow[i].tableEntry[j].targetPosition); +// indices.push_back(i); +// } +// } + +// // If we have enough points, perform cubic spline interpolation/extrapolation +// if (x.size() > 2) { +// tk::spline splineInterp; +// splineInterp.set_points(x, y, tk::spline::cspline); + +// // Extrapolate missing values +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// int j = i + diag; +// if (j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// double tempValue = splineInterp(i); + +// if (testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = static_cast(tempValue); +// } +// } +// } +// } +// } +// } + + // double polynomialExtrapolation(const std::vector& x, const std::vector& y, double x_new, int order = 1) { // if (x.size() != y.size() || x.size() < order + 1 || order < 0) { // return std::numeric_limits::quiet_NaN(); // Return NaN for invalid input From 89c5180dfa83d34b24014053de5d29f2f6d13217 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Thu, 27 Feb 2025 15:47:22 -0600 Subject: [PATCH 090/451] imported spine.h library and implemented cubic spline interpolation --- include/spline.h | 947 ++++++++++++++++++++++++++++++++++++++++++++ src/Power_Table.cpp | 130 ++++-- 2 files changed, 1042 insertions(+), 35 deletions(-) create mode 100644 include/spline.h diff --git a/include/spline.h b/include/spline.h new file mode 100644 index 00000000..5e78a5ab --- /dev/null +++ b/include/spline.h @@ -0,0 +1,947 @@ +/* + * spline.h + * + * simple cubic spline interpolation library without external + * dependencies + * + * --------------------------------------------------------------------- + * Copyright (C) 2011, 2014, 2016, 2021 Tino Kluge (ttk448 at gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * --------------------------------------------------------------------- + * + */ + + + #ifndef TK_SPLINE_H + #define TK_SPLINE_H + + #include + #include + #include + #include + #include + #ifdef HAVE_SSTREAM + #include + #include + #endif // HAVE_SSTREAM + + // not ideal but disable unused-function warnings + // (we get them because we have implementations in the header file, + // and this is because we want to be able to quickly separate them + // into a cpp file if necessary) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-function" + + // unnamed namespace only because the implementation is in this + // header file and we don't want to export symbols to the obj files + namespace + { + + namespace tk + { + + // spline interpolation + class spline + { + public: + // spline types + enum spline_type { + linear = 10, // linear interpolation + cspline = 30, // cubic splines (classical C^2) + cspline_hermite = 31 // cubic hermite splines (local, only C^1) + }; + + // boundary condition type for the spline end-points + enum bd_type { + first_deriv = 1, + second_deriv = 2, + not_a_knot = 3 + }; + + protected: + std::vector m_x,m_y; // x,y coordinates of points + // interpolation parameters + // f(x) = a_i + b_i*(x-x_i) + c_i*(x-x_i)^2 + d_i*(x-x_i)^3 + // where a_i = y_i, or else it won't go through grid points + std::vector m_b,m_c,m_d; // spline coefficients + double m_c0; // for left extrapolation + spline_type m_type; + bd_type m_left, m_right; + double m_left_value, m_right_value; + bool m_made_monotonic; + void set_coeffs_from_b(); // calculate c_i, d_i from b_i + size_t find_closest(double x) const; // closest idx so that m_x[idx]<=x + + public: + // default constructor: set boundary condition to be zero curvature + // at both ends, i.e. natural splines + spline(): m_type(cspline), + m_left(second_deriv), m_right(second_deriv), + m_left_value(0.0), m_right_value(0.0), m_made_monotonic(false) + { + ; + } + spline(const std::vector& X, const std::vector& Y, + spline_type type = cspline, + bool make_monotonic = false, + bd_type left = second_deriv, double left_value = 0.0, + bd_type right = second_deriv, double right_value = 0.0 + ): + m_type(type), + m_left(left), m_right(right), + m_left_value(left_value), m_right_value(right_value), + m_made_monotonic(false) // false correct here: make_monotonic() sets it + { + this->set_points(X,Y,m_type); + if(make_monotonic) { + this->make_monotonic(); + } + } + + + // modify boundary conditions: if called it must be before set_points() + void set_boundary(bd_type left, double left_value, + bd_type right, double right_value); + + // set all data points (cubic_spline=false means linear interpolation) + void set_points(const std::vector& x, + const std::vector& y, + spline_type type=cspline); + + // adjust coefficients so that the spline becomes piecewise monotonic + // where possible + // this is done by adjusting slopes at grid points by a non-negative + // factor and this will break C^2 + // this can also break boundary conditions if adjustments need to + // be made at the boundary points + // returns false if no adjustments have been made, true otherwise + bool make_monotonic(); + + // evaluates the spline at point x + double operator() (double x) const; + double deriv(int order, double x) const; + + // solves for all x so that: spline(x) = y + std::vector solve(double y, bool ignore_extrapolation=true) const; + + // returns the input data points + std::vector get_x() const { return m_x; } + std::vector get_y() const { return m_y; } + double get_x_min() const { assert(!m_x.empty()); return m_x.front(); } + double get_x_max() const { assert(!m_x.empty()); return m_x.back(); } + + #ifdef HAVE_SSTREAM + // spline info string, i.e. spline type, boundary conditions etc. + std::string info() const; + #endif // HAVE_SSTREAM + + }; + + + + namespace internal + { + + // band matrix solver + class band_matrix + { + private: + std::vector< std::vector > m_upper; // upper band + std::vector< std::vector > m_lower; // lower band + public: + band_matrix() {}; // constructor + band_matrix(int dim, int n_u, int n_l); // constructor + ~band_matrix() {}; // destructor + void resize(int dim, int n_u, int n_l); // init with dim,n_u,n_l + int dim() const; // matrix dimension + int num_upper() const + { + return (int)m_upper.size()-1; + } + int num_lower() const + { + return (int)m_lower.size()-1; + } + // access operator + double & operator () (int i, int j); // write + double operator () (int i, int j) const; // read + // we can store an additional diagonal (in m_lower) + double& saved_diag(int i); + double saved_diag(int i) const; + void lu_decompose(); + std::vector r_solve(const std::vector& b) const; + std::vector l_solve(const std::vector& b) const; + std::vector lu_solve(const std::vector& b, + bool is_lu_decomposed=false); + + }; + + double get_eps(); + + std::vector solve_cubic(double a, double b, double c, double d, + int newton_iter=0); + + } // namespace internal + + + + + // --------------------------------------------------------------------- + // implementation part, which could be separated into a cpp file + // --------------------------------------------------------------------- + + // spline implementation + // ----------------------- + + void spline::set_boundary(spline::bd_type left, double left_value, + spline::bd_type right, double right_value) + { + assert(m_x.size()==0); // set_points() must not have happened yet + m_left=left; + m_right=right; + m_left_value=left_value; + m_right_value=right_value; + } + + + void spline::set_coeffs_from_b() + { + assert(m_x.size()==m_y.size()); + assert(m_x.size()==m_b.size()); + assert(m_x.size()>2); + size_t n=m_b.size(); + if(m_c.size()!=n) + m_c.resize(n); + if(m_d.size()!=n) + m_d.resize(n); + + for(size_t i=0; i& x, + const std::vector& y, + spline_type type) + { + assert(x.size()==y.size()); + assert(x.size()>=3); + // not-a-knot with 3 points has many solutions + if(m_left==not_a_knot || m_right==not_a_knot) + assert(x.size()>=4); + m_type=type; + m_made_monotonic=false; + m_x=x; + m_y=y; + int n = (int) x.size(); + // check strict monotonicity of input vector x + for(int i=0; i rhs(n); + for(int i=1; i2); + bool modified = false; + const int n=(int)m_x.size(); + // make sure: input data monotonic increasing --> b_i>=0 + // input data monotonic decreasing --> b_i<=0 + for(int i=0; i=m_y[i]) && (m_y[i]>=m_y[ip1]) && m_b[i]>0.0) ) { + modified=true; + m_b[i]=0.0; + } + } + // if input data is monotonic (b[i], b[i+1], avg have all the same sign) + // ensure a sufficient criteria for monotonicity is satisfied: + // sqrt(b[i]^2+b[i+1]^2) <= 3 |avg|, with avg=(y[i+1]-y[i])/h, + for(int i=0; i=0.0 && m_b[i+1]>=0.0 && avg>0.0) || + (m_b[i]<=0.0 && m_b[i+1]<=0.0 && avg<0.0) ) { + // input data is monotonic + double r = sqrt(m_b[i]*m_b[i]+m_b[i+1]*m_b[i+1])/std::fabs(avg); + if(r>3.0) { + // sufficient criteria for monotonicity: r<=3 + // adjust b[i] and b[i+1] + modified=true; + m_b[i] *= (3.0/r); + m_b[i+1] *= (3.0/r); + } + } + } + + if(modified==true) { + set_coeffs_from_b(); + m_made_monotonic=true; + } + + return modified; + } + + // return the closest idx so that m_x[idx] <= x (return 0 if x::const_iterator it; + it=std::upper_bound(m_x.begin(),m_x.end(),x); // *it > x + size_t idx = std::max( int(it-m_x.begin())-1, 0); // m_x[idx] <= x + return idx; + } + + double spline::operator() (double x) const + { + // polynomial evaluation using Horner's scheme + // TODO: consider more numerically accurate algorithms, e.g.: + // - Clenshaw + // - Even-Odd method by A.C.R. Newbery + // - Compensated Horner Scheme + size_t n=m_x.size(); + size_t idx=find_closest(x); + + double h=x-m_x[idx]; + double interpol; + if(xm_x[n-1]) { + // extrapolation to the right + interpol=(m_c[n-1]*h + m_b[n-1])*h + m_y[n-1]; + } else { + // interpolation + interpol=((m_d[idx]*h + m_c[idx])*h + m_b[idx])*h + m_y[idx]; + } + return interpol; + } + + double spline::deriv(int order, double x) const + { + assert(order>0); + size_t n=m_x.size(); + size_t idx = find_closest(x); + + double h=x-m_x[idx]; + double interpol; + if(xm_x[n-1]) { + // extrapolation to the right + switch(order) { + case 1: + interpol=2.0*m_c[n-1]*h + m_b[n-1]; + break; + case 2: + interpol=2.0*m_c[n-1]; + break; + default: + interpol=0.0; + break; + } + } else { + // interpolation + switch(order) { + case 1: + interpol=(3.0*m_d[idx]*h + 2.0*m_c[idx])*h + m_b[idx]; + break; + case 2: + interpol=6.0*m_d[idx]*h + 2.0*m_c[idx]; + break; + case 3: + interpol=6.0*m_d[idx]; + break; + default: + interpol=0.0; + break; + } + } + return interpol; + } + + std::vector spline::solve(double y, bool ignore_extrapolation) const + { + std::vector x; // roots for the entire spline + std::vector root; // roots for each piecewise cubic + const size_t n=m_x.size(); + + // left extrapolation + if(ignore_extrapolation==false) { + root = internal::solve_cubic(m_y[0]-y,m_b[0],m_c0,0.0,1); + for(size_t j=0; j0) ? (m_x[i]-m_x[i-1]) : 0.0; + double eps = internal::get_eps()*512.0*std::min(h,1.0); + if( (-eps<=root[j]) && (root[j]0 && x.back()+eps > new_root) { + x.back()=new_root; // avoid spurious duplicate roots + } else { + x.push_back(new_root); + } + } + } + } + + // right extrapolation + if(ignore_extrapolation==false) { + root = internal::solve_cubic(m_y[n-1]-y,m_b[n-1],m_c[n-1],0.0,1); + for(size_t j=0; j0); + assert(n_u>=0); + assert(n_l>=0); + m_upper.resize(n_u+1); + m_lower.resize(n_l+1); + for(size_t i=0; i0) { + return m_upper[0].size(); + } else { + return 0; + } + } + + + // defines the new operator (), so that we can access the elements + // by A(i,j), index going from i=0,...,dim()-1 + double & band_matrix::operator () (int i, int j) + { + int k=j-i; // what band is the entry + assert( (i>=0) && (i=0) && (j diagonal, k<0 lower left part, k>0 upper right part + if(k>=0) return m_upper[k][i]; + else return m_lower[-k][i]; + } + double band_matrix::operator () (int i, int j) const + { + int k=j-i; // what band is the entry + assert( (i>=0) && (i=0) && (j diagonal, k<0 lower left part, k>0 upper right part + if(k>=0) return m_upper[k][i]; + else return m_lower[-k][i]; + } + // second diag (used in LU decomposition), saved in m_lower + double band_matrix::saved_diag(int i) const + { + assert( (i>=0) && (i=0) && (idim(); i++) { + assert(this->operator()(i,i)!=0.0); + this->saved_diag(i)=1.0/this->operator()(i,i); + j_min=std::max(0,i-this->num_lower()); + j_max=std::min(this->dim()-1,i+this->num_upper()); + for(int j=j_min; j<=j_max; j++) { + this->operator()(i,j) *= this->saved_diag(i); + } + this->operator()(i,i)=1.0; // prevents rounding errors + } + + // Gauss LR-Decomposition + for(int k=0; kdim(); k++) { + i_max=std::min(this->dim()-1,k+this->num_lower()); // num_lower not a mistake! + for(int i=k+1; i<=i_max; i++) { + assert(this->operator()(k,k)!=0.0); + x=-this->operator()(i,k)/this->operator()(k,k); + this->operator()(i,k)=-x; // assembly part of L + j_max=std::min(this->dim()-1,k+this->num_upper()); + for(int j=k+1; j<=j_max; j++) { + // assembly part of R + this->operator()(i,j)=this->operator()(i,j)+x*this->operator()(k,j); + } + } + } + } + // solves Ly=b + std::vector band_matrix::l_solve(const std::vector& b) const + { + assert( this->dim()==(int)b.size() ); + std::vector x(this->dim()); + int j_start; + double sum; + for(int i=0; idim(); i++) { + sum=0; + j_start=std::max(0,i-this->num_lower()); + for(int j=j_start; joperator()(i,j)*x[j]; + x[i]=(b[i]*this->saved_diag(i)) - sum; + } + return x; + } + // solves Rx=y + std::vector band_matrix::r_solve(const std::vector& b) const + { + assert( this->dim()==(int)b.size() ); + std::vector x(this->dim()); + int j_stop; + double sum; + for(int i=this->dim()-1; i>=0; i--) { + sum=0; + j_stop=std::min(this->dim()-1,i+this->num_upper()); + for(int j=i+1; j<=j_stop; j++) sum += this->operator()(i,j)*x[j]; + x[i]=( b[i] - sum ) / this->operator()(i,i); + } + return x; + } + + std::vector band_matrix::lu_solve(const std::vector& b, + bool is_lu_decomposed) + { + assert( this->dim()==(int)b.size() ); + std::vector x,y; + if(is_lu_decomposed==false) { + this->lu_decompose(); + } + y=this->l_solve(b); + x=this->r_solve(y); + return x; + } + + // machine precision of a double, i.e. the successor of 1 is 1+eps + double get_eps() + { + //return std::numeric_limits::epsilon(); // __DBL_EPSILON__ + return 2.2204460492503131e-16; // 2^-52 + } + + // solutions for a + b*x = 0 + std::vector solve_linear(double a, double b) + { + std::vector x; // roots + if(b==0.0) { + if(a==0.0) { + // 0*x = 0 + x.resize(1); + x[0] = 0.0; // any x solves it but we need to pick one + return x; + } else { + // 0*x + ... = 0, no solution + return x; + } + } else { + x.resize(1); + x[0] = -a/b; + return x; + } + } + + // solutions for a + b*x + c*x^2 = 0 + std::vector solve_quadratic(double a, double b, double c, + int newton_iter=0) + { + if(c==0.0) { + return solve_linear(a,b); + } + // rescale so that we solve x^2 + 2p x + q = (x+p)^2 + q - p^2 = 0 + double p=0.5*b/c; + double q=a/c; + double discr = p*p-q; + const double eps=0.5*internal::get_eps(); + double discr_err = (6.0*(p*p)+3.0*fabs(q)+fabs(discr))*eps; + + std::vector x; // roots + if(fabs(discr)<=discr_err) { + // discriminant is zero --> one root + x.resize(1); + x[0] = -p; + } else if(discr<0) { + // no root + } else { + // two roots + x.resize(2); + x[0] = -p - sqrt(discr); + x[1] = -p + sqrt(discr); + } + + // improve solution via newton steps + for(size_t i=0; i1e-8) { + x[i] -= f/f1; + } + } + } + + return x; + } + + // solutions for the cubic equation: a + b*x +c*x^2 + d*x^3 = 0 + // this is a naive implementation of the analytic solution without + // optimisation for speed or numerical accuracy + // newton_iter: number of newton iterations to improve analytical solution + // see also + // gsl: gsl_poly_solve_cubic() in solve_cubic.c + // octave: roots.m - via eigenvalues of the Frobenius companion matrix + std::vector solve_cubic(double a, double b, double c, double d, + int newton_iter) + { + if(d==0.0) { + return solve_quadratic(a,b,c,newton_iter); + } + + // convert to normalised form: a + bx + cx^2 + x^3 = 0 + if(d!=1.0) { + a/=d; + b/=d; + c/=d; + } + + // convert to depressed cubic: z^3 - 3pz - 2q = 0 + // via substitution: z = x + c/3 + std::vector z; // roots of the depressed cubic + double p = -(1.0/3.0)*b + (1.0/9.0)*(c*c); + double r = 2.0*(c*c)-9.0*b; + double q = -0.5*a - (1.0/54.0)*(c*r); + double discr=p*p*p-q*q; // discriminant + // calculating numerical round-off errors with assumptions: + // - each operation is precise but each intermediate result x + // when stored has max error of x*eps + // - only multiplication with a power of 2 introduces no new error + // - a,b,c,d and some fractions (e.g. 1/3) have rounding errors eps + // - p_err << |p|, q_err << |q|, ... (this is violated in rare cases) + // would be more elegant to use boost::numeric::interval + const double eps = internal::get_eps(); + double p_err = eps*((3.0/3.0)*fabs(b)+(4.0/9.0)*(c*c)+fabs(p)); + double r_err = eps*(6.0*(c*c)+18.0*fabs(b)+fabs(r)); + double q_err = 0.5*fabs(a)*eps + (1.0/54.0)*fabs(c)*(r_err+fabs(r)*3.0*eps) + + fabs(q)*eps; + double discr_err = (p*p) * (3.0*p_err + fabs(p)*2.0*eps) + + fabs(q) * (2.0*q_err + fabs(q)*eps) + fabs(discr)*eps; + + // depending on the discriminant we get different solutions + if(fabs(discr)<=discr_err) { + // discriminant zero: one or two real roots + if(fabs(p)<=p_err) { + // p and q are zero: single root + z.resize(1); + z[0] = 0.0; // triple root + } else { + z.resize(2); + z[0] = 2.0*q/p; // single root + z[1] = -0.5*z[0]; // double root + } + } else if(discr>0) { + // three real roots: via trigonometric solution + z.resize(3); + double ac = (1.0/3.0) * acos( q/(p*sqrt(p)) ); + double sq = 2.0*sqrt(p); + z[0] = sq * cos(ac); + z[1] = sq * cos(ac-2.0*M_PI/3.0); + z[2] = sq * cos(ac-4.0*M_PI/3.0); + } else if (discr<0.0) { + // single real root: via Cardano's fromula + z.resize(1); + double sgnq = (q >= 0 ? 1 : -1); + double basis = fabs(q) + sqrt(-discr); + double C = sgnq * pow(basis, 1.0/3.0); // c++11 has std::cbrt() + z[0] = C + p/C; + } + for(size_t i=0; i1e-8) { + z[i] -= f/f1; + } + } + } + // ensure if a=0 we get exactly x=0 as root + // TODO: remove this fudge + if(a==0.0) { + assert(z.size()>0); // cubic should always have at least one root + double xmin=fabs(z[0]); + size_t imin=0; + for(size_t i=1; ifabs(z[i])) { + xmin=fabs(z[i]); + imin=i; + } + } + z[imin]=0.0; // replace the smallest absolute value with 0 + } + std::sort(z.begin(), z.end()); + return z; + } + + + } // namespace internal + + + } // namespace tk + + + } // namespace + + #pragma GCC diagnostic pop + + #endif /* TK_SPLINE_H */ \ No newline at end of file diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 3c7dc447..53d58a9c 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -7,6 +7,7 @@ #include "Power_Table.h" #include "SS2KLog.h" +#include "spline.h" #include "BLE_Custom_Characteristic.h" #include #include @@ -339,54 +340,113 @@ TestResults PowerTable::testNeighbors(int i, int j, int testValue) { } void PowerTable::fillTable() { - int tempValue = INT16_MIN; - - // Fill each empty cell by linear interpolation + // Horizontal Interpolation for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - // Interpolate horizontally - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest left and right non-empty cells - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + std::vector x, y; + std::vector emptyIndices; - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear interpolation - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) * (j - left) / (right - left); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + // Collect existing data points and empty indices + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + x.push_back(j); + y.push_back(this->tableRow[i].tableEntry[j].targetPosition); + } else { + emptyIndices.push_back(j); + } + } + + if (x.size() > 2) { // Need 3 points + tk::spline s(x, y); + + // Interpolate and fill empty cells + for (int j : emptyIndices) { + int tempValue = static_cast(std::round(s(j))); // Round to make more accurete + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } } - } } - } } + // Vertical Interpolation for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - // Interpolate vertically - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top and bottom non-empty cells - int top = i - 1; - while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; - int bottom = i + 1; - while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; + std::vector x, y; + std::vector emptyIndices; - if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { - // Linear interpolation - tempValue = this->tableRow[top].tableEntry[j].targetPosition + - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) * (i - top) / (bottom - top); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + // Collect existing data points and empty indices + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + x.push_back(i); + y.push_back(this->tableRow[i].tableEntry[j].targetPosition); + } else { + emptyIndices.push_back(i); + } + } + + if (x.size() > 2) { // Need 3 points + tk::spline s(x, y); + + // Interpolate and fill empty cells + for (int i : emptyIndices) { + int tempValue = static_cast(std::round(s(i))); // Round to make more accurate + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } } - } } - } } } +// Old Fill Function +// void PowerTable::fillTable() { +// int tempValue = INT16_MIN; + +// // Fill each empty cell by linear interpolation +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// // Interpolate horizontally +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// // Find nearest left and right non-empty cells +// int left = j - 1; +// while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; +// int right = j + 1; +// while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + +// if (left >= 0 && right < POWERTABLE_WATT_SIZE) { +// // Linear interpolation +// tempValue = this->tableRow[i].tableEntry[left].targetPosition + +// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) * (j - left) / (right - left); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } +// } +// } + +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// // Interpolate vertically +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// // Find nearest top and bottom non-empty cells +// int top = i - 1; +// while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; +// int bottom = i + 1; +// while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; + +// if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { +// // Linear interpolation +// tempValue = this->tableRow[top].tableEntry[j].targetPosition + +// (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) * (i - top) / (bottom - top); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } +// } +// } +// } + void PowerTable::extrapFillTable() { // Find the center of the known data int sumRow = 0, sumCol = 0, count = 0; From 9a43bb2f180b152949274727b861a6b4578e5dba Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Thu, 27 Feb 2025 18:12:45 -0600 Subject: [PATCH 091/451] extrap functions working --- src/Power_Table.cpp | 634 +++++--------------------------------------- 1 file changed, 67 insertions(+), 567 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 696cc280..b76b24e2 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -345,163 +345,6 @@ TestResults PowerTable::testNeighbors(int i, int j, int testValue) { return returnResult; } -// struct SplineCoefficients { -// std::vector a, b, c, d, x; -// }; - -// SplineCoefficients computeCubicSpline(const std::vector& x, const std::vector& y) { -// int n = x.size() - 1; -// std::vector interval_widths(n), alpha(n), l(n + 1), mu(n), z(n + 1); -// std::vector a(y), b(n), c(n + 1), d(n); - -// for (int i = 0; i < n; ++i) { -// interval_widths[i] = x[i + 1] - x[i]; -// } - -// for (int i = 1; i < n; ++i) { -// alpha[i] = (3.0 / interval_widths[i]) * (y[i + 1] - y[i]) - (3.0 / interval_widths[i - 1]) * (y[i] - y[i - 1]); -// } - -// l[0] = 1.0; -// mu[0] = z[0] = 0.0; - -// for (int i = 1; i < n; ++i) { -// l[i] = 2.0 * (x[i + 1] - x[i - 1]) - interval_widths[i - 1] * mu[i - 1]; -// mu[i] = interval_widths[i] / l[i]; -// z[i] = (alpha[i] - interval_widths[i - 1] * z[i - 1]) / l[i]; -// } - -// l[n] = 1.0; -// z[n] = c[n] = 0.0; - -// for (int j = n - 1; j >= 0; --j) { -// c[j] = z[j] - mu[j] * c[j + 1]; -// b[j] = (y[j + 1] - y[j]) / interval_widths[j] - interval_widths[j] * (c[j + 1] + 2.0 * c[j]) / 3.0; -// d[j] = (c[j + 1] - c[j]) / (3.0 * interval_widths[j]); -// } - -// return {a, b, c, d, x}; -// } - -// double interpolateCubicSpline(const SplineCoefficients& spline, double x_val) { -// int n = spline.x.size() - 1; - -// // Binary search to find the correct interval -// auto it = std::lower_bound(spline.x.begin(), spline.x.end(), x_val); -// int i = std::distance(spline.x.begin(), it); -// if (i > 0) { -// i--; -// } else if (i == n) { -// i--; // Handle the case where x_val is equal to the last x -// } - - -// double dx = x_val - spline.x[i]; -// return spline.a[i] + spline.b[i] * dx + spline.c[i] * dx * dx + spline.d[i] * dx * dx * dx; -// } - -// void PowerTable::fillTable() { -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// std::vector x_vals, y_vals; -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { -// x_vals.push_back(j); -// y_vals.push_back(this->tableRow[i].tableEntry[j].targetPosition); -// } -// } -// if (x_vals.size() > 1) { -// SplineCoefficients spline = computeCubicSpline(x_vals, y_vals); -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// double interpolated_value = interpolateCubicSpline(spline, j); -// if (this->testNeighbors(i, j, static_cast(std::round(interpolated_value))).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(interpolated_value)); -// } -// } -// } -// } -// } - -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// std::vector x_vals, y_vals; -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { -// x_vals.push_back(i); -// y_vals.push_back(this->tableRow[i].tableEntry[j].targetPosition); -// } -// } -// if (x_vals.size() > 1) { -// SplineCoefficients spline = computeCubicSpline(x_vals, y_vals); -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// double interpolated_value = interpolateCubicSpline(spline, i); -// if (this->testNeighbors(i, j, static_cast(std::round(interpolated_value))).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(interpolated_value)); -// } -// } -// } -// } -// } -// } - -// void PowerTable::fillTable() { -// tk::spline spline_interpolator; - -// // Perform horizontal cubic spline interpolation for each row -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// std::vector x_vals, y_vals; -// x_vals.reserve(POWERTABLE_WATT_SIZE); -// y_vals.reserve(POWERTABLE_WATT_SIZE); - -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { -// x_vals.push_back(j); -// y_vals.push_back(this->tableRow[i].tableEntry[j].targetPosition); -// } -// } - -// if (x_vals.size() > 2) { // Only interpolate if we have 3 points. (Cubic) -// spline_interpolator.set_points(x_vals, y_vals); - -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// int tempValue = static_cast(std::round(spline_interpolator(j))); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// } -// } - -// // Perform vertical cubic spline interpolation for each column -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// std::vector x_vals, y_vals; -// x_vals.reserve(POWERTABLE_CAD_SIZE); -// y_vals.reserve(POWERTABLE_CAD_SIZE); - -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { -// x_vals.push_back(i); -// y_vals.push_back(this->tableRow[i].tableEntry[j].targetPosition); -// } -// } - -// if (x_vals.size() > 2) { // Only interpolate if we have 3 points(cubic) -// spline_interpolator.set_points(x_vals, y_vals); - -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// int tempValue = static_cast(std::round(spline_interpolator(i))); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// } -// } -// } - void PowerTable::fillTable() { // Horizontal Interpolation for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { @@ -548,7 +391,7 @@ void PowerTable::fillTable() { if (x.size() > 2) { // Need 3 points tk::spline s(x, y); - + // Interpolate and fill empty cells for (int i : emptyIndices) { int tempValue = static_cast(std::round(s(i))); // Round to make more accurate @@ -560,437 +403,94 @@ void PowerTable::fillTable() { } } - -// void PowerTable::extrapFillTable() { -// // Extract known data points for each row -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// std::vector x_vals, y_vals; -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { -// x_vals.push_back(j); -// y_vals.push_back(this->tableRow[i].tableEntry[j].targetPosition); -// } -// } - -// if (x_vals.size() > 2) { // Need at least two points for spline -// tk::spline spline_interp; -// spline_interp.set_points(x_vals, y_vals, tk::spline::cspline); // Cubic spline interpolation - -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// double extrapolatedValue = spline_interp(j); -// if (this->testNeighbors(i, j, extrapolatedValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = extrapolatedValue; -// } -// } -// } -// } -// } - -// // Extract known data points for each column -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// std::vector x_vals, y_vals; -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { -// x_vals.push_back(i); -// y_vals.push_back(this->tableRow[i].tableEntry[j].targetPosition); -// } -// } - -// if (x_vals.size() > 2) { -// tk::spline spline_interp; -// spline_interp.set_points(x_vals, y_vals, tk::spline::cspline); - -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// double extrapolatedValue = spline_interp(i); -// if (this->testNeighbors(i, j, extrapolatedValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = extrapolatedValue; -// } -// } -// } -// } -// } -// } - - void PowerTable::extrapFillTable() { - // Find the center of the known data - int sumRow = 0, sumCol = 0, count = 0; - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - sumRow += i; - sumCol += j; - count++; - } - } - } - - // prevent divide by zero - if (count == 0) { - return; - } - int centerRow = sumRow / count; - int centerCol = sumCol / count; - int tempValue = INT16_MIN; - - // Function to extrapolate a single cell based on its neighbors - auto extrapolateCell = [&](int i, int j) { - // Find nearest left non-empty cell - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - - // Find nearest right non-empty cell - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear extrapolation - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - if (j < left) { - // Extrapolate to the left - tempValue = this->tableRow[i].tableEntry[left].targetPosition - - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } else if (j > right) { - // Extrapolate to the right - tempValue = this->tableRow[i].tableEntry[right].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + // Horizontal Extrapolation + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + std::vector x, y; + + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + x.push_back(j); + y.push_back(this->tableRow[i].tableEntry[j].targetPosition); } - } - } - } else if (left - 1 >= 0) { - // Only left value available, extrapolate to the right - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (right + 1 < POWERTABLE_WATT_SIZE) { - // Only right value available, extrapolate to the left - if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - tempValue = - this->tableRow[i].tableEntry[right].targetPosition - - (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } } - } - }; - - // Extrapolate horizontally and vertically starting from the center - for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { - for (int i = centerRow - distance; i <= centerRow + distance; ++i) { - for (int j = centerCol - distance; j <= centerCol + distance; ++j) { - if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - extrapolateCell(i, j); - } - } - } - } - // Extrapolate each empty cell - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - // Extrapolate horizontally - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest left non-empty cell - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - - // Find nearest right non-empty cell - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear extrapolation - if (j < left) { - // Extrapolate to the left - tempValue = this->tableRow[i].tableEntry[left].targetPosition - - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - - } else if (j > right) { - // Extrapolate to the right - tempValue = this->tableRow[i].tableEntry[right].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (left >= 1) { - // Only left value available, extrapolate to the right - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (right + 1 < POWERTABLE_WATT_SIZE) { - // Only right value available, extrapolate to the left - if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[right].targetPosition - - (right - j) * - (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + + if (x.size() > 2) { // Need 3 points + tk::spline s; + s.set_points(x, y, tk::spline::cspline); // Set points checks if its within range to extrapolate + + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + int tempValue = static_cast(std::round(s(j))); // Round to make more accurate + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } } - } } - } } - } } - + + // Vertical Extrapolation for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - // Extrapolate vertically - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top non-empty cell - int top = i - 1; - while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; - - // Find nearest bottom non-empty cell - int bottom = i + 1; - while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; - - if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { - // Linear extrapolation - if (i < top) { - // Extrapolate upwards - tempValue = this->tableRow[top].tableEntry[j].targetPosition - - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } else if (i > bottom) { - // Extrapolate downwards - tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (top >= 1) { - // Only top value available, extrapolate downwards - if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { - tempValue = this->tableRow[top].tableEntry[j].targetPosition + - (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } else { - } + std::vector x, y; + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + x.push_back(i); + y.push_back(this->tableRow[i].tableEntry[j].targetPosition); } - } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { - // Only bottom value available, extrapolate upwards - if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { - tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - - (bottom - i) * - (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + } + + if (x.size() > 2) { + tk::spline s; + s.set_points(x, y, tk::spline::cspline); + + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + int tempValue = static_cast(std::round(s(i))); // Round to make more accurate + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } } - } } - } } } void PowerTable::extrapolateDiagonal() { - int tempValue = INT16_MIN; - - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top-left non-empty cell - int topLeftRow = i - 1, topLeftCol = j - 1; - while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { - topLeftRow--; - topLeftCol--; - } - - // Find nearest bottom-right non-empty cell - int bottomRightRow = i + 1, bottomRightCol = j + 1; - while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && - this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { - bottomRightRow++; - bottomRightCol++; - } - - // Perform diagonal extrapolation (top-left to bottom-right) - if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { - tempValue = - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + - ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / - (bottomRightCol - topLeftCol); - - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - - // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left - if (tempValue == INT16_MIN) { - // Find nearest top-right non-empty cell - int topRightRow = i - 1, topRightCol = j + 1; - while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { - topRightRow--; - topRightCol++; - } - - // Find nearest bottom-left non-empty cell - int bottomLeftRow = i + 1, bottomLeftCol = j - 1; - while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { - bottomLeftRow++; - bottomLeftCol--; + for (int diag = -POWERTABLE_CAD_SIZE + 1; diag < POWERTABLE_WATT_SIZE; ++diag) { + std::vector x, y; + std::vector emptyIndices; + + // get Data + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + int j = i + diag; + if (j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + x.push_back(i); + y.push_back(this->tableRow[i].tableEntry[j].targetPosition); + emptyIndices.push_back(i); } - - // Perform diagonal extrapolation (top-right to bottom-left) - if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { - tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + - ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * - (j - bottomLeftCol)) / - (topRightCol - bottomLeftCol); - - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + } + + if (x.size() > 2) { // 3 points needed + tk::spline s; + s.set_points(x, y, tk::spline::cspline); + + // Extrapolate + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + int j = i + diag; + if (j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + int tempValue = static_cast(std::round(s(i))); // Round to make more accurate + + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } } - } } - } } } -// void PowerTable::extrapolateDiagonal() { -// for (int diag = -POWERTABLE_CAD_SIZE + 1; diag < POWERTABLE_WATT_SIZE; ++diag) { -// std::vector x, y; -// std::vector indices; - -// // Collect known data points along the diagonal -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// int j = i + diag; -// if (j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { -// x.push_back(i); -// y.push_back(this->tableRow[i].tableEntry[j].targetPosition); -// indices.push_back(i); -// } -// } - -// // If we have enough points, perform cubic spline interpolation/extrapolation -// if (x.size() > 2) { -// tk::spline splineInterp; -// splineInterp.set_points(x, y, tk::spline::cspline); - -// // Extrapolate missing values -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// int j = i + diag; -// if (j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// double tempValue = splineInterp(i); - -// if (testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = static_cast(tempValue); -// } -// } -// } -// } -// } -// } - - -// double polynomialExtrapolation(const std::vector& x, const std::vector& y, double x_new, int order = 1) { -// if (x.size() != y.size() || x.size() < order + 1 || order < 0) { -// return std::numeric_limits::quiet_NaN(); // Return NaN for invalid input -// } - -// if (order == 1) { // Linear -// // Simple linear interpolation (same as before) -// return y[0] + (y[1] - y[0]) * (x_new - x[0]) / (x[1] - x[0]); //Assumes x values are in increasing order -// } else if (order == 2) { // Quadratic -// // Use Lagrange interpolation for quadratic -// if (x.size() < 3) return std::numeric_limits::quiet_NaN(); -// double y_new = 0.0; -// for (int i = 0; i < 3; ++i) { -// double term = y[i]; -// for (int j = 0; j < 3; ++j) { -// if (i != j) { -// term *= (x_new - x[j]) / (x[i] - x[j]); -// } -// } -// y_new += term; -// } -// return y_new; -// } else { -// return std::numeric_limits::quiet_NaN(); // Invalid order -// } -// } - -// void PowerTable::extrapolateDiagonal() { -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// double tempValue = INT16_MIN; - -// // Top-left to bottom-right extrapolation -// std::vector x, y; -// int row = i; -// int col = j; - -// //Find points along the diagonal -// for(int k = 0; k < 3 && row >= 0 && col >= 0 && row < POWERTABLE_CAD_SIZE && col < POWERTABLE_WATT_SIZE; k++){ -// if(this->tableRow[row].tableEntry[col].targetPosition != INT16_MIN){ -// x.push_back(col); -// y.push_back(this->tableRow[row].tableEntry[col].targetPosition); -// } -// row--; -// col--; -// } - -// if (x.size() >= 2) { //Need at least 2 points for linear, 3 for quadratic -// tempValue = polynomialExtrapolation(x, y, j, 2); // Use quadratic. Change to 1 for linear. -// if (!std::isnan(tempValue) && testNeighbors(i, j, static_cast(tempValue)).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = static_cast(tempValue); -// } -// } - - -// // Top-right to bottom-left extrapolation (if the first one failed) -// if (tempValue == INT16_MIN) { -// x.clear(); -// y.clear(); -// row = i; -// col = j; -// for(int k = 0; k < 3 && row >= 0 && col >= 0 && row < POWERTABLE_CAD_SIZE && col < POWERTABLE_WATT_SIZE; k++){ -// if(this->tableRow[row].tableEntry[col].targetPosition != INT16_MIN){ -// x.push_back(col); -// y.push_back(this->tableRow[row].tableEntry[col].targetPosition); -// } -// row--; -// col++; -// } -// if (x.size() >= 2) { //Need at least 2 points for linear, 3 for quadratic -// tempValue = polynomialExtrapolation(x, y, j, 2); // Use quadratic. Change to 1 for linear. -// if (!std::isnan(tempValue) && testNeighbors(i, j, static_cast(tempValue)).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = static_cast(tempValue); -// } -// } -// } -// } -// } -// } -// } int PowerTable::getNumEntries() { int ret = 0; for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { From f9441913d9c62ea67c8b71ceef9d86131cb1ebc8 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Thu, 27 Feb 2025 18:26:06 -0600 Subject: [PATCH 092/451] implemented extrap function, still could use some work. --- src/Power_Table.cpp | 564 +++++++++++++++++++++++++------------------- 1 file changed, 326 insertions(+), 238 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 53d58a9c..d208a5d7 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -447,263 +447,351 @@ void PowerTable::fillTable() { // } // } -void PowerTable::extrapFillTable() { - // Find the center of the known data - int sumRow = 0, sumCol = 0, count = 0; - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - sumRow += i; - sumCol += j; - count++; - } - } - } +// void PowerTable::extrapFillTable() { +// // Find the center of the known data +// int sumRow = 0, sumCol = 0, count = 0; +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { +// sumRow += i; +// sumCol += j; +// count++; +// } +// } +// } - // prevent divide by zero - if (count == 0) { - return; - } +// // prevent divide by zero +// if (count == 0) { +// return; +// } - int centerRow = sumRow / count; - int centerCol = sumCol / count; - int tempValue = INT16_MIN; - - // Function to extrapolate a single cell based on its neighbors - auto extrapolateCell = [&](int i, int j) { - // Find nearest left non-empty cell - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - - // Find nearest right non-empty cell - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear extrapolation - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - if (j < left) { - // Extrapolate to the left - tempValue = this->tableRow[i].tableEntry[left].targetPosition - - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } else if (j > right) { - // Extrapolate to the right - tempValue = this->tableRow[i].tableEntry[right].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// int centerRow = sumRow / count; +// int centerCol = sumCol / count; +// int tempValue = INT16_MIN; + +// // Function to extrapolate a single cell based on its neighbors +// auto extrapolateCell = [&](int i, int j) { +// // Find nearest left non-empty cell +// int left = j - 1; +// while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + +// // Find nearest right non-empty cell +// int right = j + 1; +// while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + +// if (left >= 0 && right < POWERTABLE_WATT_SIZE) { +// // Linear extrapolation +// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { +// if (j < left) { +// // Extrapolate to the left +// tempValue = this->tableRow[i].tableEntry[left].targetPosition - +// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } else if (j > right) { +// // Extrapolate to the right +// tempValue = this->tableRow[i].tableEntry[right].targetPosition + +// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } +// } else if (left - 1 >= 0) { +// // Only left value available, extrapolate to the right +// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { +// tempValue = this->tableRow[i].tableEntry[left].targetPosition + +// (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } else if (right + 1 < POWERTABLE_WATT_SIZE) { +// // Only right value available, extrapolate to the left +// if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { +// tempValue = +// this->tableRow[i].tableEntry[right].targetPosition - +// (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } +// }; + +// // Extrapolate horizontally and vertically starting from the center +// for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { +// for (int i = centerRow - distance; i <= centerRow + distance; ++i) { +// for (int j = centerCol - distance; j <= centerCol + distance; ++j) { +// if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// extrapolateCell(i, j); +// } +// } +// } +// } +// // Extrapolate each empty cell +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// // Extrapolate horizontally +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// // Find nearest left non-empty cell +// int left = j - 1; +// while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + +// // Find nearest right non-empty cell +// int right = j + 1; +// while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; +// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { +// if (left >= 0 && right < POWERTABLE_WATT_SIZE) { +// // Linear extrapolation +// if (j < left) { +// // Extrapolate to the left +// tempValue = this->tableRow[i].tableEntry[left].targetPosition - +// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } + +// } else if (j > right) { +// // Extrapolate to the right +// tempValue = this->tableRow[i].tableEntry[right].targetPosition + +// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } else if (left >= 1) { +// // Only left value available, extrapolate to the right +// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { +// tempValue = this->tableRow[i].tableEntry[left].targetPosition + +// (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } else if (right + 1 < POWERTABLE_WATT_SIZE) { +// // Only right value available, extrapolate to the left +// if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { +// tempValue = this->tableRow[i].tableEntry[right].targetPosition - +// (right - j) * +// (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } +// } +// } +// } +// } + +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// // Extrapolate vertically +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// // Find nearest top non-empty cell +// int top = i - 1; +// while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; + +// // Find nearest bottom non-empty cell +// int bottom = i + 1; +// while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; + +// if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { +// // Linear extrapolation +// if (i < top) { +// // Extrapolate upwards +// tempValue = this->tableRow[top].tableEntry[j].targetPosition - +// (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } else if (i > bottom) { +// // Extrapolate downwards +// tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + +// (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } else if (top >= 1) { +// // Only top value available, extrapolate downwards +// if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { +// tempValue = this->tableRow[top].tableEntry[j].targetPosition + +// (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } else { +// } +// } +// } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { +// // Only bottom value available, extrapolate upwards +// if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { +// tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - +// (bottom - i) * +// (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } +// } +// } +// } +// } + +// void PowerTable::extrapolateDiagonal() { +// int tempValue = INT16_MIN; + +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// // Find nearest top-left non-empty cell +// int topLeftRow = i - 1, topLeftCol = j - 1; +// while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { +// topLeftRow--; +// topLeftCol--; +// } + +// // Find nearest bottom-right non-empty cell +// int bottomRightRow = i + 1, bottomRightCol = j + 1; +// while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && +// this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { +// bottomRightRow++; +// bottomRightCol++; +// } + +// // Perform diagonal extrapolation (top-left to bottom-right) +// if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { +// tempValue = +// this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + +// ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / +// (bottomRightCol - topLeftCol); + +// if (testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } + +// // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left +// if (tempValue == INT16_MIN) { +// // Find nearest top-right non-empty cell +// int topRightRow = i - 1, topRightCol = j + 1; +// while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { +// topRightRow--; +// topRightCol++; +// } + +// // Find nearest bottom-left non-empty cell +// int bottomLeftRow = i + 1, bottomLeftCol = j - 1; +// while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { +// bottomLeftRow++; +// bottomLeftCol--; +// } + +// // Perform diagonal extrapolation (top-right to bottom-left) +// if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { +// tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + +// ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * +// (j - bottomLeftCol)) / +// (topRightCol - bottomLeftCol); + +// if (testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } +// } +// } +// } +// } + +void PowerTable::extrapFillTable() { + + // Horizontal Extrapolation + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + std::vector x, y; + + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + x.push_back(j); + y.push_back(this->tableRow[i].tableEntry[j].targetPosition); } - } - } - } else if (left - 1 >= 0) { - // Only left value available, extrapolate to the right - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (right + 1 < POWERTABLE_WATT_SIZE) { - // Only right value available, extrapolate to the left - if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - tempValue = - this->tableRow[i].tableEntry[right].targetPosition - - (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } } - } - }; - - // Extrapolate horizontally and vertically starting from the center - for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { - for (int i = centerRow - distance; i <= centerRow + distance; ++i) { - for (int j = centerCol - distance; j <= centerCol + distance; ++j) { - if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - extrapolateCell(i, j); - } - } - } - } - // Extrapolate each empty cell - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - // Extrapolate horizontally - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest left non-empty cell - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - - // Find nearest right non-empty cell - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear extrapolation - if (j < left) { - // Extrapolate to the left - tempValue = this->tableRow[i].tableEntry[left].targetPosition - - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - - } else if (j > right) { - // Extrapolate to the right - tempValue = this->tableRow[i].tableEntry[right].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (left >= 1) { - // Only left value available, extrapolate to the right - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (right + 1 < POWERTABLE_WATT_SIZE) { - // Only right value available, extrapolate to the left - if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[right].targetPosition - - (right - j) * - (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + + if (x.size() > 2) { // Need 3 points + tk::spline s; + s.set_points(x, y, tk::spline::cspline); // Set points checks if its within range to extrapolate + + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + int tempValue = static_cast(std::round(s(j))); // Round to make more accurate + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } } - } } - } } - } } - + + // Vertical Extrapolation for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - // Extrapolate vertically - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top non-empty cell - int top = i - 1; - while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; - - // Find nearest bottom non-empty cell - int bottom = i + 1; - while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; - - if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { - // Linear extrapolation - if (i < top) { - // Extrapolate upwards - tempValue = this->tableRow[top].tableEntry[j].targetPosition - - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } else if (i > bottom) { - // Extrapolate downwards - tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (top >= 1) { - // Only top value available, extrapolate downwards - if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { - tempValue = this->tableRow[top].tableEntry[j].targetPosition + - (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } else { - } + std::vector x, y; + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + x.push_back(i); + y.push_back(this->tableRow[i].tableEntry[j].targetPosition); } - } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { - // Only bottom value available, extrapolate upwards - if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { - tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - - (bottom - i) * - (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + } + + if (x.size() > 2) { + tk::spline s; + s.set_points(x, y, tk::spline::cspline); + + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + int tempValue = static_cast(std::round(s(i))); // Round to make more accurate + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } } - } } - } } } void PowerTable::extrapolateDiagonal() { - int tempValue = INT16_MIN; - - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top-left non-empty cell - int topLeftRow = i - 1, topLeftCol = j - 1; - while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { - topLeftRow--; - topLeftCol--; - } - - // Find nearest bottom-right non-empty cell - int bottomRightRow = i + 1, bottomRightCol = j + 1; - while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && - this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { - bottomRightRow++; - bottomRightCol++; - } - - // Perform diagonal extrapolation (top-left to bottom-right) - if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { - tempValue = - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + - ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / - (bottomRightCol - topLeftCol); - - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - - // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left - if (tempValue == INT16_MIN) { - // Find nearest top-right non-empty cell - int topRightRow = i - 1, topRightCol = j + 1; - while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { - topRightRow--; - topRightCol++; - } - - // Find nearest bottom-left non-empty cell - int bottomLeftRow = i + 1, bottomLeftCol = j - 1; - while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { - bottomLeftRow++; - bottomLeftCol--; + for (int diag = -POWERTABLE_CAD_SIZE + 1; diag < POWERTABLE_WATT_SIZE; ++diag) { + std::vector x, y; + std::vector emptyIndices; + + // get Data + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + int j = i + diag; + if (j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + x.push_back(i); + y.push_back(this->tableRow[i].tableEntry[j].targetPosition); + emptyIndices.push_back(i); } - - // Perform diagonal extrapolation (top-right to bottom-left) - if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { - tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + - ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * - (j - bottomLeftCol)) / - (topRightCol - bottomLeftCol); - - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + } + + if (x.size() > 2) { // 3 points needed + tk::spline s; + s.set_points(x, y, tk::spline::cspline); + + // Extrapolate + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + int j = i + diag; + if (j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + int tempValue = static_cast(std::round(s(i))); // Round to make more accurate + + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } } - } } - } } } From cc3d6b85241eda54349cc6fe6760fea8da696c42 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Thu, 27 Feb 2025 21:38:06 -0600 Subject: [PATCH 093/451] implemented cubic spline for lookUp, needs to be tested --- include/Power_Table.h | 3 ++ src/ERG_Mode.cpp | 2 +- src/Power_Table.cpp | 73 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/include/Power_Table.h b/include/Power_Table.h index 12c0361d..f96f6dc9 100644 --- a/include/Power_Table.h +++ b/include/Power_Table.h @@ -110,6 +110,9 @@ class PowerTable { // returns incline for wattTarget. Null if not found. int32_t lookup(int watts, int cad); + // returns + int32_t splineLookup(int watts, int cad); + // returns watts for given cadence and target position. Returns RETURN_ERROR if not found. int32_t lookupWatts(int cad, int32_t targetPosition); diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 0eb026d6..bb8cb7be 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -181,7 +181,7 @@ void ErgMode::computeErg() { } void ErgMode::_setPointChangeState(int newCadence, Measurement& newWatts) { - int32_t tableResult = powerTable->lookup(newWatts.getTarget(), newCadence); + int32_t tableResult = powerTable->splineLookup(newWatts.getTarget(), newCadence); // Sanity check for targets if (tableResult != RETURN_ERROR) { diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index b76b24e2..5395aee0 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -345,6 +345,79 @@ TestResults PowerTable::testNeighbors(int i, int j, int testValue) { return returnResult; } +int32_t PowerTable::splineLookup(int watts, int cad) { + int cadIndex = round(((float)cad - (float)MINIMUM_TABLE_CAD) / (float)POWERTABLE_CAD_INCREMENT); + int wattIndex = round((float)watts / (float)POWERTABLE_WATT_INCREMENT); + + std::vector cadValues; + std::vector targetPositionsCad; + + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[wattIndex].targetPosition != INT16_MIN) { + cadValues.push_back(i * POWERTABLE_CAD_INCREMENT + MINIMUM_TABLE_CAD); + targetPositionsCad.push_back(this->tableRow[i].tableEntry[wattIndex].targetPosition); + } + } + + if (cadValues.size() > 2) { // Need at least 3 points for cubic spline + tk::spline splineCad(cadValues, targetPositionsCad); + double interpolatedCad = splineCad(cad); + SS2K_LOG(POWERTABLE_LOG_TAG, "Spline Cadence Interpolated: %f", interpolatedCad); + if(interpolatedCad != interpolatedCad){ + interpolatedCad = INT16_MIN; + } + + std::vector wattValues; + std::vector targetPositionsWatt; + + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[cadIndex].tableEntry[j].targetPosition != INT16_MIN) { + wattValues.push_back(j * POWERTABLE_WATT_INCREMENT); + targetPositionsWatt.push_back(this->tableRow[cadIndex].tableEntry[j].targetPosition); + } + } + + if (wattValues.size() > 2) { + tk::spline splineWatt(wattValues, targetPositionsWatt); + double interpolatedWatt = splineWatt(watts); + SS2K_LOG(POWERTABLE_LOG_TAG, "Spline Wattage Interpolated: %f", interpolatedWatt); + if(interpolatedWatt != interpolatedWatt){ + interpolatedWatt = INT16_MIN; + } + + double sum = 0; + int count = 0; + + if (interpolatedCad != INT16_MIN) { + sum += interpolatedCad; + count++; + } + if (interpolatedWatt != INT16_MIN) { + sum += interpolatedWatt; + count++; + } + if (this->tableRow[cadIndex].tableEntry[wattIndex].targetPosition != INT16_MIN) { + sum += this->tableRow[cadIndex].tableEntry[wattIndex].targetPosition; + count++; + } + + if (count > 0) { + int32_t ret = (int32_t)(sum / count) * TABLE_DIVISOR; + SS2K_LOG(POWERTABLE_LOG_TAG, "Spline Lookup result: %dw %dcad %d", watts, cad, ret); + return ret; + } else { + return INT32_MIN; + } + } else { + // Not enough wattage data for spline interpolation + return lookup(watts,cad); + } + } else { + // Not enough cadence data for spline interpolation + return lookup(watts,cad); + } +} + void PowerTable::fillTable() { // Horizontal Interpolation for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { From 6ad9474f17db1cec0def0959ee36e9fd32b3da10 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Sun, 2 Mar 2025 23:18:45 -0600 Subject: [PATCH 094/451] fixed fillTable() bug, reverted back to old extrap functions. --- .vscode/settings.json | 3 +- src/Power_Table.cpp | 660 +++++++++++++++++++----------------------- 2 files changed, 304 insertions(+), 359 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index bb2e7a41..13746c13 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -59,7 +59,8 @@ "set": "cpp", "iostream": "cpp", "*.dontuse": "cpp", - "core": "cpp" + "core": "cpp", + "complex": "cpp" }, "cSpell.words": [ "Appender", diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index d208a5d7..532a8068 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -16,6 +16,8 @@ #include #include #include +#include +#include void PowerBuffer::set(int i) { this->powerEntry[i].readings++; @@ -340,64 +342,94 @@ TestResults PowerTable::testNeighbors(int i, int j, int testValue) { } void PowerTable::fillTable() { - // Horizontal Interpolation + // Horizontal Interpolation for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { std::vector x, y; std::vector emptyIndices; - // Collect existing data points and empty indices + // Collect data points for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - x.push_back(j); - y.push_back(this->tableRow[i].tableEntry[j].targetPosition); + x.push_back(static_cast(j)); + y.push_back(static_cast(this->tableRow[i].tableEntry[j].targetPosition)); } else { emptyIndices.push_back(j); } } - if (x.size() > 2) { // Need 3 points - tk::spline s(x, y); + if (x.size() < 2) continue; // We skip if there are fewer than two unique points - // Interpolate and fill empty cells - for (int j : emptyIndices) { - int tempValue = static_cast(std::round(s(j))); // Round to make more accurete - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } + std::map unique_xy; + for (size_t k = 0; k < x.size(); ++k) { + unique_xy[x[k]] = y[k]; // Get rid of duplicates so we only have unique points } - } - // Vertical Interpolation - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - std::vector x, y; - std::vector emptyIndices; + // Clear x and y so we can put ONLY the unique points in + x.clear(); + y.clear(); - // Collect existing data points and empty indices - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - x.push_back(i); - y.push_back(this->tableRow[i].tableEntry[j].targetPosition); - } else { - emptyIndices.push_back(i); - } + for (const auto& it : unique_xy) { // We put the unique points back into x and y + x.push_back(it.first); + y.push_back(it.second); } - if (x.size() > 2) { // Need 3 points - tk::spline s(x, y); + tk::spline s; // Initialize s for using in cubic spline + + if (x.size() == 1) { + // If we only have one unique point, we fill the row with that value. Good for keeping data + double singleValue = y.front(); + for (int j : emptyIndices) { + this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); + } + continue; + } else if (x.size() == 2) { + // If only 2 unique points, we perform linear interpolation + for (int j : emptyIndices) { + if (j < x.front() || j > x.back()) continue; // So we avoid extrapolation + double x0 = x[0]; + double y0 = y[0]; + double x1 = x[1]; + double y1 = y[1]; + + double interpolated_value = y0 + (y1 - y0) * (j - x0) / (x1 - x0); + + // Might use clamp in the future, but we are not at the right c++ version. + + interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + + int tempValue = static_cast(std::round(interpolated_value)); - // Interpolate and fill empty cells - for (int i : emptyIndices) { - int tempValue = static_cast(std::round(s(i))); // Round to make more accurate if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } + continue; + } else if (x.size() >= 3) { + // If we have 3 unique points, then we can perform cubic sline + s.set_points(x, y, tk::spline::cspline); + } else { + //Sanity check just so we don't crash when we don't have a unique point, won't happen. + SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); + continue; } + + // Continue with the interpolation. + for (int j : emptyIndices) { + if (j < x.front() || j > x.back()) continue; // So we avoid extrapolation + double interpolated_value = s(j); + interpolated_value = std::max(*std::min_element(y.begin(), y.end()), + std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + + int tempValue = static_cast(std::round(interpolated_value)); + + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } } } -// Old Fill Function +//Old Fill Function // void PowerTable::fillTable() { // int tempValue = INT16_MIN; @@ -447,351 +479,263 @@ void PowerTable::fillTable() { // } // } -// void PowerTable::extrapFillTable() { -// // Find the center of the known data -// int sumRow = 0, sumCol = 0, count = 0; -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { -// sumRow += i; -// sumCol += j; -// count++; -// } -// } -// } - -// // prevent divide by zero -// if (count == 0) { -// return; -// } - -// int centerRow = sumRow / count; -// int centerCol = sumCol / count; -// int tempValue = INT16_MIN; - -// // Function to extrapolate a single cell based on its neighbors -// auto extrapolateCell = [&](int i, int j) { -// // Find nearest left non-empty cell -// int left = j - 1; -// while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - -// // Find nearest right non-empty cell -// int right = j + 1; -// while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - -// if (left >= 0 && right < POWERTABLE_WATT_SIZE) { -// // Linear extrapolation -// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { -// if (j < left) { -// // Extrapolate to the left -// tempValue = this->tableRow[i].tableEntry[left].targetPosition - -// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } else if (j > right) { -// // Extrapolate to the right -// tempValue = this->tableRow[i].tableEntry[right].targetPosition + -// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// } else if (left - 1 >= 0) { -// // Only left value available, extrapolate to the right -// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { -// tempValue = this->tableRow[i].tableEntry[left].targetPosition + -// (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } else if (right + 1 < POWERTABLE_WATT_SIZE) { -// // Only right value available, extrapolate to the left -// if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { -// tempValue = -// this->tableRow[i].tableEntry[right].targetPosition - -// (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// }; - -// // Extrapolate horizontally and vertically starting from the center -// for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { -// for (int i = centerRow - distance; i <= centerRow + distance; ++i) { -// for (int j = centerCol - distance; j <= centerCol + distance; ++j) { -// if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// extrapolateCell(i, j); -// } -// } -// } -// } -// // Extrapolate each empty cell -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// // Extrapolate horizontally -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// // Find nearest left non-empty cell -// int left = j - 1; -// while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - -// // Find nearest right non-empty cell -// int right = j + 1; -// while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; -// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { -// if (left >= 0 && right < POWERTABLE_WATT_SIZE) { -// // Linear extrapolation -// if (j < left) { -// // Extrapolate to the left -// tempValue = this->tableRow[i].tableEntry[left].targetPosition - -// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } - -// } else if (j > right) { -// // Extrapolate to the right -// tempValue = this->tableRow[i].tableEntry[right].targetPosition + -// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } else if (left >= 1) { -// // Only left value available, extrapolate to the right -// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { -// tempValue = this->tableRow[i].tableEntry[left].targetPosition + -// (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } else if (right + 1 < POWERTABLE_WATT_SIZE) { -// // Only right value available, extrapolate to the left -// if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { -// tempValue = this->tableRow[i].tableEntry[right].targetPosition - -// (right - j) * -// (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// } -// } -// } -// } - -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// // Extrapolate vertically -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// // Find nearest top non-empty cell -// int top = i - 1; -// while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; - -// // Find nearest bottom non-empty cell -// int bottom = i + 1; -// while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; - -// if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { -// // Linear extrapolation -// if (i < top) { -// // Extrapolate upwards -// tempValue = this->tableRow[top].tableEntry[j].targetPosition - -// (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } else if (i > bottom) { -// // Extrapolate downwards -// tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + -// (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } else if (top >= 1) { -// // Only top value available, extrapolate downwards -// if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { -// tempValue = this->tableRow[top].tableEntry[j].targetPosition + -// (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } else { -// } -// } -// } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { -// // Only bottom value available, extrapolate upwards -// if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { -// tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - -// (bottom - i) * -// (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// } -// } -// } -// } - -// void PowerTable::extrapolateDiagonal() { -// int tempValue = INT16_MIN; - -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// // Find nearest top-left non-empty cell -// int topLeftRow = i - 1, topLeftCol = j - 1; -// while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { -// topLeftRow--; -// topLeftCol--; -// } - -// // Find nearest bottom-right non-empty cell -// int bottomRightRow = i + 1, bottomRightCol = j + 1; -// while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && -// this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { -// bottomRightRow++; -// bottomRightCol++; -// } - -// // Perform diagonal extrapolation (top-left to bottom-right) -// if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { -// tempValue = -// this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + -// ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / -// (bottomRightCol - topLeftCol); - -// if (testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } - -// // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left -// if (tempValue == INT16_MIN) { -// // Find nearest top-right non-empty cell -// int topRightRow = i - 1, topRightCol = j + 1; -// while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { -// topRightRow--; -// topRightCol++; -// } - -// // Find nearest bottom-left non-empty cell -// int bottomLeftRow = i + 1, bottomLeftCol = j - 1; -// while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { -// bottomLeftRow++; -// bottomLeftCol--; -// } - -// // Perform diagonal extrapolation (top-right to bottom-left) -// if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { -// tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + -// ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * -// (j - bottomLeftCol)) / -// (topRightCol - bottomLeftCol); - -// if (testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// } -// } -// } -// } - void PowerTable::extrapFillTable() { - - // Horizontal Extrapolation + // Find the center of the known data + int sumRow = 0, sumCol = 0, count = 0; for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - std::vector x, y; - - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - x.push_back(j); - y.push_back(this->tableRow[i].tableEntry[j].targetPosition); + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + sumRow += i; + sumCol += j; + count++; + } + } + } + + // prevent divide by zero + if (count == 0) { + return; + } + + int centerRow = sumRow / count; + int centerCol = sumCol / count; + int tempValue = INT16_MIN; + + // Function to extrapolate a single cell based on its neighbors + auto extrapolateCell = [&](int i, int j) { + // Find nearest left non-empty cell + int left = j - 1; + while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + + // Find nearest right non-empty cell + int right = j + 1; + while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + + if (left >= 0 && right < POWERTABLE_WATT_SIZE) { + // Linear extrapolation + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + if (j < left) { + // Extrapolate to the left + tempValue = this->tableRow[i].tableEntry[left].targetPosition - + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } + } else if (j > right) { + // Extrapolate to the right + tempValue = this->tableRow[i].tableEntry[right].targetPosition + + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } } - - if (x.size() > 2) { // Need 3 points - tk::spline s; - s.set_points(x, y, tk::spline::cspline); // Set points checks if its within range to extrapolate - - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - int tempValue = static_cast(std::round(s(j))); // Round to make more accurate - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + } else if (left - 1 >= 0) { + // Only left value available, extrapolate to the right + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { + tempValue = this->tableRow[i].tableEntry[left].targetPosition + + (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (right + 1 < POWERTABLE_WATT_SIZE) { + // Only right value available, extrapolate to the left + if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + tempValue = + this->tableRow[i].tableEntry[right].targetPosition - + (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + }; + + // Extrapolate horizontally and vertically starting from the center + for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { + for (int i = centerRow - distance; i <= centerRow + distance; ++i) { + for (int j = centerCol - distance; j <= centerCol + distance; ++j) { + if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + extrapolateCell(i, j); + } + } + } + } + // Extrapolate each empty cell + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + // Extrapolate horizontally + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest left non-empty cell + int left = j - 1; + while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + + // Find nearest right non-empty cell + int right = j + 1; + while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + if (left >= 0 && right < POWERTABLE_WATT_SIZE) { + // Linear extrapolation + if (j < left) { + // Extrapolate to the left + tempValue = this->tableRow[i].tableEntry[left].targetPosition - + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + + } else if (j > right) { + // Extrapolate to the right + tempValue = this->tableRow[i].tableEntry[right].targetPosition + + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (left >= 1) { + // Only left value available, extrapolate to the right + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { + tempValue = this->tableRow[i].tableEntry[left].targetPosition + + (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } + } + } else if (right + 1 < POWERTABLE_WATT_SIZE) { + // Only right value available, extrapolate to the left + if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { + tempValue = this->tableRow[i].tableEntry[right].targetPosition - + (right - j) * + (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } } + } } + } } - - // Vertical Extrapolation + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - std::vector x, y; - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - x.push_back(i); - y.push_back(this->tableRow[i].tableEntry[j].targetPosition); + // Extrapolate vertically + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest top non-empty cell + int top = i - 1; + while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; + + // Find nearest bottom non-empty cell + int bottom = i + 1; + while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; + + if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { + // Linear extrapolation + if (i < top) { + // Extrapolate upwards + tempValue = this->tableRow[top].tableEntry[j].targetPosition - + (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } else if (i > bottom) { + // Extrapolate downwards + tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + + (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } } - } - - if (x.size() > 2) { - tk::spline s; - s.set_points(x, y, tk::spline::cspline); - - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - int tempValue = static_cast(std::round(s(i))); // Round to make more accurate - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } + } else if (top >= 1) { + // Only top value available, extrapolate downwards + if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { + tempValue = this->tableRow[top].tableEntry[j].targetPosition + + (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } else { + } + } + } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { + // Only bottom value available, extrapolate upwards + if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { + tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - + (bottom - i) * + (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } } + } } + } } } void PowerTable::extrapolateDiagonal() { - for (int diag = -POWERTABLE_CAD_SIZE + 1; diag < POWERTABLE_WATT_SIZE; ++diag) { - std::vector x, y; - std::vector emptyIndices; - - // get Data - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - int j = i + diag; - if (j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - x.push_back(i); - y.push_back(this->tableRow[i].tableEntry[j].targetPosition); - emptyIndices.push_back(i); + int tempValue = INT16_MIN; + + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest top-left non-empty cell + int topLeftRow = i - 1, topLeftCol = j - 1; + while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { + topLeftRow--; + topLeftCol--; + } + + // Find nearest bottom-right non-empty cell + int bottomRightRow = i + 1, bottomRightCol = j + 1; + while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && + this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { + bottomRightRow++; + bottomRightCol++; + } + + // Perform diagonal extrapolation (top-left to bottom-right) + if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { + tempValue = + this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + + ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / + (bottomRightCol - topLeftCol); + + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } - } - - if (x.size() > 2) { // 3 points needed - tk::spline s; - s.set_points(x, y, tk::spline::cspline); - - // Extrapolate - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - int j = i + diag; - if (j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - int tempValue = static_cast(std::round(s(i))); // Round to make more accurate - - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } + } + + // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left + if (tempValue == INT16_MIN) { + // Find nearest top-right non-empty cell + int topRightRow = i - 1, topRightCol = j + 1; + while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { + topRightRow--; + topRightCol++; + } + + // Find nearest bottom-left non-empty cell + int bottomLeftRow = i + 1, bottomLeftCol = j - 1; + while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { + bottomLeftRow++; + bottomLeftCol--; } + + // Perform diagonal extrapolation (top-right to bottom-left) + if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { + tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + + ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * + (j - bottomLeftCol)) / + (topRightCol - bottomLeftCol); + + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } } + } } } From ea901413c73c9b2b9bdab39435c21b84bc723ed0 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Sun, 2 Mar 2025 23:23:50 -0600 Subject: [PATCH 095/451] added extrap functions, need to debug them --- src/Power_Table.cpp | 288 ++++++++++++++++++++++++++------------------ 1 file changed, 172 insertions(+), 116 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 5395aee0..30e630b6 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -17,6 +17,7 @@ #include #include #include +#include void PowerBuffer::set(int i) { this->powerEntry[i].readings++; @@ -345,79 +346,6 @@ TestResults PowerTable::testNeighbors(int i, int j, int testValue) { return returnResult; } -int32_t PowerTable::splineLookup(int watts, int cad) { - int cadIndex = round(((float)cad - (float)MINIMUM_TABLE_CAD) / (float)POWERTABLE_CAD_INCREMENT); - int wattIndex = round((float)watts / (float)POWERTABLE_WATT_INCREMENT); - - std::vector cadValues; - std::vector targetPositionsCad; - - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[wattIndex].targetPosition != INT16_MIN) { - cadValues.push_back(i * POWERTABLE_CAD_INCREMENT + MINIMUM_TABLE_CAD); - targetPositionsCad.push_back(this->tableRow[i].tableEntry[wattIndex].targetPosition); - } - } - - if (cadValues.size() > 2) { // Need at least 3 points for cubic spline - tk::spline splineCad(cadValues, targetPositionsCad); - double interpolatedCad = splineCad(cad); - SS2K_LOG(POWERTABLE_LOG_TAG, "Spline Cadence Interpolated: %f", interpolatedCad); - if(interpolatedCad != interpolatedCad){ - interpolatedCad = INT16_MIN; - } - - std::vector wattValues; - std::vector targetPositionsWatt; - - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[cadIndex].tableEntry[j].targetPosition != INT16_MIN) { - wattValues.push_back(j * POWERTABLE_WATT_INCREMENT); - targetPositionsWatt.push_back(this->tableRow[cadIndex].tableEntry[j].targetPosition); - } - } - - if (wattValues.size() > 2) { - tk::spline splineWatt(wattValues, targetPositionsWatt); - double interpolatedWatt = splineWatt(watts); - SS2K_LOG(POWERTABLE_LOG_TAG, "Spline Wattage Interpolated: %f", interpolatedWatt); - if(interpolatedWatt != interpolatedWatt){ - interpolatedWatt = INT16_MIN; - } - - double sum = 0; - int count = 0; - - if (interpolatedCad != INT16_MIN) { - sum += interpolatedCad; - count++; - } - if (interpolatedWatt != INT16_MIN) { - sum += interpolatedWatt; - count++; - } - if (this->tableRow[cadIndex].tableEntry[wattIndex].targetPosition != INT16_MIN) { - sum += this->tableRow[cadIndex].tableEntry[wattIndex].targetPosition; - count++; - } - - if (count > 0) { - int32_t ret = (int32_t)(sum / count) * TABLE_DIVISOR; - SS2K_LOG(POWERTABLE_LOG_TAG, "Spline Lookup result: %dw %dcad %d", watts, cad, ret); - return ret; - } else { - return INT32_MIN; - } - } else { - // Not enough wattage data for spline interpolation - return lookup(watts,cad); - } - } else { - // Not enough cadence data for spline interpolation - return lookup(watts,cad); - } -} - void PowerTable::fillTable() { // Horizontal Interpolation for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { @@ -477,25 +405,63 @@ void PowerTable::fillTable() { } void PowerTable::extrapFillTable() { - - // Horizontal Extrapolation + // Horizontal extrapolation for each row for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - std::vector x, y; - + std::map unique_xy; + + // Gather known data points in row i for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - x.push_back(j); - y.push_back(this->tableRow[i].tableEntry[j].targetPosition); + unique_xy[j] = this->tableRow[i].tableEntry[j].targetPosition; } } - - if (x.size() > 2) { // Need 3 points + + if (unique_xy.size() < 2) continue; // Skip if not enough data + + std::vector x, y; + for (std::map::iterator it = unique_xy.begin(); it != unique_xy.end(); ++it) { + x.push_back(it->first); + y.push_back(it->second); + } + + if (x.size() == 2) { + // Use linear extrapolation for two points + double slope = (y[1] - y[0]) / (x[1] - x[0]); + double intercept = y[0] - slope * x[0]; + + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + double extrapolatedValue = slope * j + intercept; + + // Clamp manually (since std::clamp isn't available in C++14) + double minVal = *std::min_element(y.begin(), y.end()); + double maxVal = *std::max_element(y.begin(), y.end()); + extrapolatedValue = std::max(minVal, std::min(maxVal, extrapolatedValue)); + + int tempValue = static_cast(std::round(extrapolatedValue)); + + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } + else if (x.size() >= 3) { + // Use cubic spline extrapolation for 3+ points tk::spline s; - s.set_points(x, y, tk::spline::cspline); // Set points checks if its within range to extrapolate - + s.set_points(x, y, tk::spline::cspline); + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - int tempValue = static_cast(std::round(s(j))); // Round to make more accurate + double extrapolatedValue = s(j); + + // Clamp manually + double minVal = *std::min_element(y.begin(), y.end()); + double maxVal = *std::max_element(y.begin(), y.end()); + extrapolatedValue = std::max(minVal, std::min(maxVal, extrapolatedValue)); + + int tempValue = static_cast(std::round(extrapolatedValue)); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } @@ -503,24 +469,64 @@ void PowerTable::extrapFillTable() { } } } - - // Vertical Extrapolation + + // Vertical extrapolation for each column for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - std::vector x, y; + std::map unique_xy; + + // Gather known data points in column j for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - x.push_back(i); - y.push_back(this->tableRow[i].tableEntry[j].targetPosition); + unique_xy[i] = this->tableRow[i].tableEntry[j].targetPosition; } } - - if (x.size() > 2) { + + if (unique_xy.size() < 2) continue; // Skip if not enough data + + std::vector x, y; + for (std::map::iterator it = unique_xy.begin(); it != unique_xy.end(); ++it) { + x.push_back(it->first); + y.push_back(it->second); + } + + if (x.size() == 2) { + // Use linear extrapolation for two points + double slope = (y[1] - y[0]) / (x[1] - x[0]); + double intercept = y[0] - slope * x[0]; + + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + double extrapolatedValue = slope * i + intercept; + + // Clamp manually + double minVal = *std::min_element(y.begin(), y.end()); + double maxVal = *std::max_element(y.begin(), y.end()); + extrapolatedValue = std::max(minVal, std::min(maxVal, extrapolatedValue)); + + int tempValue = static_cast(std::round(extrapolatedValue)); + + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } + else if (x.size() >= 3) { + // Use cubic spline extrapolation for 3+ points tk::spline s; s.set_points(x, y, tk::spline::cspline); - + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - int tempValue = static_cast(std::round(s(i))); // Round to make more accurate + double extrapolatedValue = s(i); + + // Clamp manually + double minVal = *std::min_element(y.begin(), y.end()); + double maxVal = *std::max_element(y.begin(), y.end()); + extrapolatedValue = std::max(minVal, std::min(maxVal, extrapolatedValue)); + + int tempValue = static_cast(std::round(extrapolatedValue)); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } @@ -530,40 +536,90 @@ void PowerTable::extrapFillTable() { } } + void PowerTable::extrapolateDiagonal() { - for (int diag = -POWERTABLE_CAD_SIZE + 1; diag < POWERTABLE_WATT_SIZE; ++diag) { - std::vector x, y; - std::vector emptyIndices; - - // get Data + for (int d = 1 - POWERTABLE_WATT_SIZE; d < POWERTABLE_CAD_SIZE; ++d) { + std::map knownPoints; + std::vector> emptyIndices; + + // Collect known values for this diagonal for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - int j = i + diag; - if (j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - x.push_back(i); - y.push_back(this->tableRow[i].tableEntry[j].targetPosition); - emptyIndices.push_back(i); + int j = i - d; + if (j >= 0 && j < POWERTABLE_WATT_SIZE) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + knownPoints[i] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); + } else { + emptyIndices.emplace_back(i, j); + } } } - - if (x.size() > 2) { // 3 points needed + + if (knownPoints.size() < 2) continue; // Skip if not enough data + + // Extract x and y values from map (already sorted and unique) + std::vector x, y; + for (const auto& pair : knownPoints) { + x.push_back(pair.first); + y.push_back(pair.second); + } + + // If only 1 unique value, fill all missing positions with it + if (x.size() == 1) { + int constantValue = static_cast(std::round(y.front())); + for (const auto& index : emptyIndices) { + this->tableRow[index.first].tableEntry[index.second].targetPosition = constantValue; + } + continue; + } + + // Handle linear interpolation for exactly two points + if (x.size() == 2) { + double slope = (y[1] - y[0]) / (x[1] - x[0]); + double intercept = y[0] - slope * x[0]; + + for (const auto& index : emptyIndices) { + int i = index.first; + int j = index.second; + + double interpolatedValue = slope * i + intercept; + int roundedValue = static_cast(std::round(interpolatedValue)); + + if (testNeighbors(i, j, roundedValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = roundedValue; + } + } + continue; // Avoid calling cubic spline with 2 points + } + + // If there are at least 3 points, use cubic spline + if (x.size() >= 3) { tk::spline s; - s.set_points(x, y, tk::spline::cspline); - - // Extrapolate - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - int j = i + diag; - if (j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - int tempValue = static_cast(std::round(s(i))); // Round to make more accurate - - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + s.set_points(x, y, tk::spline::cspline); // Use cubic spline + + for (const auto& index : emptyIndices) { + int i = index.first; + int j = index.second; + + if (i < 0 || i >= POWERTABLE_CAD_SIZE || j < 0 || j >= POWERTABLE_WATT_SIZE) continue; + + double interpolatedValue = s(static_cast(i)); + + // Compute min/max for clamping + double minVal = *std::min_element(y.begin(), y.end()); + double maxVal = *std::max_element(y.begin(), y.end()); + double range = maxVal - minVal; + interpolatedValue = std::max(minVal - 0.1 * range, std::min(interpolatedValue, maxVal + 0.1 * range)); + + int roundedValue = static_cast(std::round(interpolatedValue)); + if (testNeighbors(i, j, roundedValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = roundedValue; } } } } } + int PowerTable::getNumEntries() { int ret = 0; for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { From bf1997ecfdd2fb7fafb7465729377bf2bb58e599 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Sun, 2 Mar 2025 23:26:55 -0600 Subject: [PATCH 096/451] implemented new fillTable() function. --- .vscode/settings.json | 3 +- src/Power_Table.cpp | 95 ++++++++++++++++++++++++++++--------------- 2 files changed, 65 insertions(+), 33 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index bb2e7a41..13746c13 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -59,7 +59,8 @@ "set": "cpp", "iostream": "cpp", "*.dontuse": "cpp", - "core": "cpp" + "core": "cpp", + "complex": "cpp" }, "cSpell.words": [ "Appender", diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 30e630b6..3e0a9ba0 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -18,6 +18,7 @@ #include #include #include +#include void PowerBuffer::set(int i) { this->powerEntry[i].readings++; @@ -347,60 +348,90 @@ TestResults PowerTable::testNeighbors(int i, int j, int testValue) { } void PowerTable::fillTable() { - // Horizontal Interpolation + // Horizontal Interpolation for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { std::vector x, y; std::vector emptyIndices; - // Collect existing data points and empty indices + // Collect data points for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - x.push_back(j); - y.push_back(this->tableRow[i].tableEntry[j].targetPosition); + x.push_back(static_cast(j)); + y.push_back(static_cast(this->tableRow[i].tableEntry[j].targetPosition)); } else { emptyIndices.push_back(j); } } - if (x.size() > 2) { // Need 3 points - tk::spline s(x, y); + if (x.size() < 2) continue; // We skip if there are fewer than two unique points - // Interpolate and fill empty cells - for (int j : emptyIndices) { - int tempValue = static_cast(std::round(s(j))); // Round to make more accurete - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } + std::map unique_xy; + for (size_t k = 0; k < x.size(); ++k) { + unique_xy[x[k]] = y[k]; // Get rid of duplicates so we only have unique points } - } - // Vertical Interpolation - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - std::vector x, y; - std::vector emptyIndices; + // Clear x and y so we can put ONLY the unique points in + x.clear(); + y.clear(); - // Collect existing data points and empty indices - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - x.push_back(i); - y.push_back(this->tableRow[i].tableEntry[j].targetPosition); - } else { - emptyIndices.push_back(i); - } + for (const auto& it : unique_xy) { // We put the unique points back into x and y + x.push_back(it.first); + y.push_back(it.second); } - if (x.size() > 2) { // Need 3 points - tk::spline s(x, y); - - // Interpolate and fill empty cells - for (int i : emptyIndices) { - int tempValue = static_cast(std::round(s(i))); // Round to make more accurate + tk::spline s; // Initialize s for using in cubic spline + + if (x.size() == 1) { + // If we only have one unique point, we fill the row with that value. Good for keeping data + double singleValue = y.front(); + for (int j : emptyIndices) { + this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); + } + continue; + } else if (x.size() == 2) { + // If only 2 unique points, we perform linear interpolation + for (int j : emptyIndices) { + if (j < x.front() || j > x.back()) continue; // So we avoid extrapolation + double x0 = x[0]; + double y0 = y[0]; + double x1 = x[1]; + double y1 = y[1]; + + double interpolated_value = y0 + (y1 - y0) * (j - x0) / (x1 - x0); + + // Might use clamp in the future, but we are not at the right c++ version. + + interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + + int tempValue = static_cast(std::round(interpolated_value)); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } + continue; + } else if (x.size() >= 3) { + // If we have 3 unique points, then we can perform cubic sline + s.set_points(x, y, tk::spline::cspline); + } else { + //Sanity check just so we don't crash when we don't have a unique point, won't happen. + SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); + continue; } + + // Continue with the interpolation. + for (int j : emptyIndices) { + if (j < x.front() || j > x.back()) continue; // So we avoid extrapolation + double interpolated_value = s(j); + interpolated_value = std::max(*std::min_element(y.begin(), y.end()), + std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + + int tempValue = static_cast(std::round(interpolated_value)); + + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } } } From 043664718043b1a6cc62f3e993a5db184d95a673 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Tue, 4 Mar 2025 17:36:10 -0600 Subject: [PATCH 097/451] small extrapolation changes --- src/ERG_Mode.cpp | 2 +- src/Power_Table.cpp | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index bb8cb7be..0eb026d6 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -181,7 +181,7 @@ void ErgMode::computeErg() { } void ErgMode::_setPointChangeState(int newCadence, Measurement& newWatts) { - int32_t tableResult = powerTable->splineLookup(newWatts.getTarget(), newCadence); + int32_t tableResult = powerTable->lookup(newWatts.getTarget(), newCadence); // Sanity check for targets if (tableResult != RETURN_ERROR) { diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 3e0a9ba0..ecec1fc3 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -455,6 +455,16 @@ void PowerTable::extrapFillTable() { y.push_back(it->second); } + if (x.size() == 1) { + int constantValue = static_cast(std::round(y.front())); + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + this->tableRow[i].tableEntry[j].targetPosition = constantValue; + } + } + continue; + } + if (x.size() == 2) { // Use linear extrapolation for two points double slope = (y[1] - y[0]) / (x[1] - x[0]); @@ -520,6 +530,15 @@ void PowerTable::extrapFillTable() { y.push_back(it->second); } + if (x.size() == 1) { + int constantValue = static_cast(std::round(y.front())); + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + this->tableRow[i].tableEntry[j].targetPosition = constantValue; + } + } + continue; + } if (x.size() == 2) { // Use linear extrapolation for two points double slope = (y[1] - y[0]) / (x[1] - x[0]); From 50c3b2cfa5cceeab0ea053c209b6d54580271599 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Tue, 4 Mar 2025 19:39:41 -0600 Subject: [PATCH 098/451] fillTable() finished with cubic spline interpolation. --- src/Power_Table.cpp | 82 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 532a8068..e7206c98 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -417,8 +417,7 @@ void PowerTable::fillTable() { for (int j : emptyIndices) { if (j < x.front() || j > x.back()) continue; // So we avoid extrapolation double interpolated_value = s(j); - interpolated_value = std::max(*std::min_element(y.begin(), y.end()), - std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + interpolated_value = std::max(*std::min_element(y.begin(), y.end()),std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); int tempValue = static_cast(std::round(interpolated_value)); @@ -427,8 +426,87 @@ void PowerTable::fillTable() { } } } + // Vertical Interpolation + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + std::vector x, y; + std::vector emptyIndices; + + // Collect data points + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + x.push_back(static_cast(i)); + y.push_back(static_cast(this->tableRow[i].tableEntry[j].targetPosition)); + } else { + emptyIndices.push_back(i); + } + } + + if (x.size() < 2) continue; // We skip if there are fewer than two unique points + + std::map unique_xy; + for (size_t k = 0; k < x.size(); ++k) { + unique_xy[x[k]] = y[k]; + } + + x.clear(); + y.clear(); + + for (const auto& it : unique_xy) { + x.push_back(it.first); + y.push_back(it.second); + } + + tk::spline s; // Initialize s for using in cubic spline + + if (x.size() == 1) { + double singleValue = y.front(); + for (int i : emptyIndices) { + this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); + } + continue; + } else if (x.size() == 2) { + for (int i : emptyIndices) { + if (i < x.front() || i > x.back()) continue; // Avoid extrapolation + + double x0 = x[0]; + double y0 = y[0]; + double x1 = x[1]; + double y1 = y[1]; + + double interpolated_value = y0 + (y1 - y0) * (i - x0) / (x1 - x0); + + interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + + int tempValue = static_cast(std::round(interpolated_value)); + + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + + } + continue; + } else if (x.size() >= 3) { + s.set_points(x, y, tk::spline::cspline); + } else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); + continue; + } + + for (int i : emptyIndices) { + if (i < x.front() || i > x.back()) continue; // Avoid extrapolation + double interpolated_value = s(i); + interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + + int tempValue = static_cast(std::round(interpolated_value)); + + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } } + //Old Fill Function // void PowerTable::fillTable() { // int tempValue = INT16_MIN; From 605652b042b3b5abe53ee9e054c713ef50dd87f5 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Tue, 4 Mar 2025 19:49:29 -0600 Subject: [PATCH 099/451] filltable() complete --- src/Power_Table.cpp | 81 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index ecec1fc3..433c915c 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -423,8 +423,7 @@ void PowerTable::fillTable() { for (int j : emptyIndices) { if (j < x.front() || j > x.back()) continue; // So we avoid extrapolation double interpolated_value = s(j); - interpolated_value = std::max(*std::min_element(y.begin(), y.end()), - std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + interpolated_value = std::max(*std::min_element(y.begin(), y.end()),std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); int tempValue = static_cast(std::round(interpolated_value)); @@ -433,6 +432,84 @@ void PowerTable::fillTable() { } } } + // Vertical Interpolation + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + std::vector x, y; + std::vector emptyIndices; + + // Collect data points + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + x.push_back(static_cast(i)); + y.push_back(static_cast(this->tableRow[i].tableEntry[j].targetPosition)); + } else { + emptyIndices.push_back(i); + } + } + + if (x.size() < 2) continue; // We skip if there are fewer than two unique points + + std::map unique_xy; + for (size_t k = 0; k < x.size(); ++k) { + unique_xy[x[k]] = y[k]; + } + + x.clear(); + y.clear(); + + for (const auto& it : unique_xy) { + x.push_back(it.first); + y.push_back(it.second); + } + + tk::spline s; // Initialize s for using in cubic spline + + if (x.size() == 1) { + double singleValue = y.front(); + for (int i : emptyIndices) { + this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); + } + continue; + } else if (x.size() == 2) { + for (int i : emptyIndices) { + if (i < x.front() || i > x.back()) continue; // Avoid extrapolation + + double x0 = x[0]; + double y0 = y[0]; + double x1 = x[1]; + double y1 = y[1]; + + double interpolated_value = y0 + (y1 - y0) * (i - x0) / (x1 - x0); + + interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + + int tempValue = static_cast(std::round(interpolated_value)); + + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + + } + continue; + } else if (x.size() >= 3) { + s.set_points(x, y, tk::spline::cspline); + } else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); + continue; + } + + for (int i : emptyIndices) { + if (i < x.front() || i > x.back()) continue; // Avoid extrapolation + double interpolated_value = s(i); + interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + + int tempValue = static_cast(std::round(interpolated_value)); + + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } } void PowerTable::extrapFillTable() { From ee0916437dfb9e43c4b4b33548d055824cc2eac6 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Wed, 5 Mar 2025 13:01:06 -0600 Subject: [PATCH 100/451] implemented cubic spline extrapolation. --- src/Power_Table.cpp | 325 ++++++++++++++++++++------------------------ 1 file changed, 145 insertions(+), 180 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 433c915c..7046e771 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -363,7 +363,7 @@ void PowerTable::fillTable() { } } - if (x.size() < 2) continue; // We skip if there are fewer than two unique points + if (x.size() < 2) continue; // We skip if there are fewer than two unique points std::map unique_xy; for (size_t k = 0; k < x.size(); ++k) { @@ -371,16 +371,16 @@ void PowerTable::fillTable() { } // Clear x and y so we can put ONLY the unique points in - x.clear(); + x.clear(); y.clear(); - for (const auto& it : unique_xy) { // We put the unique points back into x and y + for (const auto& it : unique_xy) { // We put the unique points back into x and y x.push_back(it.first); y.push_back(it.second); } tk::spline s; // Initialize s for using in cubic spline - + if (x.size() == 1) { // If we only have one unique point, we fill the row with that value. Good for keeping data double singleValue = y.front(); @@ -389,9 +389,8 @@ void PowerTable::fillTable() { } continue; } else if (x.size() == 2) { - // If only 2 unique points, we perform linear interpolation + // If only 2 unique points, we perform linear interpolation for (int j : emptyIndices) { - if (j < x.front() || j > x.back()) continue; // So we avoid extrapolation double x0 = x[0]; double y0 = y[0]; double x1 = x[1]; @@ -399,8 +398,6 @@ void PowerTable::fillTable() { double interpolated_value = y0 + (y1 - y0) * (j - x0) / (x1 - x0); - // Might use clamp in the future, but we are not at the right c++ version. - interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); int tempValue = static_cast(std::round(interpolated_value)); @@ -411,259 +408,227 @@ void PowerTable::fillTable() { } continue; } else if (x.size() >= 3) { - // If we have 3 unique points, then we can perform cubic sline + // If we have 3 unique points, then we can perform cubic spline s.set_points(x, y, tk::spline::cspline); } else { - //Sanity check just so we don't crash when we don't have a unique point, won't happen. + // Sanity check just so we don't crash when we don't have a unique point, won't happen. SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); continue; } - // Continue with the interpolation. + // Continue with the interpolation/extrapolation. for (int j : emptyIndices) { - if (j < x.front() || j > x.back()) continue; // So we avoid extrapolation - double interpolated_value = s(j); - interpolated_value = std::max(*std::min_element(y.begin(), y.end()),std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + double interpolated_value = s(j); + interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); - int tempValue = static_cast(std::round(interpolated_value)); + int tempValue = static_cast(std::round(interpolated_value)); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } } - // Vertical Interpolation - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - std::vector x, y; - std::vector emptyIndices; - - // Collect data points - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - x.push_back(static_cast(i)); - y.push_back(static_cast(this->tableRow[i].tableEntry[j].targetPosition)); - } else { - emptyIndices.push_back(i); - } - } - if (x.size() < 2) continue; // We skip if there are fewer than two unique points + // Vertical Interpolation (Similar changes) + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + std::vector x, y; + std::vector emptyIndices; - std::map unique_xy; - for (size_t k = 0; k < x.size(); ++k) { - unique_xy[x[k]] = y[k]; - } + // Collect data points + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + x.push_back(static_cast(i)); + y.push_back(static_cast(this->tableRow[i].tableEntry[j].targetPosition)); + } else { + emptyIndices.push_back(i); + } + } - x.clear(); - y.clear(); + if (x.size() < 2) continue; // We skip if there are fewer than two unique points - for (const auto& it : unique_xy) { - x.push_back(it.first); - y.push_back(it.second); - } + std::map unique_xy; + for (size_t k = 0; k < x.size(); ++k) { + unique_xy[x[k]] = y[k]; + } - tk::spline s; // Initialize s for using in cubic spline + x.clear(); + y.clear(); - if (x.size() == 1) { - double singleValue = y.front(); - for (int i : emptyIndices) { - this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); - } - continue; - } else if (x.size() == 2) { - for (int i : emptyIndices) { - if (i < x.front() || i > x.back()) continue; // Avoid extrapolation + for (const auto& it : unique_xy) { + x.push_back(it.first); + y.push_back(it.second); + } - double x0 = x[0]; - double y0 = y[0]; - double x1 = x[1]; - double y1 = y[1]; + tk::spline s; // Initialize s for using in cubic spline - double interpolated_value = y0 + (y1 - y0) * (i - x0) / (x1 - x0); + if (x.size() == 1) { + double singleValue = y.front(); + for (int i : emptyIndices) { + this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); + } + continue; + } else if (x.size() == 2) { + for (int i : emptyIndices) { + double x0 = x[0]; + double y0 = y[0]; + double x1 = x[1]; + double y1 = y[1]; - interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + double interpolated_value = y0 + (y1 - y0) * (i - x0) / (x1 - x0); - int tempValue = static_cast(std::round(interpolated_value)); + interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + int tempValue = static_cast(std::round(interpolated_value)); - } - continue; - } else if (x.size() >= 3) { - s.set_points(x, y, tk::spline::cspline); - } else { - SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); - continue; - } + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + continue; + } else if (x.size() >= 3) { + s.set_points(x, y, tk::spline::cspline); + } else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); + continue; + } - for (int i : emptyIndices) { - if (i < x.front() || i > x.back()) continue; // Avoid extrapolation - double interpolated_value = s(i); - interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + for (int i : emptyIndices) { + double interpolated_value = s(i); + interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); - int tempValue = static_cast(std::round(interpolated_value)); + int tempValue = static_cast(std::round(interpolated_value)); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } } - } + } } void PowerTable::extrapFillTable() { // Horizontal extrapolation for each row for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - std::map unique_xy; + std::map knownPoints; + std::vector emptyIndices; - // Gather known data points in row i + // Collect known values for this row for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - unique_xy[j] = this->tableRow[i].tableEntry[j].targetPosition; + knownPoints[j] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); + } else { + emptyIndices.push_back(j); } } - if (unique_xy.size() < 2) continue; // Skip if not enough data + if (knownPoints.size() < 2) continue; // Skip if not enough data std::vector x, y; - for (std::map::iterator it = unique_xy.begin(); it != unique_xy.end(); ++it) { - x.push_back(it->first); - y.push_back(it->second); + for (const auto& pair : knownPoints) { + x.push_back(pair.first); + y.push_back(pair.second); } if (x.size() == 1) { - int constantValue = static_cast(std::round(y.front())); - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - this->tableRow[i].tableEntry[j].targetPosition = constantValue; - } - } - continue; - } + int constantValue = static_cast(std::round(y.front())); + for (int j : emptyIndices) { + this->tableRow[i].tableEntry[j].targetPosition = constantValue; + } + continue; + } if (x.size() == 2) { - // Use linear extrapolation for two points double slope = (y[1] - y[0]) / (x[1] - x[0]); double intercept = y[0] - slope * x[0]; - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - double extrapolatedValue = slope * j + intercept; - - // Clamp manually (since std::clamp isn't available in C++14) - double minVal = *std::min_element(y.begin(), y.end()); - double maxVal = *std::max_element(y.begin(), y.end()); - extrapolatedValue = std::max(minVal, std::min(maxVal, extrapolatedValue)); - - int tempValue = static_cast(std::round(extrapolatedValue)); - - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + for (int j : emptyIndices) { + double interpolatedValue = slope * j + intercept; + int roundedValue = static_cast(std::round(interpolatedValue)); + if (testNeighbors(i, j, roundedValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = roundedValue; } } - } - else if (x.size() >= 3) { - // Use cubic spline extrapolation for 3+ points - tk::spline s; - s.set_points(x, y, tk::spline::cspline); - - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - double extrapolatedValue = s(j); - - // Clamp manually - double minVal = *std::min_element(y.begin(), y.end()); - double maxVal = *std::max_element(y.begin(), y.end()); - extrapolatedValue = std::max(minVal, std::min(maxVal, extrapolatedValue)); + continue; + } - int tempValue = static_cast(std::round(extrapolatedValue)); + tk::spline s; + s.set_points(x, y, tk::spline::cspline); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } + for (int j : emptyIndices) { + double interpolatedValue = s(j); + double minVal = *std::min_element(y.begin(), y.end()); + double maxVal = *std::max_element(y.begin(), y.end()); + double range = maxVal - minVal; + interpolatedValue = std::max(minVal - 0.1 * range, std::min(interpolatedValue, maxVal + 0.1 * range)); + int roundedValue = static_cast(std::round(interpolatedValue)); + if (testNeighbors(i, j, roundedValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = roundedValue; } } } // Vertical extrapolation for each column for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - std::map unique_xy; + std::map knownPoints; + std::vector emptyIndices; - // Gather known data points in column j + // Collect known values for this column for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - unique_xy[i] = this->tableRow[i].tableEntry[j].targetPosition; + knownPoints[i] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); + } else { + emptyIndices.push_back(i); } } - if (unique_xy.size() < 2) continue; // Skip if not enough data + if (knownPoints.size() < 2) continue; std::vector x, y; - for (std::map::iterator it = unique_xy.begin(); it != unique_xy.end(); ++it) { - x.push_back(it->first); - y.push_back(it->second); + for (const auto& pair : knownPoints) { + x.push_back(pair.first); + y.push_back(pair.second); } if (x.size() == 1) { - int constantValue = static_cast(std::round(y.front())); - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - this->tableRow[i].tableEntry[j].targetPosition = constantValue; - } - } - continue; - } + int constantValue = static_cast(std::round(y.front())); + for (int i : emptyIndices) { + this->tableRow[i].tableEntry[j].targetPosition = constantValue; + } + continue; + } + if (x.size() == 2) { - // Use linear extrapolation for two points double slope = (y[1] - y[0]) / (x[1] - x[0]); double intercept = y[0] - slope * x[0]; - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - double extrapolatedValue = slope * i + intercept; - - // Clamp manually - double minVal = *std::min_element(y.begin(), y.end()); - double maxVal = *std::max_element(y.begin(), y.end()); - extrapolatedValue = std::max(minVal, std::min(maxVal, extrapolatedValue)); - - int tempValue = static_cast(std::round(extrapolatedValue)); - - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + for (int i : emptyIndices) { + double interpolatedValue = slope * i + intercept; + int roundedValue = static_cast(std::round(interpolatedValue)); + if (testNeighbors(i, j, roundedValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = roundedValue; } } - } - else if (x.size() >= 3) { - // Use cubic spline extrapolation for 3+ points - tk::spline s; - s.set_points(x, y, tk::spline::cspline); - - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - double extrapolatedValue = s(i); - - // Clamp manually - double minVal = *std::min_element(y.begin(), y.end()); - double maxVal = *std::max_element(y.begin(), y.end()); - extrapolatedValue = std::max(minVal, std::min(maxVal, extrapolatedValue)); - - int tempValue = static_cast(std::round(extrapolatedValue)); + continue; + } - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } + tk::spline s; + s.set_points(x, y, tk::spline::cspline); + + for (int i : emptyIndices) { + double interpolatedValue = s(i); + double minVal = *std::min_element(y.begin(), y.end()); + double maxVal = *std::max_element(y.begin(), y.end()); + double range = maxVal - minVal; + interpolatedValue = std::max(minVal - 0.1 * range, std::min(interpolatedValue, maxVal + 0.1 * range)); + int roundedValue = static_cast(std::round(interpolatedValue)); + if (testNeighbors(i, j, roundedValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = roundedValue; } } } } + void PowerTable::extrapolateDiagonal() { for (int d = 1 - POWERTABLE_WATT_SIZE; d < POWERTABLE_CAD_SIZE; ++d) { std::map knownPoints; From 7f8c716b343ce76ea9e40ac1968b8ae355c5503d Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Wed, 5 Mar 2025 21:02:53 -0600 Subject: [PATCH 101/451] extrap function rewrork --- src/Power_Table.cpp | 506 +++++++++++++++++++++++++++++--------------- 1 file changed, 334 insertions(+), 172 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 7046e771..37f9bfad 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -350,36 +350,25 @@ TestResults PowerTable::testNeighbors(int i, int j, int testValue) { void PowerTable::fillTable() { // Horizontal Interpolation for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - std::vector x, y; - std::vector emptyIndices; - - // Collect data points - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - x.push_back(static_cast(j)); - y.push_back(static_cast(this->tableRow[i].tableEntry[j].targetPosition)); - } else { - emptyIndices.push_back(j); - } - } - - if (x.size() < 2) continue; // We skip if there are fewer than two unique points - - std::map unique_xy; - for (size_t k = 0; k < x.size(); ++k) { - unique_xy[x[k]] = y[k]; // Get rid of duplicates so we only have unique points - } - - // Clear x and y so we can put ONLY the unique points in - x.clear(); - y.clear(); + std::map unique_xy; + std::vector emptyIndices; + + // Collect known values for this row + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + unique_xy[j] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); + } else { + emptyIndices.push_back(j); + } + } - for (const auto& it : unique_xy) { // We put the unique points back into x and y - x.push_back(it.first); - y.push_back(it.second); - } + if (unique_xy.size() < 2) continue; // Skip if not enough data - tk::spline s; // Initialize s for using in cubic spline + std::vector x, y; + for (const auto& it : unique_xy) { + x.push_back(it.first); + y.push_back(it.second); + } if (x.size() == 1) { // If we only have one unique point, we fill the row with that value. Good for keeping data @@ -388,15 +377,15 @@ void PowerTable::fillTable() { this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); } continue; - } else if (x.size() == 2) { + } + if (x.size() == 2) { // If only 2 unique points, we perform linear interpolation + double slope = (y[1] - y[0]) / (x[1] - x[0]); + double intercept = y[0] - slope * x[0]; + for (int j : emptyIndices) { - double x0 = x[0]; - double y0 = y[0]; - double x1 = x[1]; - double y1 = y[1]; - double interpolated_value = y0 + (y1 - y0) * (j - x0) / (x1 - x0); + double interpolated_value = slope * j + intercept; interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); @@ -407,131 +396,307 @@ void PowerTable::fillTable() { } } continue; - } else if (x.size() >= 3) { + } + if (x.size() >= 3) { // If we have 3 unique points, then we can perform cubic spline + tk::spline s; // Initialize s for using in cubic spline s.set_points(x, y, tk::spline::cspline); - } else { - // Sanity check just so we don't crash when we don't have a unique point, won't happen. - SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); + for (int j : emptyIndices) { + double interpolated_value = s(j); + interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + + int tempValue = static_cast(std::round(interpolated_value)); + + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + + } + + // Vertical Interpolation + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + std::map unique_xy; + std::vector emptyIndices; + + // Collect known values for this column + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + unique_xy[i] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); + } else { + emptyIndices.push_back(i); + } + } + + if (unique_xy.size() < 2) continue; + + std::vector x, y; + for (const auto& it : unique_xy) { + x.push_back(it.first); + y.push_back(it.second); + } + + if (x.size() == 1) { + double singleValue = y.front(); + for (int i : emptyIndices) { + this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); + } continue; - } + } + if (x.size() == 2) { + + double slope = (y[1] - y[0]) / (x[1] - x[0]); + double intercept = y[0] - slope * x[0]; + + for (int i : emptyIndices) { + + double interpolated_value = slope * i + intercept; - // Continue with the interpolation/extrapolation. - for (int j : emptyIndices) { - double interpolated_value = s(j); - interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); - int tempValue = static_cast(std::round(interpolated_value)); + int tempValue = static_cast(std::round(interpolated_value)); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } } + continue; + } + if (x.size() >= 3) { + tk::spline s; // Initialize s for using in cubic spline + s.set_points(x, y, tk::spline::cspline); + for (int i : emptyIndices) { + double interpolated_value = s(i); + interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + + int tempValue = static_cast(std::round(interpolated_value)); + + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } } } +} - // Vertical Interpolation (Similar changes) - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - std::vector x, y; - std::vector emptyIndices; +/* +void PowerTable::fillTable() { + // Horizontal Interpolation + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - // Collect data points - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - x.push_back(static_cast(i)); - y.push_back(static_cast(this->tableRow[i].tableEntry[j].targetPosition)); - } else { - emptyIndices.push_back(i); + std::map unique_xy; + std::vector emptyIndices; + + // Collect data points + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + unique_xy[j] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); // Get all unique points + } else { + emptyIndices.push_back(j); + } + } + + if (unique_xy.size() < 2) continue; // Make sure that we have more than 2 unique points + + std::vector x, y; + for (const auto& it : unique_xy) { // Put the unique values in x and y + x.push_back(it.first); + y.push_back(it.second); + } + + if (x.size() == 1) { // If we only have one unique point, we fill the row with that value. Good for keeping data + double singleValue = y.front(); + for (int j : emptyIndices) { + this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); } - } + continue; + } else if (x.size() == 2) { // If only 2 unique points, we perform linear interpolation + for (int j : emptyIndices) { - if (x.size() < 2) continue; // We skip if there are fewer than two unique points + double x0 = x[0]; + double y0 = y[0]; + double x1 = x[1]; + double y1 = y[1]; - std::map unique_xy; - for (size_t k = 0; k < x.size(); ++k) { - unique_xy[x[k]] = y[k]; - } + double tempValue = y0 + (y1 - y0) * (j - x0) / (x1 - x0); // interpolation formula + double minValue = *std::min_element(y.begin(), y.end()); + double maxValue = *std::max_element(y.begin(), y.end()); + double range = maxValue - minValue; + + double clampingFactor = 0.1 + 0.05 * std::abs((y.back() - y.front()) / (x.back() - x.front())); + + if (j < x.front() || j > x.back()) { // Extrapolate outside the range + tempValue = std::max(minValue - clampingFactor * range, std::min(tempValue, maxValue + clampingFactor * range)); + } + if (j > x.front() && j < x.back()) { // Interpoalte inside the range + tempValue = std::max(minValue, std::min(maxValue, tempValue)); //we stay inside the range of the points + } - x.clear(); - y.clear(); + int roundedValue = static_cast(std::round(tempValue)); + + if (this->testNeighbors(i, j, roundedValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = roundedValue; + } + } + continue; + } else if (x.size() >= 3) { // If we have 3 unique points, then we can perform cubic spline + + tk::spline s; // Initialize s for using in cubic spline + s.set_points(x, y, tk::spline::cspline); + + for (int j : emptyIndices) { + + double tempValue = s(j); + double minValue = *std::min_element(y.begin(), y.end()); + double maxValue = *std::max_element(y.begin(), y.end()); + double range = maxValue - minValue; + double clampingFactor = 0.1 + 0.05 * std::abs((y.back() - y.front()) / (x.back() - x.front())); + + if (j < x.front() || j > x.back()) { // Extrapolate outside the range + tempValue = std::max(minValue - clampingFactor * range, std::min(tempValue, maxValue + clampingFactor * range)); + } + if (j > x.front() && j < x.back()) { // Interpoalte inside the range + tempValue = std::max(minValue, std::min(maxValue, tempValue)); //we stay inside the range of the points + } + + int roundedValue = static_cast(std::round(tempValue)); + + if (this->testNeighbors(i, j, roundedValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = roundedValue; + } + } + + } else { // Saftey check just so we don't crash when we don't have a unique point, won't happen. + + SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); + continue; - for (const auto& it : unique_xy) { - x.push_back(it.first); - y.push_back(it.second); } + } + + // Vertical Interpolation + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - tk::spline s; // Initialize s for using in cubic spline + std::map unique_xy; + std::vector emptyIndices; - if (x.size() == 1) { + // Collect data points + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + unique_xy[i] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); + } else { + emptyIndices.push_back(i); + } + } + + if (unique_xy.size() < 2) continue; + + std::vector x, y; + + for (const auto& it : unique_xy) { + x.push_back(it.first); + y.push_back(it.second); + } + + if (x.size() == 1) { // If we only have one unique point, we fill the row with that value. Good for keeping data double singleValue = y.front(); for (int i : emptyIndices) { this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); } continue; - } else if (x.size() == 2) { + } else if (x.size() == 2) { // If only 2 unique points, we perform linear interpolation for (int i : emptyIndices) { + double x0 = x[0]; double y0 = y[0]; double x1 = x[1]; double y1 = y[1]; - double interpolated_value = y0 + (y1 - y0) * (i - x0) / (x1 - x0); - - interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + double tempValue = y0 + (y1 - y0) * (i - x0) / (x1 - x0); //interpolation formula + double minValue = *std::min_element(y.begin(), y.end()); + double maxValue = *std::max_element(y.begin(), y.end()); + double range = maxValue - minValue; + double clampingFactor = 0.1 + 0.05 * std::abs((y.back() - y.front()) / (x.back() - x.front())); + + if (i < x.front() || i > x.back()) { // Extrapolate outside the range + tempValue = std::max(minValue - clampingFactor * range, std::min(tempValue, maxValue + clampingFactor * range)); + } + if (i > x.front() && i < x.back()) { // Interpoalte inside the range + tempValue = std::max(minValue, std::min(maxValue, tempValue)); //we stay inside the range of the points + } - int tempValue = static_cast(std::round(interpolated_value)); + int roundedValue = static_cast(std::round(tempValue)); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + if (this->testNeighbors(i, j, roundedValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = roundedValue; } } continue; - } else if (x.size() >= 3) { + } else if (x.size() >= 3) { // If we have 3 unique points, then we can perform cubic spline + + tk::spline s; // Initialize s for using in cubic spline s.set_points(x, y, tk::spline::cspline); - } else { - SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); - continue; - } - for (int i : emptyIndices) { - double interpolated_value = s(i); - interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + for (int i : emptyIndices) { + + double tempValue = s(i); + double minValue = *std::min_element(y.begin(), y.end()); + double maxValue = *std::max_element(y.begin(), y.end()); + double range = maxValue - minValue; + double clampingFactor = 0.1 + 0.05 * std::abs((y.back() - y.front()) / (x.back() - x.front())); + + if (i < x.front() || i > x.back()) { // Extrapolate outside the range + tempValue = std::max(minValue - clampingFactor * range, std::min(tempValue, maxValue + clampingFactor * range)); + } + if (i > x.front() && i < x.back()) { // Interpoalte inside the range + tempValue = std::max(minValue, std::min(maxValue, tempValue)); //we stay inside the range of the points + } + + int roundedValue = static_cast(std::round(tempValue)); + + if (this->testNeighbors(i, j, roundedValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = roundedValue; + } + } + + } else { // Saftey check just so we don't crash when we don't have a unique point, won't happen. - int tempValue = static_cast(std::round(interpolated_value)); + SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); + continue; - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } } } } +*/ void PowerTable::extrapFillTable() { - // Horizontal extrapolation for each row + // Horizontal extrapolation for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - std::map knownPoints; + std::map unique_xy; std::vector emptyIndices; // Collect known values for this row for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - knownPoints[j] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); + unique_xy[j] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); } else { emptyIndices.push_back(j); } } - if (knownPoints.size() < 2) continue; // Skip if not enough data + if (unique_xy.size() < 2) continue; // Skip if not enough data std::vector x, y; - for (const auto& pair : knownPoints) { - x.push_back(pair.first); - y.push_back(pair.second); + for (const auto& it : unique_xy) { + x.push_back(it.first); + y.push_back(it.second); } if (x.size() == 1) { - int constantValue = static_cast(std::round(y.front())); + int singleValue = static_cast(std::round(y.front())); for (int j : emptyIndices) { - this->tableRow[i].tableEntry[j].targetPosition = constantValue; + this->tableRow[i].tableEntry[j].targetPosition = singleValue; } continue; } @@ -541,51 +706,52 @@ void PowerTable::extrapFillTable() { double intercept = y[0] - slope * x[0]; for (int j : emptyIndices) { - double interpolatedValue = slope * j + intercept; - int roundedValue = static_cast(std::round(interpolatedValue)); - if (testNeighbors(i, j, roundedValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = roundedValue; + double extrapolated_value = slope * j + intercept; + int tempValue = static_cast(std::round(extrapolated_value)); + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } continue; } - - tk::spline s; - s.set_points(x, y, tk::spline::cspline); - - for (int j : emptyIndices) { - double interpolatedValue = s(j); - double minVal = *std::min_element(y.begin(), y.end()); - double maxVal = *std::max_element(y.begin(), y.end()); - double range = maxVal - minVal; - interpolatedValue = std::max(minVal - 0.1 * range, std::min(interpolatedValue, maxVal + 0.1 * range)); - int roundedValue = static_cast(std::round(interpolatedValue)); - if (testNeighbors(i, j, roundedValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = roundedValue; - } + if(x.size() >= 3){ + tk::spline s; + s.set_points(x, y, tk::spline::cspline); + + for (int j : emptyIndices) { + double extrapolated_value = s(j); + double minVal = *std::min_element(y.begin(), y.end()); + double maxVal = *std::max_element(y.begin(), y.end()); + double range = maxVal - minVal; + extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); + int tempValue = static_cast(std::round(extrapolated_value)); + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } } } - // Vertical extrapolation for each column + // Vertical extrapolation for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - std::map knownPoints; + std::map unique_xy; std::vector emptyIndices; // Collect known values for this column for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - knownPoints[i] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); + unique_xy[i] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); } else { emptyIndices.push_back(i); } } - if (knownPoints.size() < 2) continue; + if (unique_xy.size() < 2) continue; std::vector x, y; - for (const auto& pair : knownPoints) { - x.push_back(pair.first); - y.push_back(pair.second); + for (const auto& it : unique_xy) { + x.push_back(it.first); + y.push_back(it.second); } if (x.size() == 1) { @@ -601,28 +767,29 @@ void PowerTable::extrapFillTable() { double intercept = y[0] - slope * x[0]; for (int i : emptyIndices) { - double interpolatedValue = slope * i + intercept; - int roundedValue = static_cast(std::round(interpolatedValue)); - if (testNeighbors(i, j, roundedValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = roundedValue; + double extrapolated_value = slope * i + intercept; + int tempValue = static_cast(std::round(extrapolated_value)); + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } continue; } - - tk::spline s; - s.set_points(x, y, tk::spline::cspline); - - for (int i : emptyIndices) { - double interpolatedValue = s(i); - double minVal = *std::min_element(y.begin(), y.end()); - double maxVal = *std::max_element(y.begin(), y.end()); - double range = maxVal - minVal; - interpolatedValue = std::max(minVal - 0.1 * range, std::min(interpolatedValue, maxVal + 0.1 * range)); - int roundedValue = static_cast(std::round(interpolatedValue)); - if (testNeighbors(i, j, roundedValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = roundedValue; - } + if(x.size() >= 3){ + tk::spline s; + s.set_points(x, y, tk::spline::cspline); + + for (int i : emptyIndices) { + double extrapolated_value = s(i); + double minVal = *std::min_element(y.begin(), y.end()); + double maxVal = *std::max_element(y.begin(), y.end()); + double range = maxVal - minVal; + extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); + int tempValue = static_cast(std::round(extrapolated_value)); + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } } } } @@ -631,7 +798,7 @@ void PowerTable::extrapFillTable() { void PowerTable::extrapolateDiagonal() { for (int d = 1 - POWERTABLE_WATT_SIZE; d < POWERTABLE_CAD_SIZE; ++d) { - std::map knownPoints; + std::map unique_xy; std::vector> emptyIndices; // Collect known values for this diagonal @@ -639,72 +806,67 @@ void PowerTable::extrapolateDiagonal() { int j = i - d; if (j >= 0 && j < POWERTABLE_WATT_SIZE) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - knownPoints[i] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); + unique_xy[i] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); } else { emptyIndices.emplace_back(i, j); } } } - if (knownPoints.size() < 2) continue; // Skip if not enough data + if (unique_xy.size() < 2) continue; // Skip if not enough data - // Extract x and y values from map (already sorted and unique) std::vector x, y; - for (const auto& pair : knownPoints) { - x.push_back(pair.first); - y.push_back(pair.second); + for (const auto& it : unique_xy) { + x.push_back(it.first); + y.push_back(it.second); } - // If only 1 unique value, fill all missing positions with it if (x.size() == 1) { - int constantValue = static_cast(std::round(y.front())); - for (const auto& index : emptyIndices) { - this->tableRow[index.first].tableEntry[index.second].targetPosition = constantValue; + int singleValue = static_cast(std::round(y.front())); + for (const auto& it : emptyIndices) { + this->tableRow[it.first].tableEntry[it.second].targetPosition = singleValue; } continue; } - // Handle linear interpolation for exactly two points if (x.size() == 2) { double slope = (y[1] - y[0]) / (x[1] - x[0]); double intercept = y[0] - slope * x[0]; - for (const auto& index : emptyIndices) { - int i = index.first; - int j = index.second; + for (const auto& it : emptyIndices) { + int i = it.first; + int j = it.second; - double interpolatedValue = slope * i + intercept; - int roundedValue = static_cast(std::round(interpolatedValue)); + double extrapolated_value = slope * i + intercept; + int tempValue = static_cast(std::round(extrapolated_value)); - if (testNeighbors(i, j, roundedValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = roundedValue; + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } - continue; // Avoid calling cubic spline with 2 points + continue; } - // If there are at least 3 points, use cubic spline if (x.size() >= 3) { tk::spline s; - s.set_points(x, y, tk::spline::cspline); // Use cubic spline + s.set_points(x, y, tk::spline::cspline); - for (const auto& index : emptyIndices) { - int i = index.first; - int j = index.second; + for (const auto& it : emptyIndices) { + int i = it.first; + int j = it.second; if (i < 0 || i >= POWERTABLE_CAD_SIZE || j < 0 || j >= POWERTABLE_WATT_SIZE) continue; - double interpolatedValue = s(static_cast(i)); + double extrapolated_value = s(static_cast(i)); - // Compute min/max for clamping double minVal = *std::min_element(y.begin(), y.end()); double maxVal = *std::max_element(y.begin(), y.end()); double range = maxVal - minVal; - interpolatedValue = std::max(minVal - 0.1 * range, std::min(interpolatedValue, maxVal + 0.1 * range)); + extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); - int roundedValue = static_cast(std::round(interpolatedValue)); - if (testNeighbors(i, j, roundedValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = roundedValue; + int tempValue = static_cast(std::round(extrapolated_value)); + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } } From 6d545c0a135b9028ca91d1fc8ba343bc7db1707c Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Wed, 5 Mar 2025 21:18:16 -0600 Subject: [PATCH 102/451] logging fixes --- src/Power_Table.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 37f9bfad..5ee9cbb4 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -353,7 +353,7 @@ void PowerTable::fillTable() { std::map unique_xy; std::vector emptyIndices; - // Collect known values for this row + // Collect data points for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { unique_xy[j] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); @@ -420,7 +420,7 @@ void PowerTable::fillTable() { std::map unique_xy; std::vector emptyIndices; - // Collect known values for this column + // Collect data points for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { unique_xy[i] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); @@ -676,7 +676,7 @@ void PowerTable::extrapFillTable() { std::map unique_xy; std::vector emptyIndices; - // Collect known values for this row + // Collect data points for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { unique_xy[j] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); @@ -737,7 +737,7 @@ void PowerTable::extrapFillTable() { std::map unique_xy; std::vector emptyIndices; - // Collect known values for this column + // Collect data points for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { unique_xy[i] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); From b18ee016301ad97ddd9e9998a6feb975038c3df5 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Wed, 5 Mar 2025 21:33:51 -0600 Subject: [PATCH 103/451] modified fillTable() for better readability --- src/Power_Table.cpp | 180 +++++++++++++++++++------------------------- 1 file changed, 77 insertions(+), 103 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index e7206c98..97f95b1c 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -344,37 +344,26 @@ TestResults PowerTable::testNeighbors(int i, int j, int testValue) { void PowerTable::fillTable() { // Horizontal Interpolation for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - std::vector x, y; - std::vector emptyIndices; - - // Collect data points - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - x.push_back(static_cast(j)); - y.push_back(static_cast(this->tableRow[i].tableEntry[j].targetPosition)); - } else { - emptyIndices.push_back(j); - } - } - - if (x.size() < 2) continue; // We skip if there are fewer than two unique points + std::map unique_xy; + std::vector emptyIndices; - std::map unique_xy; - for (size_t k = 0; k < x.size(); ++k) { - unique_xy[x[k]] = y[k]; // Get rid of duplicates so we only have unique points - } + // Collect data points + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + unique_xy[j] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); + } else { + emptyIndices.push_back(j); + } + } - // Clear x and y so we can put ONLY the unique points in - x.clear(); - y.clear(); + if (unique_xy.size() < 2) continue; // Skip if not enough data - for (const auto& it : unique_xy) { // We put the unique points back into x and y - x.push_back(it.first); - y.push_back(it.second); - } + std::vector x, y; + for (const auto& it : unique_xy) { + x.push_back(it.first); + y.push_back(it.second); + } - tk::spline s; // Initialize s for using in cubic spline - if (x.size() == 1) { // If we only have one unique point, we fill the row with that value. Good for keeping data double singleValue = y.front(); @@ -382,20 +371,18 @@ void PowerTable::fillTable() { this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); } continue; - } else if (x.size() == 2) { - // If only 2 unique points, we perform linear interpolation + } + if (x.size() == 2) { + // If only 2 unique points, we perform linear interpolation + for (int j : emptyIndices) { - if (j < x.front() || j > x.back()) continue; // So we avoid extrapolation - double x0 = x[0]; - double y0 = y[0]; - double x1 = x[1]; - double y1 = y[1]; - double interpolated_value = y0 + (y1 - y0) * (j - x0) / (x1 - x0); + double interpolated_value = y[0] + (y[1] - y[0]) * (j - x[0]) / (x[1] - x[1]); //interpolation formula - // Might use clamp in the future, but we are not at the right c++ version. + double minValue = *std::min_element(y.begin(), y.end()); + double maxValue = *std::max_element(y.begin(), y.end()); - interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); int tempValue = static_cast(std::round(interpolated_value)); @@ -404,106 +391,93 @@ void PowerTable::fillTable() { } } continue; - } else if (x.size() >= 3) { - // If we have 3 unique points, then we can perform cubic sline + } + if (x.size() >= 3) { + // If we have 3 unique points, then we can perform cubic spline + tk::spline s; // Initialize s for using in cubic spline s.set_points(x, y, tk::spline::cspline); - } else { - //Sanity check just so we don't crash when we don't have a unique point, won't happen. - SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); - continue; - } - - // Continue with the interpolation. - for (int j : emptyIndices) { - if (j < x.front() || j > x.back()) continue; // So we avoid extrapolation - double interpolated_value = s(j); - interpolated_value = std::max(*std::min_element(y.begin(), y.end()),std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); - - int tempValue = static_cast(std::round(interpolated_value)); + for (int j : emptyIndices) { + double interpolated_value = s(j); + double minValue = *std::min_element(y.begin(), y.end()); + double maxValue = *std::max_element(y.begin(), y.end()); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); + + int tempValue = static_cast(std::round(interpolated_value)); + + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } } - } + } + } + // Vertical Interpolation for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - std::vector x, y; + std::map unique_xy; std::vector emptyIndices; // Collect data points for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - x.push_back(static_cast(i)); - y.push_back(static_cast(this->tableRow[i].tableEntry[j].targetPosition)); + unique_xy[i] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); } else { emptyIndices.push_back(i); } } - if (x.size() < 2) continue; // We skip if there are fewer than two unique points - - std::map unique_xy; - for (size_t k = 0; k < x.size(); ++k) { - unique_xy[x[k]] = y[k]; - } - - x.clear(); - y.clear(); + if (unique_xy.size() < 2) continue; + std::vector x, y; for (const auto& it : unique_xy) { x.push_back(it.first); y.push_back(it.second); } - tk::spline s; // Initialize s for using in cubic spline + if (x.size() == 1) { + double singleValue = y.front(); + for (int i : emptyIndices) { + this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); + } + continue; + } + if (x.size() == 2) { - if (x.size() == 1) { - double singleValue = y.front(); - for (int i : emptyIndices) { - this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); - } - continue; - } else if (x.size() == 2) { - for (int i : emptyIndices) { - if (i < x.front() || i > x.back()) continue; // Avoid extrapolation + for (int i : emptyIndices) { - double x0 = x[0]; - double y0 = y[0]; - double x1 = x[1]; - double y1 = y[1]; + double interpolated_value = y[0] + (y[1] - y[0]) * (i - x[0]) / (x[1] - x[1]); //interpolation formula - double interpolated_value = y0 + (y1 - y0) * (i - x0) / (x1 - x0); + double minValue = *std::min_element(y.begin(), y.end()); + double maxValue = *std::max_element(y.begin(), y.end()); - interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); int tempValue = static_cast(std::round(interpolated_value)); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + continue; + } + if (x.size() >= 3) { + tk::spline s; // Initialize s for using in cubic spline + s.set_points(x, y, tk::spline::cspline); + for (int i : emptyIndices) { + double interpolated_value = s(i); + double minValue = *std::min_element(y.begin(), y.end()); + double maxValue = *std::max_element(y.begin(), y.end()); + + interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); + int tempValue = static_cast(std::round(interpolated_value)); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } - - } - continue; - } else if (x.size() >= 3) { - s.set_points(x, y, tk::spline::cspline); - } else { - SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); - continue; - } - - for (int i : emptyIndices) { - if (i < x.front() || i > x.back()) continue; // Avoid extrapolation - double interpolated_value = s(i); - interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); - - int tempValue = static_cast(std::round(interpolated_value)); - - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } - } + } } From 7207af1ade25dbd223ef1eff1017af97fd8b418e Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Wed, 5 Mar 2025 22:27:28 -0600 Subject: [PATCH 104/451] added extrapolation constraint back into fillTable() --- src/Power_Table.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 97f95b1c..16847456 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -377,6 +377,8 @@ void PowerTable::fillTable() { for (int j : emptyIndices) { + if (j < x.front() || j > x.back()) continue; + double interpolated_value = y[0] + (y[1] - y[0]) * (j - x[0]) / (x[1] - x[1]); //interpolation formula double minValue = *std::min_element(y.begin(), y.end()); @@ -397,6 +399,9 @@ void PowerTable::fillTable() { tk::spline s; // Initialize s for using in cubic spline s.set_points(x, y, tk::spline::cspline); for (int j : emptyIndices) { + + if (j < x.front() || j > x.back()) continue; + double interpolated_value = s(j); double minValue = *std::min_element(y.begin(), y.end()); double maxValue = *std::max_element(y.begin(), y.end()); @@ -446,6 +451,8 @@ void PowerTable::fillTable() { for (int i : emptyIndices) { + if (i < x.front() || i > x.back()) continue; + double interpolated_value = y[0] + (y[1] - y[0]) * (i - x[0]) / (x[1] - x[1]); //interpolation formula double minValue = *std::min_element(y.begin(), y.end()); @@ -465,6 +472,9 @@ void PowerTable::fillTable() { tk::spline s; // Initialize s for using in cubic spline s.set_points(x, y, tk::spline::cspline); for (int i : emptyIndices) { + + if (i < x.front() || i > x.back()) continue; + double interpolated_value = s(i); double minValue = *std::min_element(y.begin(), y.end()); double maxValue = *std::max_element(y.begin(), y.end()); From de12d291405f2222acc1815b1214efb33a77d158 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Thu, 6 Mar 2025 10:00:42 -0600 Subject: [PATCH 105/451] fixed fillTable() bug, typo in linear interpolation formula --- src/Power_Table.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 16847456..82ef4235 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -371,15 +371,14 @@ void PowerTable::fillTable() { this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); } continue; - } - if (x.size() == 2) { + } else if (x.size() == 2) { // If only 2 unique points, we perform linear interpolation for (int j : emptyIndices) { if (j < x.front() || j > x.back()) continue; - double interpolated_value = y[0] + (y[1] - y[0]) * (j - x[0]) / (x[1] - x[1]); //interpolation formula + double interpolated_value = y[0] + (y[1] - y[0]) * (j - x[0]) / (x[1] - x[0]); //interpolation formula double minValue = *std::min_element(y.begin(), y.end()); double maxValue = *std::max_element(y.begin(), y.end()); @@ -393,8 +392,7 @@ void PowerTable::fillTable() { } } continue; - } - if (x.size() >= 3) { + } else if (x.size() >= 3) { // If we have 3 unique points, then we can perform cubic spline tk::spline s; // Initialize s for using in cubic spline s.set_points(x, y, tk::spline::cspline); @@ -414,8 +412,10 @@ void PowerTable::fillTable() { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } - } - + } else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); + continue; + } } // Vertical Interpolation @@ -446,14 +446,13 @@ void PowerTable::fillTable() { this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); } continue; - } - if (x.size() == 2) { + } else if (x.size() == 2) { for (int i : emptyIndices) { if (i < x.front() || i > x.back()) continue; - double interpolated_value = y[0] + (y[1] - y[0]) * (i - x[0]) / (x[1] - x[1]); //interpolation formula + double interpolated_value = y[0] + (y[1] - y[0]) * (i - x[0]) / (x[1] - x[0]); //interpolation formula double minValue = *std::min_element(y.begin(), y.end()); double maxValue = *std::max_element(y.begin(), y.end()); @@ -467,8 +466,7 @@ void PowerTable::fillTable() { } } continue; - } - if (x.size() >= 3) { + } else if (x.size() >= 3) { tk::spline s; // Initialize s for using in cubic spline s.set_points(x, y, tk::spline::cspline); for (int i : emptyIndices) { @@ -486,7 +484,10 @@ void PowerTable::fillTable() { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } - } + } else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); + continue; + } } } From a191b39938e4f78f2bed77cea587196bea7992cb Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Fri, 7 Mar 2025 12:17:52 -0600 Subject: [PATCH 106/451] Bug Fix: X values are now in ascending order. --- src/Power_Table.cpp | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 82ef4235..bb01cecc 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -360,8 +360,8 @@ void PowerTable::fillTable() { std::vector x, y; for (const auto& it : unique_xy) { - x.push_back(it.first); - y.push_back(it.second); + x.push_back(static_cast(it.first)); + y.push_back(static_cast(it.second)); } if (x.size() == 1) { @@ -393,6 +393,19 @@ void PowerTable::fillTable() { } continue; } else if (x.size() >= 3) { + + bool validForSpline = true; + for (size_t i = 1; i < x.size(); ++i) { + if (x[i] <= x[i - 1]) { // Make sure x is in ascending order and not a duplicate + validForSpline = false; + break; + } + } + if (!validForSpline) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); + continue; + } + // If we have 3 unique points, then we can perform cubic spline tk::spline s; // Initialize s for using in cubic spline s.set_points(x, y, tk::spline::cspline); @@ -436,8 +449,8 @@ void PowerTable::fillTable() { std::vector x, y; for (const auto& it : unique_xy) { - x.push_back(it.first); - y.push_back(it.second); + x.push_back(static_cast(it.first)); + y.push_back(static_cast(it.second)); } if (x.size() == 1) { @@ -467,6 +480,20 @@ void PowerTable::fillTable() { } continue; } else if (x.size() >= 3) { + + bool validForSpline = true; + for (size_t i = 1; i < x.size(); ++i) { + if (x[i] <= x[i - 1]) { // Make sure x is in ascending order and not a duplicate + validForSpline = false; + break; + } + } + if (!validForSpline) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); + continue; // Skip spline interpolation + } + + tk::spline s; // Initialize s for using in cubic spline s.set_points(x, y, tk::spline::cspline); for (int i : emptyIndices) { From cfcf42e622ae55e4e0595cc54e9c4047d912a8a0 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Fri, 7 Mar 2025 12:18:55 -0600 Subject: [PATCH 107/451] new fillTable() function --- src/Power_Table.cpp | 101 +++++++++++++++++++++++++++++++------------- 1 file changed, 72 insertions(+), 29 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 5ee9cbb4..73150089 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -366,8 +366,8 @@ void PowerTable::fillTable() { std::vector x, y; for (const auto& it : unique_xy) { - x.push_back(it.first); - y.push_back(it.second); + x.push_back(static_cast(it.first)); + y.push_back(static_cast(it.second)); } if (x.size() == 1) { @@ -377,17 +377,19 @@ void PowerTable::fillTable() { this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); } continue; - } - if (x.size() == 2) { + } else if (x.size() == 2) { // If only 2 unique points, we perform linear interpolation - double slope = (y[1] - y[0]) / (x[1] - x[0]); - double intercept = y[0] - slope * x[0]; for (int j : emptyIndices) { - double interpolated_value = slope * j + intercept; + if (j < x.front() || j > x.back()) continue; - interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + double interpolated_value = y[0] + (y[1] - y[0]) * (j - x[0]) / (x[1] - x[0]); //interpolation formula + + double minValue = *std::min_element(y.begin(), y.end()); + double maxValue = *std::max_element(y.begin(), y.end()); + + interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); int tempValue = static_cast(std::round(interpolated_value)); @@ -396,14 +398,32 @@ void PowerTable::fillTable() { } } continue; - } - if (x.size() >= 3) { + } else if (x.size() >= 3) { + + bool validForSpline = true; + for (size_t i = 1; i < x.size(); ++i) { + if (x[i] <= x[i - 1]) { // Make sure x is in ascending order and not a duplicate + validForSpline = false; + break; + } + } + if (!validForSpline) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); + continue; + } + // If we have 3 unique points, then we can perform cubic spline tk::spline s; // Initialize s for using in cubic spline s.set_points(x, y, tk::spline::cspline); for (int j : emptyIndices) { + + if (j < x.front() || j > x.back()) continue; + double interpolated_value = s(j); - interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + double minValue = *std::min_element(y.begin(), y.end()); + double maxValue = *std::max_element(y.begin(), y.end()); + + interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); int tempValue = static_cast(std::round(interpolated_value)); @@ -411,8 +431,10 @@ void PowerTable::fillTable() { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } - } - + } else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); + continue; + } } // Vertical Interpolation @@ -433,8 +455,8 @@ void PowerTable::fillTable() { std::vector x, y; for (const auto& it : unique_xy) { - x.push_back(it.first); - y.push_back(it.second); + x.push_back(static_cast(it.first)); + y.push_back(static_cast(it.second)); } if (x.size() == 1) { @@ -443,43 +465,64 @@ void PowerTable::fillTable() { this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); } continue; - } - if (x.size() == 2) { - - double slope = (y[1] - y[0]) / (x[1] - x[0]); - double intercept = y[0] - slope * x[0]; + } else if (x.size() == 2) { for (int i : emptyIndices) { - double interpolated_value = slope * i + intercept; + if (i < x.front() || i > x.back()) continue; - interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); + double interpolated_value = y[0] + (y[1] - y[0]) * (i - x[0]) / (x[1] - x[0]); //interpolation formula - int tempValue = static_cast(std::round(interpolated_value)); + double minValue = *std::min_element(y.begin(), y.end()); + double maxValue = *std::max_element(y.begin(), y.end()); + + interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); + + int tempValue = static_cast(std::round(interpolated_value)); if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } continue; - } - if (x.size() >= 3) { + } else if (x.size() >= 3) { + + bool validForSpline = true; + for (size_t i = 1; i < x.size(); ++i) { + if (x[i] <= x[i - 1]) { // Make sure x is in ascending order and not a duplicate + validForSpline = false; + break; + } + } + if (!validForSpline) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); + continue; // Skip spline interpolation + } + + tk::spline s; // Initialize s for using in cubic spline s.set_points(x, y, tk::spline::cspline); for (int i : emptyIndices) { + + if (i < x.front() || i > x.back()) continue; + double interpolated_value = s(i); - interpolated_value = std::max(*std::min_element(y.begin(), y.end()), std::min(*std::max_element(y.begin(), y.end()), interpolated_value)); - + double minValue = *std::min_element(y.begin(), y.end()); + double maxValue = *std::max_element(y.begin(), y.end()); + + interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); int tempValue = static_cast(std::round(interpolated_value)); if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } - } + } else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); + continue; + } } } - /* void PowerTable::fillTable() { // Horizontal Interpolation From 7e62fa00a13d66c80c55931bf955c0f493d42011 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Fri, 7 Mar 2025 12:44:15 -0600 Subject: [PATCH 108/451] modified extrap functions --- src/Power_Table.cpp | 51 +++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 73150089..8ef4fa73 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -732,8 +732,8 @@ void PowerTable::extrapFillTable() { std::vector x, y; for (const auto& it : unique_xy) { - x.push_back(it.first); - y.push_back(it.second); + x.push_back(static_cast(it.first)); + y.push_back(static_cast(it.second)); } if (x.size() == 1) { @@ -745,11 +745,11 @@ void PowerTable::extrapFillTable() { } if (x.size() == 2) { - double slope = (y[1] - y[0]) / (x[1] - x[0]); - double intercept = y[0] - slope * x[0]; for (int j : emptyIndices) { - double extrapolated_value = slope * j + intercept; + + double extrapolated_value = y[0] + (y[1] - y[0]) * (j - x[0]) / (x[1] - x[0]); //interpolation formula + int tempValue = static_cast(std::round(extrapolated_value)); if (testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; @@ -758,6 +758,19 @@ void PowerTable::extrapFillTable() { continue; } if(x.size() >= 3){ + + bool validForSpline = true; + for (size_t i = 1; i < x.size(); ++i) { + if (x[i] <= x[i - 1]) { // Make sure x is in ascending order and not a duplicate + validForSpline = false; + break; + } + } + if (!validForSpline) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); + continue; // Skip spline interpolation + } + tk::spline s; s.set_points(x, y, tk::spline::cspline); @@ -793,8 +806,8 @@ void PowerTable::extrapFillTable() { std::vector x, y; for (const auto& it : unique_xy) { - x.push_back(it.first); - y.push_back(it.second); + x.push_back(static_cast(it.first)); + y.push_back(static_cast(it.second)); } if (x.size() == 1) { @@ -806,11 +819,11 @@ void PowerTable::extrapFillTable() { } if (x.size() == 2) { - double slope = (y[1] - y[0]) / (x[1] - x[0]); - double intercept = y[0] - slope * x[0]; for (int i : emptyIndices) { - double extrapolated_value = slope * i + intercept; + + double extrapolated_value = y[0] + (y[1] - y[0]) * (i - x[0]) / (x[1] - x[0]); //interpolation formula + int tempValue = static_cast(std::round(extrapolated_value)); if (testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; @@ -819,6 +832,19 @@ void PowerTable::extrapFillTable() { continue; } if(x.size() >= 3){ + + bool validForSpline = true; + for (size_t i = 1; i < x.size(); ++i) { + if (x[i] <= x[i - 1]) { // Make sure x is in ascending order and not a duplicate + validForSpline = false; + break; + } + } + if (!validForSpline) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); + continue; // Skip spline interpolation + } + tk::spline s; s.set_points(x, y, tk::spline::cspline); @@ -873,14 +899,13 @@ void PowerTable::extrapolateDiagonal() { } if (x.size() == 2) { - double slope = (y[1] - y[0]) / (x[1] - x[0]); - double intercept = y[0] - slope * x[0]; for (const auto& it : emptyIndices) { int i = it.first; int j = it.second; - double extrapolated_value = slope * i + intercept; + double extrapolated_value = y[0] + (y[1] - y[0]) * (i - x[0]) / (x[1] - x[0]); //interpolation formula + int tempValue = static_cast(std::round(extrapolated_value)); if (testNeighbors(i, j, tempValue).allNeighborsPassed) { From 2a85005bb6b2843f156b3a66bbd0d00c1e090c24 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Sat, 8 Mar 2025 16:54:20 -0600 Subject: [PATCH 109/451] implemented old fill functions when not enough points --- include/Power_Table.h | 3 + src/Power_Table.cpp | 660 ++++++++++++++++++++++++++---------------- 2 files changed, 409 insertions(+), 254 deletions(-) diff --git a/include/Power_Table.h b/include/Power_Table.h index f96f6dc9..653d5804 100644 --- a/include/Power_Table.h +++ b/include/Power_Table.h @@ -137,6 +137,9 @@ class PowerTable { void fillTable(); void extrapFillTable(); void extrapolateDiagonal(); + void linearInterpolate(); + void linearExtrapolate(); + void linearExtrapolateDiag(); int getNumEntries(); // remove entries with < 1 readings void clean(); diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 8ef4fa73..d6c23b7d 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -371,32 +371,36 @@ void PowerTable::fillTable() { } if (x.size() == 1) { + + this->linearInterpolate(); // If we only have one unique point, we fill the row with that value. Good for keeping data - double singleValue = y.front(); - for (int j : emptyIndices) { - this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); - } + // double singleValue = y.front(); + // for (int j : emptyIndices) { + // this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); + // } continue; } else if (x.size() == 2) { + + this->linearInterpolate(); // If only 2 unique points, we perform linear interpolation - for (int j : emptyIndices) { + // for (int j : emptyIndices) { - if (j < x.front() || j > x.back()) continue; + // if (j < x.front() || j > x.back()) continue; - double interpolated_value = y[0] + (y[1] - y[0]) * (j - x[0]) / (x[1] - x[0]); //interpolation formula + // double interpolated_value = y[0] + (y[1] - y[0]) * (j - x[0]) / (x[1] - x[0]); //interpolation formula - double minValue = *std::min_element(y.begin(), y.end()); - double maxValue = *std::max_element(y.begin(), y.end()); + // double minValue = *std::min_element(y.begin(), y.end()); + // double maxValue = *std::max_element(y.begin(), y.end()); - interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); + // interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); - int tempValue = static_cast(std::round(interpolated_value)); + // int tempValue = static_cast(std::round(interpolated_value)); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } + // if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + // this->tableRow[i].tableEntry[j].targetPosition = tempValue; + // } + // } continue; } else if (x.size() >= 3) { @@ -460,30 +464,34 @@ void PowerTable::fillTable() { } if (x.size() == 1) { - double singleValue = y.front(); - for (int i : emptyIndices) { - this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); - } + + this->linearInterpolate(); + // double singleValue = y.front(); + // for (int i : emptyIndices) { + // this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); + // } continue; } else if (x.size() == 2) { - for (int i : emptyIndices) { + this->linearInterpolate(); - if (i < x.front() || i > x.back()) continue; + // for (int i : emptyIndices) { - double interpolated_value = y[0] + (y[1] - y[0]) * (i - x[0]) / (x[1] - x[0]); //interpolation formula + // if (i < x.front() || i > x.back()) continue; - double minValue = *std::min_element(y.begin(), y.end()); - double maxValue = *std::max_element(y.begin(), y.end()); + // double interpolated_value = y[0] + (y[1] - y[0]) * (i - x[0]) / (x[1] - x[0]); //interpolation formula - interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); + // double minValue = *std::min_element(y.begin(), y.end()); + // double maxValue = *std::max_element(y.begin(), y.end()); - int tempValue = static_cast(std::round(interpolated_value)); + // interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } + // int tempValue = static_cast(std::round(interpolated_value)); + + // if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + // this->tableRow[i].tableEntry[j].targetPosition = tempValue; + // } + // } continue; } else if (x.size() >= 3) { @@ -523,195 +531,6 @@ void PowerTable::fillTable() { } } } -/* -void PowerTable::fillTable() { - // Horizontal Interpolation - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - - std::map unique_xy; - std::vector emptyIndices; - - // Collect data points - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - unique_xy[j] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); // Get all unique points - } else { - emptyIndices.push_back(j); - } - } - - if (unique_xy.size() < 2) continue; // Make sure that we have more than 2 unique points - - std::vector x, y; - for (const auto& it : unique_xy) { // Put the unique values in x and y - x.push_back(it.first); - y.push_back(it.second); - } - - if (x.size() == 1) { // If we only have one unique point, we fill the row with that value. Good for keeping data - double singleValue = y.front(); - for (int j : emptyIndices) { - this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); - } - continue; - } else if (x.size() == 2) { // If only 2 unique points, we perform linear interpolation - for (int j : emptyIndices) { - - double x0 = x[0]; - double y0 = y[0]; - double x1 = x[1]; - double y1 = y[1]; - - double tempValue = y0 + (y1 - y0) * (j - x0) / (x1 - x0); // interpolation formula - double minValue = *std::min_element(y.begin(), y.end()); - double maxValue = *std::max_element(y.begin(), y.end()); - double range = maxValue - minValue; - - double clampingFactor = 0.1 + 0.05 * std::abs((y.back() - y.front()) / (x.back() - x.front())); - - if (j < x.front() || j > x.back()) { // Extrapolate outside the range - tempValue = std::max(minValue - clampingFactor * range, std::min(tempValue, maxValue + clampingFactor * range)); - } - if (j > x.front() && j < x.back()) { // Interpoalte inside the range - tempValue = std::max(minValue, std::min(maxValue, tempValue)); //we stay inside the range of the points - } - - int roundedValue = static_cast(std::round(tempValue)); - - if (this->testNeighbors(i, j, roundedValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = roundedValue; - } - } - continue; - } else if (x.size() >= 3) { // If we have 3 unique points, then we can perform cubic spline - - tk::spline s; // Initialize s for using in cubic spline - s.set_points(x, y, tk::spline::cspline); - - for (int j : emptyIndices) { - - double tempValue = s(j); - double minValue = *std::min_element(y.begin(), y.end()); - double maxValue = *std::max_element(y.begin(), y.end()); - double range = maxValue - minValue; - double clampingFactor = 0.1 + 0.05 * std::abs((y.back() - y.front()) / (x.back() - x.front())); - - if (j < x.front() || j > x.back()) { // Extrapolate outside the range - tempValue = std::max(minValue - clampingFactor * range, std::min(tempValue, maxValue + clampingFactor * range)); - } - if (j > x.front() && j < x.back()) { // Interpoalte inside the range - tempValue = std::max(minValue, std::min(maxValue, tempValue)); //we stay inside the range of the points - } - - int roundedValue = static_cast(std::round(tempValue)); - - if (this->testNeighbors(i, j, roundedValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = roundedValue; - } - } - - } else { // Saftey check just so we don't crash when we don't have a unique point, won't happen. - - SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); - continue; - - } - } - - // Vertical Interpolation - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - - std::map unique_xy; - std::vector emptyIndices; - - // Collect data points - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - unique_xy[i] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); - } else { - emptyIndices.push_back(i); - } - } - - if (unique_xy.size() < 2) continue; - - std::vector x, y; - - for (const auto& it : unique_xy) { - x.push_back(it.first); - y.push_back(it.second); - } - - if (x.size() == 1) { // If we only have one unique point, we fill the row with that value. Good for keeping data - double singleValue = y.front(); - for (int i : emptyIndices) { - this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); - } - continue; - } else if (x.size() == 2) { // If only 2 unique points, we perform linear interpolation - for (int i : emptyIndices) { - - double x0 = x[0]; - double y0 = y[0]; - double x1 = x[1]; - double y1 = y[1]; - - double tempValue = y0 + (y1 - y0) * (i - x0) / (x1 - x0); //interpolation formula - double minValue = *std::min_element(y.begin(), y.end()); - double maxValue = *std::max_element(y.begin(), y.end()); - double range = maxValue - minValue; - double clampingFactor = 0.1 + 0.05 * std::abs((y.back() - y.front()) / (x.back() - x.front())); - - if (i < x.front() || i > x.back()) { // Extrapolate outside the range - tempValue = std::max(minValue - clampingFactor * range, std::min(tempValue, maxValue + clampingFactor * range)); - } - if (i > x.front() && i < x.back()) { // Interpoalte inside the range - tempValue = std::max(minValue, std::min(maxValue, tempValue)); //we stay inside the range of the points - } - - int roundedValue = static_cast(std::round(tempValue)); - - if (this->testNeighbors(i, j, roundedValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = roundedValue; - } - } - continue; - } else if (x.size() >= 3) { // If we have 3 unique points, then we can perform cubic spline - - tk::spline s; // Initialize s for using in cubic spline - s.set_points(x, y, tk::spline::cspline); - - for (int i : emptyIndices) { - - double tempValue = s(i); - double minValue = *std::min_element(y.begin(), y.end()); - double maxValue = *std::max_element(y.begin(), y.end()); - double range = maxValue - minValue; - double clampingFactor = 0.1 + 0.05 * std::abs((y.back() - y.front()) / (x.back() - x.front())); - - if (i < x.front() || i > x.back()) { // Extrapolate outside the range - tempValue = std::max(minValue - clampingFactor * range, std::min(tempValue, maxValue + clampingFactor * range)); - } - if (i > x.front() && i < x.back()) { // Interpoalte inside the range - tempValue = std::max(minValue, std::min(maxValue, tempValue)); //we stay inside the range of the points - } - - int roundedValue = static_cast(std::round(tempValue)); - - if (this->testNeighbors(i, j, roundedValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = roundedValue; - } - } - - } else { // Saftey check just so we don't crash when we don't have a unique point, won't happen. - - SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); - continue; - - } - } -} -*/ void PowerTable::extrapFillTable() { // Horizontal extrapolation @@ -737,24 +556,28 @@ void PowerTable::extrapFillTable() { } if (x.size() == 1) { - int singleValue = static_cast(std::round(y.front())); - for (int j : emptyIndices) { - this->tableRow[i].tableEntry[j].targetPosition = singleValue; - } + + this->linearExtrapolate(); + // int singleValue = static_cast(std::round(y.front())); + // for (int j : emptyIndices) { + // this->tableRow[i].tableEntry[j].targetPosition = singleValue; + // } continue; } if (x.size() == 2) { - for (int j : emptyIndices) { + this->linearExtrapolate(); - double extrapolated_value = y[0] + (y[1] - y[0]) * (j - x[0]) / (x[1] - x[0]); //interpolation formula + // for (int j : emptyIndices) { - int tempValue = static_cast(std::round(extrapolated_value)); - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } + // double extrapolated_value = y[0] + (y[1] - y[0]) * (j - x[0]) / (x[1] - x[0]); //interpolation formula + + // int tempValue = static_cast(std::round(extrapolated_value)); + // if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + // this->tableRow[i].tableEntry[j].targetPosition = tempValue; + // } + // } continue; } if(x.size() >= 3){ @@ -811,24 +634,28 @@ void PowerTable::extrapFillTable() { } if (x.size() == 1) { - int constantValue = static_cast(std::round(y.front())); - for (int i : emptyIndices) { - this->tableRow[i].tableEntry[j].targetPosition = constantValue; - } + + this->linearExtrapolate(); + // int constantValue = static_cast(std::round(y.front())); + // for (int i : emptyIndices) { + // this->tableRow[i].tableEntry[j].targetPosition = constantValue; + // } continue; } if (x.size() == 2) { - for (int i : emptyIndices) { + this->linearExtrapolate(); - double extrapolated_value = y[0] + (y[1] - y[0]) * (i - x[0]) / (x[1] - x[0]); //interpolation formula + // for (int i : emptyIndices) { - int tempValue = static_cast(std::round(extrapolated_value)); - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } + // double extrapolated_value = y[0] + (y[1] - y[0]) * (i - x[0]) / (x[1] - x[0]); //interpolation formula + + // int tempValue = static_cast(std::round(extrapolated_value)); + // if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + // this->tableRow[i].tableEntry[j].targetPosition = tempValue; + // } + // } continue; } if(x.size() >= 3){ @@ -891,31 +718,46 @@ void PowerTable::extrapolateDiagonal() { } if (x.size() == 1) { - int singleValue = static_cast(std::round(y.front())); - for (const auto& it : emptyIndices) { - this->tableRow[it.first].tableEntry[it.second].targetPosition = singleValue; - } + this->linearExtrapolateDiag(); + // int singleValue = static_cast(std::round(y.front())); + // for (const auto& it : emptyIndices) { + // this->tableRow[it.first].tableEntry[it.second].targetPosition = singleValue; + // } continue; } if (x.size() == 2) { - for (const auto& it : emptyIndices) { - int i = it.first; - int j = it.second; + this->linearExtrapolateDiag(); + // for (const auto& it : emptyIndices) { + // int i = it.first; + // int j = it.second; - double extrapolated_value = y[0] + (y[1] - y[0]) * (i - x[0]) / (x[1] - x[0]); //interpolation formula + // double extrapolated_value = y[0] + (y[1] - y[0]) * (i - x[0]) / (x[1] - x[0]); //interpolation formula - int tempValue = static_cast(std::round(extrapolated_value)); + // int tempValue = static_cast(std::round(extrapolated_value)); - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } + // if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + // this->tableRow[i].tableEntry[j].targetPosition = tempValue; + // } + // } continue; } if (x.size() >= 3) { + + bool validForSpline = true; + for (size_t i = 1; i < x.size(); ++i) { + if (x[i] <= x[i - 1]) { // Make sure x is in ascending order and not a duplicate + validForSpline = false; + break; + } + } + if (!validForSpline) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); + continue; + } + tk::spline s; s.set_points(x, y, tk::spline::cspline); @@ -941,6 +783,316 @@ void PowerTable::extrapolateDiagonal() { } } +//Old Fill Function +void PowerTable::linearInterpolate() { + int tempValue = INT16_MIN; + + // Fill each empty cell by linear interpolation + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + // Interpolate horizontally + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest left and right non-empty cells + int left = j - 1; + while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + int right = j + 1; + while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + + if (left >= 0 && right < POWERTABLE_WATT_SIZE) { + // Linear interpolation + tempValue = this->tableRow[i].tableEntry[left].targetPosition + + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) * (j - left) / (right - left); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } + } + + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + // Interpolate vertically + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest top and bottom non-empty cells + int top = i - 1; + while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; + int bottom = i + 1; + while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; + + if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { + // Linear interpolation + tempValue = this->tableRow[top].tableEntry[j].targetPosition + + (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) * (i - top) / (bottom - top); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } + } +} + +void PowerTable::linearExtrapolate() { + // Find the center of the known data + int sumRow = 0, sumCol = 0, count = 0; + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + sumRow += i; + sumCol += j; + count++; + } + } + } + + // prevent divide by zero + if (count == 0) { + return; + } + + int centerRow = sumRow / count; + int centerCol = sumCol / count; + int tempValue = INT16_MIN; + + // Function to extrapolate a single cell based on its neighbors + auto extrapolateCell = [&](int i, int j) { + // Find nearest left non-empty cell + int left = j - 1; + while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + + // Find nearest right non-empty cell + int right = j + 1; + while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + + if (left >= 0 && right < POWERTABLE_WATT_SIZE) { + // Linear extrapolation + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + if (j < left) { + // Extrapolate to the left + tempValue = this->tableRow[i].tableEntry[left].targetPosition - + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } else if (j > right) { + // Extrapolate to the right + tempValue = this->tableRow[i].tableEntry[right].targetPosition + + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } else if (left - 1 >= 0) { + // Only left value available, extrapolate to the right + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { + tempValue = this->tableRow[i].tableEntry[left].targetPosition + + (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (right + 1 < POWERTABLE_WATT_SIZE) { + // Only right value available, extrapolate to the left + if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + tempValue = + this->tableRow[i].tableEntry[right].targetPosition - + (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + }; + + // Extrapolate horizontally and vertically starting from the center + for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { + for (int i = centerRow - distance; i <= centerRow + distance; ++i) { + for (int j = centerCol - distance; j <= centerCol + distance; ++j) { + if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + extrapolateCell(i, j); + } + } + } + } + // Extrapolate each empty cell + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + // Extrapolate horizontally + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest left non-empty cell + int left = j - 1; + while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + + // Find nearest right non-empty cell + int right = j + 1; + while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { + if (left >= 0 && right < POWERTABLE_WATT_SIZE) { + // Linear extrapolation + if (j < left) { + // Extrapolate to the left + tempValue = this->tableRow[i].tableEntry[left].targetPosition - + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + + } else if (j > right) { + // Extrapolate to the right + tempValue = this->tableRow[i].tableEntry[right].targetPosition + + (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (left >= 1) { + // Only left value available, extrapolate to the right + if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { + tempValue = this->tableRow[i].tableEntry[left].targetPosition + + (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (right + 1 < POWERTABLE_WATT_SIZE) { + // Only right value available, extrapolate to the left + if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { + tempValue = this->tableRow[i].tableEntry[right].targetPosition - + (right - j) * + (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } + } + } + } + + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + // Extrapolate vertically + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest top non-empty cell + int top = i - 1; + while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; + + // Find nearest bottom non-empty cell + int bottom = i + 1; + while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; + + if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { + // Linear extrapolation + if (i < top) { + // Extrapolate upwards + tempValue = this->tableRow[top].tableEntry[j].targetPosition - + (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } else if (i > bottom) { + // Extrapolate downwards + tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + + (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (top >= 1) { + // Only top value available, extrapolate downwards + if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { + tempValue = this->tableRow[top].tableEntry[j].targetPosition + + (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } else { + } + } + } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { + // Only bottom value available, extrapolate upwards + if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { + tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - + (bottom - i) * + (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } + } + } +} + +void PowerTable::linearExtrapolateDiag() { + int tempValue = INT16_MIN; + + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + // Find nearest top-left non-empty cell + int topLeftRow = i - 1, topLeftCol = j - 1; + while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { + topLeftRow--; + topLeftCol--; + } + + // Find nearest bottom-right non-empty cell + int bottomRightRow = i + 1, bottomRightCol = j + 1; + while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && + this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { + bottomRightRow++; + bottomRightCol++; + } + + // Perform diagonal extrapolation (top-left to bottom-right) + if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { + tempValue = + this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + + ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / + (bottomRightCol - topLeftCol); + + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + + // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left + if (tempValue == INT16_MIN) { + // Find nearest top-right non-empty cell + int topRightRow = i - 1, topRightCol = j + 1; + while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { + topRightRow--; + topRightCol++; + } + + // Find nearest bottom-left non-empty cell + int bottomLeftRow = i + 1, bottomLeftCol = j - 1; + while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { + bottomLeftRow++; + bottomLeftCol--; + } + + // Perform diagonal extrapolation (top-right to bottom-left) + if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { + tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + + ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * + (j - bottomLeftCol)) / + (topRightCol - bottomLeftCol); + + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } + } + } +} + int PowerTable::getNumEntries() { int ret = 0; From ca3d037cc3acfeda484501ba6b288c353b80fe79 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Mon, 10 Mar 2025 21:11:16 -0500 Subject: [PATCH 110/451] fill functions rework --- include/Power_Table.h | 6 +- src/Power_Table.cpp | 629 +++++++++++++++--------------------------- 2 files changed, 220 insertions(+), 415 deletions(-) diff --git a/include/Power_Table.h b/include/Power_Table.h index 653d5804..d9eb3501 100644 --- a/include/Power_Table.h +++ b/include/Power_Table.h @@ -137,9 +137,9 @@ class PowerTable { void fillTable(); void extrapFillTable(); void extrapolateDiagonal(); - void linearInterpolate(); - void linearExtrapolate(); - void linearExtrapolateDiag(); + // double linearInterpolate(const std::vector& x, const std::vector& y, int j); + // double linearExtrapolate(const std::vector& x, const std::vector& y, int j); + //double linearExtrapolateDiag(); int getNumEntries(); // remove entries with < 1 readings void clean(); diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index d6c23b7d..8623cb7d 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -347,6 +347,48 @@ TestResults PowerTable::testNeighbors(int i, int j, int testValue) { return returnResult; } +double linearInterpolate(const std::vector& x, const std::vector& y, int j) { + // Find the closest two points for interpolation + auto upper = std::upper_bound(x.begin(), x.end(), j); + if (upper == x.end()) return y.back(); + if (upper == x.begin()) return y.front(); + + auto lower = upper - 1; + int x0 = *lower, x1 = *upper; + double y0 = y[lower - x.begin()], y1 = y[upper - x.begin()]; + + // Linear interpolation formula + return y0 + (y1 - y0) * (j - x0) / (x1 - x0); +} + +double linearExtrapolate(const std::vector& x, const std::vector& y, int j) { + // If there's only one point, return it (flat extrapolation) + if (x.size() == 1) return y.front(); + + // Left Extrapolation: j is smaller than the first known x + if (j < x.front()) { + double x0 = x[0], x1 = x[1]; + double y0 = y[0], y1 = y[1]; + double slope = (y1 - y0) / (x1 - x0); + return y0 + slope * (j - x0); // Extend trend to the left + } + + // Right Extrapolation: j is greater than the last known x + if (j > x.back()) { + double x0 = x[x.size() - 2], x1 = x[x.size() - 1]; + double y0 = y[y.size() - 2], y1 = y[y.size() - 1]; + double slope = (y1 - y0) / (x1 - x0); + return y1 + slope * (j - x1); // Extend trend to the right + } + + // Standard Linear Interpolation + auto upper = std::upper_bound(x.begin(), x.end(), j); + auto lower = upper - 1; + double x0 = *lower, x1 = *upper; + double y0 = y[lower - x.begin()], y1 = y[upper - x.begin()]; + return y0 + (y1 - y0) * (j - x0) / (x1 - x0); +} + void PowerTable::fillTable() { // Horizontal Interpolation for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { @@ -371,36 +413,62 @@ void PowerTable::fillTable() { } if (x.size() == 1) { + double singleValue = y.front(); + int x0 = static_cast(x.front()); - this->linearInterpolate(); - // If we only have one unique point, we fill the row with that value. Good for keeping data - // double singleValue = y.front(); - // for (int j : emptyIndices) { - // this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); - // } - continue; - } else if (x.size() == 2) { - - this->linearInterpolate(); - // If only 2 unique points, we perform linear interpolation - - // for (int j : emptyIndices) { - - // if (j < x.front() || j > x.back()) continue; + for (int j : emptyIndices) { + double estimated_value = singleValue; // Default to the only known value + + // Check for neighboring valid values + bool hasLeftNeighbor = (j > 0 && this->tableRow[i].tableEntry[j - 1].targetPosition != INT16_MIN); + bool hasRightNeighbor = (j < POWERTABLE_WATT_SIZE - 1 && this->tableRow[i].tableEntry[j + 1].targetPosition != INT16_MIN); + + if (hasLeftNeighbor && hasRightNeighbor) { + // Blend using left and right known values for better accuracy + estimated_value = (this->tableRow[i].tableEntry[j - 1].targetPosition + + this->tableRow[i].tableEntry[j + 1].targetPosition) / 2.0; + } else if (hasLeftNeighbor) { + estimated_value = this->tableRow[i].tableEntry[j - 1].targetPosition; + } else if (hasRightNeighbor) { + estimated_value = this->tableRow[i].tableEntry[j + 1].targetPosition; + } - // double interpolated_value = y[0] + (y[1] - y[0]) * (j - x[0]) / (x[1] - x[0]); //interpolation formula + int tempValue = static_cast(std::round(estimated_value)); - // double minValue = *std::min_element(y.begin(), y.end()); - // double maxValue = *std::max_element(y.begin(), y.end()); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + continue; + } else if (x.size() == 2) { + double minValue = *std::min_element(y.begin(), y.end()); + double maxValue = *std::max_element(y.begin(), y.end()); + + int x0 = static_cast(x[0]), x1 = static_cast(x[1]); + double y0 = y[0], y1 = y[1]; + + for (int j : emptyIndices) { + double interpolated_value; + + if (j < x0) { + // Extrapolate using y0 (constant extrapolation) + interpolated_value = y0; + } else if (j > x1) { + // Extrapolate using y1 + interpolated_value = y1; + } else { + // Linear interpolation + interpolated_value = y0 + (y1 - y0) * (j - x0) / (x1 - x0); + } - // interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); + interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); - // int tempValue = static_cast(std::round(interpolated_value)); + int tempValue = static_cast(std::round(interpolated_value)); - // if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - // this->tableRow[i].tableEntry[j].targetPosition = tempValue; - // } - // } + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } continue; } else if (x.size() >= 3) { @@ -463,35 +531,64 @@ void PowerTable::fillTable() { y.push_back(static_cast(it.second)); } - if (x.size() == 1) { - - this->linearInterpolate(); - // double singleValue = y.front(); - // for (int i : emptyIndices) { - // this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); - // } - continue; - } else if (x.size() == 2) { - - this->linearInterpolate(); - - // for (int i : emptyIndices) { - - // if (i < x.front() || i > x.back()) continue; - - // double interpolated_value = y[0] + (y[1] - y[0]) * (i - x[0]) / (x[1] - x[0]); //interpolation formula - - // double minValue = *std::min_element(y.begin(), y.end()); - // double maxValue = *std::max_element(y.begin(), y.end()); + if (x.size() == 1) { + double singleValue = y.front(); + int x0 = static_cast(x.front()); + + for (int i : emptyIndices) { + double estimated_value = singleValue; // Default to the only known value + + // Check for neighboring valid values + bool hasLeftNeighbor = (i > 0 && this->tableRow[i - 1].tableEntry[x0].targetPosition != INT16_MIN); + bool hasRightNeighbor = (i < POWERTABLE_CAD_SIZE - 1 && this->tableRow[i + 1].tableEntry[x0].targetPosition != INT16_MIN); + + if (hasLeftNeighbor && hasRightNeighbor) { + // Blend using left and right known values for better accuracy + estimated_value = (this->tableRow[i - 1].tableEntry[x0].targetPosition + + this->tableRow[i + 1].tableEntry[x0].targetPosition) / 2.0; + } else if (hasLeftNeighbor) { + estimated_value = this->tableRow[i - 1].tableEntry[x0].targetPosition; + } else if (hasRightNeighbor) { + estimated_value = this->tableRow[i + 1].tableEntry[x0].targetPosition; + } + + int tempValue = static_cast(std::round(estimated_value)); + + if (this->testNeighbors(i, x0, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[x0].targetPosition = tempValue; + } + } + continue; + } else if (x.size() == 2) { + + double minValue = *std::min_element(y.begin(), y.end()); + double maxValue = *std::max_element(y.begin(), y.end()); + + int x0 = static_cast(x[0]), x1 = static_cast(x[1]); + double y0 = y[0], y1 = y[1]; + + for (int i : emptyIndices) { + double interpolated_value; + + if (i < x0) { + // Extrapolate using y0 (constant extrapolation) + interpolated_value = y0; + } else if (i > x1) { + // Extrapolate using y1 + interpolated_value = y1; + } else { + // Linear interpolation + interpolated_value = y0 + (y1 - y0) * (i - x0) / (x1 - x0); + } - // interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); + interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); - // int tempValue = static_cast(std::round(interpolated_value)); + int tempValue = static_cast(std::round(interpolated_value)); - // if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - // this->tableRow[i].tableEntry[j].targetPosition = tempValue; - // } - // } + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } continue; } else if (x.size() >= 3) { @@ -556,28 +653,39 @@ void PowerTable::extrapFillTable() { } if (x.size() == 1) { - - this->linearExtrapolate(); - // int singleValue = static_cast(std::round(y.front())); - // for (int j : emptyIndices) { - // this->tableRow[i].tableEntry[j].targetPosition = singleValue; - // } - continue; + double singleValue = y.front(); + int x0 = static_cast(x.front()); + + for (int j : emptyIndices) { + double estimated_value = singleValue; // Default to the only known value + + if (j < x0) { + // Left Extrapolation: Assign the first known value (flat extension) + estimated_value = singleValue; + } else if (j > x0) { + // Right Extrapolation: Assign the first known value (flat extension) + estimated_value = singleValue; + } + + int tempValue = static_cast(std::round(estimated_value)); + + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + continue; } if (x.size() == 2) { + for (int j : emptyIndices) { - this->linearExtrapolate(); - - // for (int j : emptyIndices) { - - // double extrapolated_value = y[0] + (y[1] - y[0]) * (j - x[0]) / (x[1] - x[0]); //interpolation formula + double extrapolated_value = linearExtrapolate(x, y, j); - // int tempValue = static_cast(std::round(extrapolated_value)); - // if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - // this->tableRow[i].tableEntry[j].targetPosition = tempValue; - // } - // } + int tempValue = static_cast(std::round(extrapolated_value)); + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } continue; } if(x.size() >= 3){ @@ -634,28 +742,40 @@ void PowerTable::extrapFillTable() { } if (x.size() == 1) { - - this->linearExtrapolate(); - // int constantValue = static_cast(std::round(y.front())); - // for (int i : emptyIndices) { - // this->tableRow[i].tableEntry[j].targetPosition = constantValue; - // } - continue; + double singleValue = y.front(); + int x0 = static_cast(x.front()); + + for (int i : emptyIndices) { + double estimated_value = singleValue; // Default to the only known value + + if (i < x0) { + // Left Extrapolation: Assign the first known value (flat extension) + estimated_value = singleValue; + } else if (i > x0) { + // Right Extrapolation: Assign the first known value (flat extension) + estimated_value = singleValue; + } + + int tempValue = static_cast(std::round(estimated_value)); + + if (this->testNeighbors(i, x0, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[x0].targetPosition = tempValue; + } + } + continue; } if (x.size() == 2) { - this->linearExtrapolate(); - - // for (int i : emptyIndices) { + for (int i : emptyIndices) { - // double extrapolated_value = y[0] + (y[1] - y[0]) * (i - x[0]) / (x[1] - x[0]); //interpolation formula + double extrapolated_value = linearExtrapolate(x, y, i); - // int tempValue = static_cast(std::round(extrapolated_value)); - // if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - // this->tableRow[i].tableEntry[j].targetPosition = tempValue; - // } - // } + int tempValue = static_cast(std::round(extrapolated_value)); + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } continue; } if(x.size() >= 3){ @@ -690,8 +810,6 @@ void PowerTable::extrapFillTable() { } } - - void PowerTable::extrapolateDiagonal() { for (int d = 1 - POWERTABLE_WATT_SIZE; d < POWERTABLE_CAD_SIZE; ++d) { std::map unique_xy; @@ -718,29 +836,27 @@ void PowerTable::extrapolateDiagonal() { } if (x.size() == 1) { - this->linearExtrapolateDiag(); - // int singleValue = static_cast(std::round(y.front())); - // for (const auto& it : emptyIndices) { - // this->tableRow[it.first].tableEntry[it.second].targetPosition = singleValue; - // } + int singleValue = static_cast(std::round(y.front())); + for (const auto& it : emptyIndices) { + this->tableRow[it.first].tableEntry[it.second].targetPosition = singleValue; + } continue; } if (x.size() == 2) { + + for (const auto& it : emptyIndices) { + int i = it.first; + int j = it.second; - this->linearExtrapolateDiag(); - // for (const auto& it : emptyIndices) { - // int i = it.first; - // int j = it.second; - - // double extrapolated_value = y[0] + (y[1] - y[0]) * (i - x[0]) / (x[1] - x[0]); //interpolation formula + double extrapolated_value = linearExtrapolate(x, y, i); - // int tempValue = static_cast(std::round(extrapolated_value)); + int tempValue = static_cast(std::round(extrapolated_value)); - // if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - // this->tableRow[i].tableEntry[j].targetPosition = tempValue; - // } - // } + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } continue; } @@ -783,317 +899,6 @@ void PowerTable::extrapolateDiagonal() { } } -//Old Fill Function -void PowerTable::linearInterpolate() { - int tempValue = INT16_MIN; - - // Fill each empty cell by linear interpolation - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - // Interpolate horizontally - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest left and right non-empty cells - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear interpolation - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) * (j - left) / (right - left); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } - } - - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - // Interpolate vertically - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top and bottom non-empty cells - int top = i - 1; - while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; - int bottom = i + 1; - while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; - - if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { - // Linear interpolation - tempValue = this->tableRow[top].tableEntry[j].targetPosition + - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) * (i - top) / (bottom - top); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } - } -} - -void PowerTable::linearExtrapolate() { - // Find the center of the known data - int sumRow = 0, sumCol = 0, count = 0; - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - sumRow += i; - sumCol += j; - count++; - } - } - } - - // prevent divide by zero - if (count == 0) { - return; - } - - int centerRow = sumRow / count; - int centerCol = sumCol / count; - int tempValue = INT16_MIN; - - // Function to extrapolate a single cell based on its neighbors - auto extrapolateCell = [&](int i, int j) { - // Find nearest left non-empty cell - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - - // Find nearest right non-empty cell - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear extrapolation - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - if (j < left) { - // Extrapolate to the left - tempValue = this->tableRow[i].tableEntry[left].targetPosition - - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } else if (j > right) { - // Extrapolate to the right - tempValue = this->tableRow[i].tableEntry[right].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } else if (left - 1 >= 0) { - // Only left value available, extrapolate to the right - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (right + 1 < POWERTABLE_WATT_SIZE) { - // Only right value available, extrapolate to the left - if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - tempValue = - this->tableRow[i].tableEntry[right].targetPosition - - (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - }; - - // Extrapolate horizontally and vertically starting from the center - for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { - for (int i = centerRow - distance; i <= centerRow + distance; ++i) { - for (int j = centerCol - distance; j <= centerCol + distance; ++j) { - if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - extrapolateCell(i, j); - } - } - } - } - // Extrapolate each empty cell - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - // Extrapolate horizontally - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest left non-empty cell - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - - // Find nearest right non-empty cell - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear extrapolation - if (j < left) { - // Extrapolate to the left - tempValue = this->tableRow[i].tableEntry[left].targetPosition - - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - - } else if (j > right) { - // Extrapolate to the right - tempValue = this->tableRow[i].tableEntry[right].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (left >= 1) { - // Only left value available, extrapolate to the right - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (right + 1 < POWERTABLE_WATT_SIZE) { - // Only right value available, extrapolate to the left - if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[right].targetPosition - - (right - j) * - (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } - } - } - } - - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - // Extrapolate vertically - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top non-empty cell - int top = i - 1; - while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; - - // Find nearest bottom non-empty cell - int bottom = i + 1; - while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; - - if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { - // Linear extrapolation - if (i < top) { - // Extrapolate upwards - tempValue = this->tableRow[top].tableEntry[j].targetPosition - - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } else if (i > bottom) { - // Extrapolate downwards - tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (top >= 1) { - // Only top value available, extrapolate downwards - if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { - tempValue = this->tableRow[top].tableEntry[j].targetPosition + - (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } else { - } - } - } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { - // Only bottom value available, extrapolate upwards - if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { - tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - - (bottom - i) * - (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } - } - } -} - -void PowerTable::linearExtrapolateDiag() { - int tempValue = INT16_MIN; - - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top-left non-empty cell - int topLeftRow = i - 1, topLeftCol = j - 1; - while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { - topLeftRow--; - topLeftCol--; - } - - // Find nearest bottom-right non-empty cell - int bottomRightRow = i + 1, bottomRightCol = j + 1; - while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && - this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { - bottomRightRow++; - bottomRightCol++; - } - - // Perform diagonal extrapolation (top-left to bottom-right) - if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { - tempValue = - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + - ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / - (bottomRightCol - topLeftCol); - - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - - // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left - if (tempValue == INT16_MIN) { - // Find nearest top-right non-empty cell - int topRightRow = i - 1, topRightCol = j + 1; - while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { - topRightRow--; - topRightCol++; - } - - // Find nearest bottom-left non-empty cell - int bottomLeftRow = i + 1, bottomLeftCol = j - 1; - while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { - bottomLeftRow++; - bottomLeftCol--; - } - - // Perform diagonal extrapolation (top-right to bottom-left) - if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { - tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + - ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * - (j - bottomLeftCol)) / - (topRightCol - bottomLeftCol); - - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } - } - } -} - - int PowerTable::getNumEntries() { int ret = 0; for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { From 2632895a7e086f46df2a98b1a54de468e011621d Mon Sep 17 00:00:00 2001 From: Bannus Van der Kloot Date: Tue, 11 Mar 2025 12:16:20 -0400 Subject: [PATCH 111/451] Update CSS loading mechanism --- data/index.html | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/data/index.html b/data/index.html index aaee8a58..9f11734a 100644 --- a/data/index.html +++ b/data/index.html @@ -5,6 +5,7 @@ SmartSpin2k +
@@ -116,15 +117,7 @@

SmartSpin2k Website

.catch(error => console.error('Error:', error)); } - function loadCss() { - const link = document.createElement('link'); - link.rel = 'stylesheet'; - link.href = 'style.css'; - document.head.appendChild(link); - } - window.addEventListener('load', () => { - setTimeout(loadCss, 100); requestConfigValues(); }); From 785cbcb335fb4d7b9f6d26347bc4b45e3777c018 Mon Sep 17 00:00:00 2001 From: Bannus Van der Kloot Date: Tue, 11 Mar 2025 12:21:33 -0400 Subject: [PATCH 112/451] Update all files --- data/bluetoothscanner.html | 9 +-------- data/btsimulator.html | 9 +-------- data/develop.html | 14 +------------- data/hrtowatts.html | 9 +-------- data/settings.html | 9 +-------- data/shift.html | 8 +------- data/status.html | 9 +-------- data/streamfit.html | 10 +--------- 8 files changed, 8 insertions(+), 69 deletions(-) diff --git a/data/bluetoothscanner.html b/data/bluetoothscanner.html index 0715ff43..e38ede7c 100644 --- a/data/bluetoothscanner.html +++ b/data/bluetoothscanner.html @@ -5,6 +5,7 @@ SmartSpin2k Bluetooth Scanner +
@@ -154,15 +155,7 @@

Device Selection

.catch(error => console.error('Error:', error)); } - function loadCss() { - const link = document.createElement('link'); - link.rel = 'stylesheet'; - link.href = 'style.css'; - document.head.appendChild(link); - } - window.addEventListener('load', () => { - setTimeout(loadCss, 100); requestConfigValues(); // Retry loading if values are still default diff --git a/data/btsimulator.html b/data/btsimulator.html index c65db1c2..981e5d21 100644 --- a/data/btsimulator.html +++ b/data/btsimulator.html @@ -117,6 +117,7 @@ margin-top: 0; } + @@ -382,15 +383,7 @@

Simulate ERG Mode

} } - function loadCss() { - const link = document.createElement('link'); - link.rel = 'stylesheet'; - link.href = 'style.css'; - document.head.appendChild(link); - } - window.addEventListener('load', () => { - setTimeout(loadCss, 100); setTimeout(requestConfigValues, 500); }); diff --git a/data/develop.html b/data/develop.html index 36e617cf..1f5a7689 100644 --- a/data/develop.html +++ b/data/develop.html @@ -5,6 +5,7 @@ SmartSpin2k Developer Tools +
@@ -86,18 +87,5 @@

Firmware Update

- - diff --git a/data/hrtowatts.html b/data/hrtowatts.html index c0d7ae26..1ea12df6 100644 --- a/data/hrtowatts.html +++ b/data/hrtowatts.html @@ -5,6 +5,7 @@ SmartSpin2k Heart Rate to Power +
@@ -147,15 +148,7 @@

Hard Session Data

.catch(error => console.error('Error:', error)); } - function loadCss() { - const link = document.createElement('link'); - link.rel = 'stylesheet'; - link.href = 'style.css'; - document.head.appendChild(link); - } - window.addEventListener('load', () => { - setTimeout(loadCss, 100); requestConfigValues(); // Retry loading if values are still default diff --git a/data/settings.html b/data/settings.html index c9bd5368..895efce2 100644 --- a/data/settings.html +++ b/data/settings.html @@ -5,6 +5,7 @@ SmartSpin2k Settings +
@@ -371,15 +372,7 @@

Reset to Defaults?

}, 300); } - function loadCss() { - const link = document.createElement('link'); - link.rel = 'stylesheet'; - link.href = 'style.css'; - document.head.appendChild(link); - } - window.addEventListener('load', () => { - setTimeout(loadCss, 100); startConfigUpdate(); }); diff --git a/data/shift.html b/data/shift.html index 9afc24e6..5ee45f34 100644 --- a/data/shift.html +++ b/data/shift.html @@ -5,6 +5,7 @@ SmartSpin2k Web Shifter +
@@ -81,15 +82,8 @@

Web Shifter

.catch(() => startUpdate()); } - function loadCss() { - const link = document.createElement('link'); - link.rel = 'stylesheet'; - link.href = 'style.css'; - document.head.appendChild(link); - } window.addEventListener('load', () => { - setTimeout(loadCss, 100); setTimeout(requestConfigValues, 500); startUpdate(); }); diff --git a/data/status.html b/data/status.html index c127db7d..e8c0e42b 100644 --- a/data/status.html +++ b/data/status.html @@ -10,6 +10,7 @@ background-color: #03245c } + @@ -234,15 +235,7 @@

Debug Console

} } - function loadCss() { - const link = document.createElement('link'); - link.rel = 'stylesheet'; - link.href = 'style.css'; - document.head.appendChild(link); - } - window.addEventListener('load', () => { - setTimeout(loadCss, 100); requestConfigValues(); setupLogging(); setTimeout(requestRuntimeValues, 200); diff --git a/data/streamfit.html b/data/streamfit.html index fe4b299d..5687eac5 100644 --- a/data/streamfit.html +++ b/data/streamfit.html @@ -5,6 +5,7 @@ SmartSpin2k StreamFit +
@@ -73,16 +74,7 @@

StreamFit

+ window.addEventListener('load', () => { + setTimeout(requestConfigValues, 500); + }); + - - \ No newline at end of file + diff --git a/data/develop.html b/data/develop.html index 1f5a7689..b1b16c15 100644 --- a/data/develop.html +++ b/data/develop.html @@ -4,7 +4,6 @@ SmartSpin2k Developer Tools - diff --git a/data/hrtowatts.html b/data/hrtowatts.html index 1ea12df6..f5ee98bc 100644 --- a/data/hrtowatts.html +++ b/data/hrtowatts.html @@ -4,7 +4,6 @@ SmartSpin2k Heart Rate to Power - diff --git a/data/index.html b/data/index.html index 9f11734a..f9177e48 100644 --- a/data/index.html +++ b/data/index.html @@ -4,7 +4,6 @@ SmartSpin2k - diff --git a/data/settings.html b/data/settings.html index 1ba5d247..316b77c1 100644 --- a/data/settings.html +++ b/data/settings.html @@ -4,291 +4,294 @@ SmartSpin2k Settings - -
- http://github.com/doudar/SmartSpin2k -

Main Index

-

-
Loading
-

-

Settings

-

-

+
+
+ +
+ +
+
Loading
+

Settings

+ +
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

- SSID - - WiFi network name. -
- If it doesn't exist I will create a network with this name. -
-

-
- -
-

- Password - - Password for the WiFi network. - -

-
+
+ +
+

WiFi SSID

+

+ Network name + + WiFi network name. If it doesn't exist I will create a network with this name. + +

+ +
+ +
+

WiFi Password

+

+ Network password + + Password for the WiFi network. + +

+
+ +
-

- MDNS Name - - DNS Name the device will use on the network. - -

-
-
-

- Sim Mode
Shift Amount - - Amount to move stepper per gear shift.
Try to target ~30watt changes. -
-

-
-
- 0 -
- - - -
-

- Sim Mode
Incline Multiplier - - Increase to make incline changes more noticeable. -

- Adjust until hills feel realistic. -
-

-
-
- 0x -
- - - - -
-

ERG Mode
Sensitivity - - Increase to make ERG Mode more aggressive. - -

-
-
- 1.0 -
- - - -
-

Min Bike
Brake Watts - - Set the minimum watts until stepper stops.
0 disables check. -
-

-
-
- 0W -
- - - -
-

Max Bike
Brake Watts - - Set the most watts you've ever seen your bike absorb while you're pedaling.
0 disables check. -
-

-
-
- 0W -
- - - -
-

Stepper Motor
Power - - Amount in milli amps for stepper motor -

- Set to the minimum required to move knob smoothly -
-

-
-
- 0ma -
- - - -
-

Stepper StealthChop - - Make stepper silent at expense of torque - -

-
- -
-

Automatic Updates - - Check for new firmware on boot? - -

-
- -
-

Stepper Motor
Direction - - Change Stepper Direction - -

-
- -
-

Shifter DirectionChange Shifter Direction

-
- -
-

Enable UDP LoggingSending log-messages via UDP Port - 10.000

-
- -
-

PowerTable For PowerUse the PowerTable for Power instead of PM

-
- -
- -
-

-
- -
-

-

Page Help

-

-
- - -
- +
- - Reboot Device +
+
+ + Reboot Device +
+

Reset to Defaults?

This will delete all current settings. This action cannot be undone.

@@ -344,59 +347,44 @@

Reset to Defaults?

}, 1500); } - function requestConfigValues() { - var xhttp = new XMLHttpRequest(); - xhttp.onreadystatechange = function () { - if (this.readyState == 4 && this.status == 200) { - var obj = JSON.parse(this.responseText); - document.getElementById("ssid").value = obj.ssid; - document.getElementById("password").value = obj.password; - document.getElementById("deviceName").value = obj.deviceName; - document.getElementById("shiftStep").value = obj.shiftStep; - document.getElementById("inclineMultiplier").value = obj.inclineMultiplier; - document.getElementById("ERGSensitivity").value = obj.ERGSensitivity; - document.getElementById("stepperPower").value = obj.stepperPower; - document.getElementById("minWatts").value = obj.minWatts; - document.getElementById("maxWatts").value = obj.maxWatts; - document.getElementById("stealthChop").checked = obj.stealthChop; - document.getElementById("autoUpdate").checked = obj.autoUpdate; - document.getElementById("stepperDir").checked = obj.stepperDir; - document.getElementById("shifterDir").checked = obj.shifterDir; - document.getElementById("udpLogEnabled").checked = !!obj.udpLogEnabled; - document.getElementById("pTab4Pwr").checked = !!obj.pTab4Pwr; - updateSlider(document.getElementById("shiftStep").value, document.getElementById("shiftStepValue")); - updateSlider(document.getElementById("inclineMultiplier").value, document.getElementById("inclineMultiplierValue")); - updateSlider(document.getElementById("ERGSensitivity").value, document.getElementById("ERGSensitivityValue")); - updateSlider(document.getElementById("stepperPower").value, document.getElementById("stepperPowerValue")); - updateSlider(document.getElementById("minWatts").value, document.getElementById("minWattsValue")); - updateSlider(document.getElementById("maxWatts").value, document.getElementById("maxWattsValue")); - document.getElementById("loadingWatermark").remove(); - } else { - startConfigUpdate(); - } - }; - xhttp.open("GET", "/configJSON", true); - xhttp.send(); - } - - //define function to load css - var loadCss = function () { - var cssLink = document.createElement('link'); - cssLink.rel = 'stylesheet'; - cssLink.href = 'style.css'; - var head = document.getElementsByTagName('head')[0]; - head.parentNode.insertBefore(cssLink, head); - }; - - //Delay loading css to not swamp webserver - window.addEventListener('load', function () { - setTimeout(loadCss, 100); - startConfigUpdate(); - }, false); + function requestConfigValues() { + var xhttp = new XMLHttpRequest(); + xhttp.onreadystatechange = function () { + if (this.readyState == 4 && this.status == 200) { + var obj = JSON.parse(this.responseText); + document.getElementById("ssid").value = obj.ssid; + document.getElementById("password").value = obj.password; + document.getElementById("deviceName").value = obj.deviceName; + document.getElementById("shiftStep").value = obj.shiftStep; + document.getElementById("inclineMultiplier").value = obj.inclineMultiplier; + document.getElementById("ERGSensitivity").value = obj.ERGSensitivity; + document.getElementById("stepperPower").value = obj.stepperPower; + document.getElementById("minWatts").value = obj.minWatts; + document.getElementById("maxWatts").value = obj.maxWatts; + document.getElementById("stealthChop").checked = obj.stealthChop; + document.getElementById("autoUpdate").checked = obj.autoUpdate; + document.getElementById("stepperDir").checked = obj.stepperDir; + document.getElementById("shifterDir").checked = obj.shifterDir; + document.getElementById("udpLogEnabled").checked = !!obj.udpLogEnabled; + document.getElementById("pTab4Pwr").checked = !!obj.pTab4Pwr; + updateSlider(document.getElementById("shiftStep").value, document.getElementById("shiftStepValue")); + updateSlider(document.getElementById("inclineMultiplier").value, document.getElementById("inclineMultiplierValue")); + updateSlider(document.getElementById("ERGSensitivity").value, document.getElementById("ERGSensitivityValue")); + updateSlider(document.getElementById("stepperPower").value, document.getElementById("stepperPowerValue")); + updateSlider(document.getElementById("minWatts").value, document.getElementById("minWattsValue")); + updateSlider(document.getElementById("maxWatts").value, document.getElementById("maxWattsValue")); + document.getElementById("loadingWatermark").remove(); + } else { + startConfigUpdate(); + } + }; + xhttp.open("GET", "/configJSON", true); + xhttp.send(); + } - function updateSlider(x, valueElement) { - valueElement.innerHTML = x; - } + function updateSlider(x, valueElement) { + valueElement.innerHTML = x; + } function updateSliderAndSend(element, valueElement) { updateSlider(element.value, valueElement); @@ -426,7 +414,7 @@

Reset to Defaults?

params.append(element.name, element.value); } - ['stealthChop', 'autoUpdate', 'stepperDir', 'shifterDir', 'udpLogEnabled'].forEach(id => { + ['stealthChop', 'autoUpdate', 'stepperDir', 'shifterDir', 'udpLogEnabled', 'pTab4Pwr'].forEach(id => { if (document.getElementById(id).checked) { params.append(id, 'true'); } diff --git a/data/shift.html b/data/shift.html index 5ee45f34..16a38cbd 100644 --- a/data/shift.html +++ b/data/shift.html @@ -4,7 +4,6 @@ SmartSpin2k Web Shifter - diff --git a/data/status.html b/data/status.html index e8c0e42b..12ff7996 100644 --- a/data/status.html +++ b/data/status.html @@ -5,11 +5,6 @@ SmartSpin2k Status - diff --git a/data/streamfit.html b/data/streamfit.html index 5687eac5..45466e99 100644 --- a/data/streamfit.html +++ b/data/streamfit.html @@ -4,7 +4,6 @@ SmartSpin2k StreamFit - diff --git a/data/style.css b/data/style.css index 61690d36..fbb4f9bb 100644 --- a/data/style.css +++ b/data/style.css @@ -1,891 +1,147 @@ -header, -nav { - display: flex; - justify-content: space-between; - padding: 1rem 0; -} -.brand, -.menu-item, -html, -nav a { - color: #fff; -} -.brand, -h1 { - font-weight: 700; -} -.menu-item, -.status-group { - background: rgba(3, 37, 76, 0.6); -} -.brand, -.gear-display, -.gear-value { - text-align: center; -} -.debug-console, -.gear-display, -.status-item input { - box-sizing: border-box; - width: 100%; -} -.dev-tool-card, -.menu-item, -a, -nav a { - text-decoration: none; -} -.switch, -.tooltip { - position: relative; -} -html { - font-family: system-ui, -apple-system, sans-serif; - line-height: 1.4; - background: #03245c; - -webkit-text-size-adjust: 100%; -} -body { - margin: 0; - min-height: 100vh; - background: #1167b1; -} -.page-container { - max-width: 1200px; - margin: 0 auto; - padding: 1rem; -} -header { - align-items: center; -} -.brand { - font-size: 2.5rem; - text-shadow: 0 4px 8px rgba(0, 0, 0, 0.5); - margin: 1rem 0; - width: 100%; - letter-spacing: 1px; -} -nav { - align-items: center; - width: 100%; -} -.card-header, -.debug-header { - justify-content: space-between; -} -nav a { - padding: 0.5rem; -} -nav a:hover { - text-decoration: underline; -} -.menu-grid { - display: grid; - gap: 1.5rem; - padding: 2rem 0; - max-width: 800px; - margin: 0 auto; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); -} -.menu-item { - border-radius: 12px; - padding: 1.5rem; - transition: 0.3s; - border: 1px solid rgba(255, 255, 255, 0.1); - box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); - display: block; -} -.shift-button, -.shifter-container, - -.dev-tool-card:hover, -.menu-item:hover { - background: rgba(42, 157, 244, 0.15); - border-color: rgba(42, 157, 244, 0.5); - transform: translateY(-2px); - box-shadow: 0 12px 24px rgba(0, 0, 0, 0.25); -} -.menu-content { - padding: 0.5rem; -} -.menu-content h2 { - margin: 0 0 0.75rem; - font-size: 1.3rem; - font-weight: 600; - color: #2a9df4; -} -.menu-content p { - margin: 0; - opacity: 0.9; - font-size: 1rem; - line-height: 1.5; - color: #fff; -} -a:hover, -h1, -h2 { - color: #2a9df4; -} -h1, -h2 { - margin: 0 0 1rem; -} -h1 { - font-size: 2rem; -} -h2 { - font-size: 1.2rem; - font-weight: 600; -} -p { - margin: 0.5rem 0; - line-height: 1.6; -} -a { - color: #fff; - transition: color 0.2s; -} -.status-group { - border-radius: 12px; - padding: 1.5rem; - margin-bottom: 1.5rem; - border: 1px solid rgba(255, 255, 255, 0.1); -} -.device-status h2, -.status-group h2 { - margin: 0 0 1.5rem; - color: #2a9df4; - font-size: 1.2rem; - border-bottom: 1px solid rgba(42, 157, 244, 0.3); - padding-bottom: 0.5rem; -} -.follow-toggle, -.status-item label { - color: rgba(255, 255, 255, 0.7); - font-size: 0.9rem; -} -.status-grid { - display: grid; - gap: 1rem; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); -} -.status-item { - background: rgba(0, 0, 0, 0.2); - padding: 1rem; - border-radius: 8px; -} -.status-item label { - display: block; - margin-bottom: 0.5rem; - text-transform: uppercase; - letter-spacing: 0.5px; -} -.status-item input { - padding: 0.75rem; - background: rgba(3, 37, 76, 0.6); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 4px; - color: #2a9df4; - font-size: 1.1rem; - font-weight: 500; - text-align: center; -} -.debug-section { - background: rgba(3, 37, 76, 0.6); - border-radius: 12px; - padding: 1.5rem; - margin-top: 2rem; -} -.debug-header { - display: flex; - align-items: center; - margin-bottom: 1rem; -} -.debug-header h2 { - margin: 0; - color: #2a9df4; - font-size: 1.2rem; -} -.follow-toggle { - display: flex; - align-items: center; - gap: 0.5rem; -} -.debug-console { - margin: 0; - padding: 1rem; - background-color: #000; - background-image: radial-gradient(rgba(0, 150, 0, 0.75), #000 120%); - height: 40vh; - resize: both; - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 8px; - color: #fff; - font-family: Inconsolata, monospace; - font-size: 1.1rem; - line-height: 1.4; - overflow: auto; - text-shadow: 0 0 4px rgba(200, 200, 200, 0.5); -} - -.shifter-container { - max-width: 600px; - margin: 2rem auto; - padding: 2rem; - background: rgba(3, 37, 76, 0.6); - border-radius: 12px; -} -.shift-controls { - display: flex; - flex-direction: column; - gap: 2rem; - align-items: center; -} -.shift-button { - width: 100%; - height: 80px; - border: none; - border-radius: 8px; - color: #fff; - font-size: 1.2rem; - font-weight: 600; - cursor: pointer; - transition: 0.2s; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 0.5rem; - padding: 1rem; -} -.scan-button:active, -.shift-button.active, -.shift-button:active { - transform: translateY(1px); - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); -} -.device-select:focus, -.number-input:focus, -input:focus + .slider { - box-shadow: 0 0 0 3px rgba(42, 157, 244, 0.4); -} -.shift-up { - background: linear-gradient(to bottom, #2ecc71, #27ae60); -} -.shift-up:hover { - background: linear-gradient(to bottom, #27ae60, #219a52); -} -.shift-down { - background: linear-gradient(to bottom, #e74c3c, #c0392b); -} -.shift-down:hover { - background: linear-gradient(to bottom, #c0392b, #a93224); -} -.shift-arrow { - font-size: 1.5rem; - line-height: 1; -} -.shift-label { - font-size: 1rem; - text-transform: uppercase; - letter-spacing: 1px; -} -.metric-label, -.reset-defaults-button { - text-transform: uppercase; - letter-spacing: .5px; -} -.gear-display { - background: rgba(0, 0, 0, 0.2); - padding: 2rem; - border-radius: 8px; -} -.gear-label { - display: block; - font-size: 1.2rem; - margin-bottom: 1rem; - color: rgba(255, 255, 255, 0.9); -} -.gear-value { - font-size: 2.5rem; - font-weight: 700; - color: #2a9df4; - background: 0 0; - border: none; - width: 100%; - padding: 0; -} -.input-group { - display: flex; - align-items: center; - gap: 1rem; - margin-bottom: 1.5rem; - background: rgba(0, 0, 0, 0.2); - padding: 2em; - border-radius: 4px; -} -.number-input { - width: 120px; - padding: 0rem; - border: 1px solid rgba(255, 255, 255, 0.2); - border-radius: 4px; - background: rgba(255, 255, 255, 0.1); - color: #fff; - font-size: 1.1rem; - text-align: center; - transition: .3s; -} -.unit, -.value-display { - font-weight: 500; - color: #2a9df4; -} -.device-select:focus, -.number-input:focus { - outline: 0; - border-color: #2a9df4; -} -.number-input::-webkit-inner-spin-button, -.number-input::-webkit-outer-spin-button { - opacity: 1; -} -.unit { - min-width: 40px; -} -.toggle-group { - display: flex; - justify-content: space-between; - align-items: center; - padding: 1rem; - background: rgba(0, 0, 0, 0.2); - border-radius: 4px; -} -.settings-grid { - display: grid; - gap: 2rem; - padding: 1rem 0; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - max-width: 100%; - margin: 0 auto; -} -.settings-section { - background: rgba(255, 255, 255, 0.1); - border-radius: 8px; - padding: 1.5rem; - margin-bottom: 0.5rem; -} -.setting-group { - margin-bottom: 1.5rem; - background: rgba(3, 37, 76, 0.6); - border-radius: 6px; - padding: 1rem; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); - border: 1px solid rgba(255, 255, 255, 0.1); -} -.setting-group input[type="password"], -.setting-group input[type="text"] { - width: 100%; - padding: 0.75rem; - background: rgba(255, 255, 255, 0.219); - border: 1px solid rgba(255, 255, 255, 0.2); - border-radius: 4px; - color: #fff; - font-size: 1rem; - box-sizing: border-box; -} -.slider-group { - display: flex; - align-items: center; - gap: 1rem; - min-height: 60px; - padding: 1rem; - background: rgba(0, 0, 0, 0.2); - border-radius: 4px; - justify-content: center; -} -.slider-container { - flex: 1; - display: flex; - flex-direction: column; - align-items: center; - gap: 0.5rem; - max-width: 400px; - margin: 0 auto; -} -.slider-container input[type="range"] { - width: 100%; -} -.value-display { - display: flex; - align-items: center; - justify-content: center; - margin-bottom: 5.5rem; -} -.value-display span { - margin-left: 20px; -} -.adjust-button { - width: 50px; - height: 50px; - border: none; - background: #03254c; - color: #fff; - border-radius: 50%; - cursor: pointer; - font-size: 1.25rem; - display: flex; - align-items: center; - justify-content: center; - transition: background 0.2s; - flex-shrink: 0; -} -.adjust-button:hover, -input:checked + .slider { - background: #2a9df4; -} -.button-group { - display: flex; - gap: 1rem; - margin-top: 2rem; - justify-content: flex-end; -} -.reset-defaults-button { - font-size: 1.1em; - padding: 1rem 2rem; - border: 2px solid rgba(255, 255, 255, 0.2); - font-weight: 600; - animation: 2s infinite pulse; -} -@keyframes pulse { - 0% { - box-shadow: 0 0 0 0 rgba(220, 53, 69, 0.4); - } - 70% { - box-shadow: 0 0 0 10px rgba(220, 53, 69, 0); - } - 100% { - box-shadow: 0 0 0 0 rgba(220, 53, 69, 0); - } -} -.device-status { - background: rgba(3, 37, 76, 0.8); - border-radius: 8px; - padding: 1.5rem; - margin-bottom: 2rem; -} -.status-grid { - display: grid; - gap: 1.5rem; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); -} -.status-item { - display: flex; - flex-direction: column; - gap: 0.5rem; - font-weight: 500; - color: #2a9df4; -} -.device-select { - width: 100%; - padding: 0.75rem; - border: 1px solid rgba(255, 255, 255, 0.2); - border-radius: 4px; - background: rgba(255, 255, 255, 0.1); - color: #fff; - font-size: 1rem; - cursor: pointer; - transition: 0.2s; -} -.device-select:hover { - background: rgba(255, 255, 255, 0.15); -} -.device-select option { - background: #03245c; - color: #fff; - padding: 0.5rem; -} -.scan-section { - margin-top: 3rem; - text-align: center; - padding: 2rem; - background: rgba(3, 37, 76, 0.6); - border-radius: 8px; -} -.scan-button { - display: flex; - align-items: center; - justify-content: center; - gap: 1rem; - width: 100%; - max-width: 300px; - margin: 0 auto; - padding: 1rem; - background: linear-gradient(to right, #2a9df4, #1b8fe3); - border: none; - border-radius: 8px; - color: #fff; - font-size: 1.1rem; - font-weight: 600; - cursor: pointer; - transition: 0.3s; - box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); -} -.dev-tool-card, -.upload-container { - background: rgba(3, 37, 76, 0.6); - border-radius: 12px; -} -.scan-button:hover { - transform: translateY(-2px); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15); - background: linear-gradient(to right, #1b8fe3, #0d7ac9); -} -.scan-icon { - font-size: 1.5rem; - animation: 2s linear infinite spin; - display: inline-block; -} -@keyframes spin { - from { - transform: rotate(0); - } - to { - transform: rotate(360deg); - } -} -.scan-note { - margin-top: 1.5rem; - font-size: 0.9rem; - color: rgba(255, 255, 255, 0.8); - line-height: 1.6; -} -.scan-note em { - color: #2a9df4; - font-style: normal; -} -.upload-container { - text-align: center; - padding: 2rem; - margin-bottom: 2rem; -} -.file-upload { - display: flex; - flex-direction: column; - align-items: center; - gap: 1rem; - padding: 1rem; - border: 2px dashed rgba(255, 255, 255, 0.2); - border-radius: 8px; - cursor: pointer; - transition: 0.3s; -} -.file-upload:hover { - border-color: #2a9df4; - background: rgba(42, 157, 244, 0.1); -} -.upload-icon { - font-size: 2.5rem; - color: #2a9df4; -} -.file-input, -.switch input { - display: none; -} -.dev-tool-card, -.dev-tools-grid, -.metrics-grid { - display: grid; - gap: 1.5rem; -} -.metrics-grid { - grid-template-columns: repeat(auto-fit, minmax(100px, 0.5fr)); - margin: 0.5rem; -} -.metric-card { - background: rgba(3, 37, 76, 0.6); - border-radius: 8px; - padding: 0.5rem; - text-align: center; - border: 1px solid rgba(255, 255, 255, 0.1); -} -.metric-icon { - font-size: 2rem; - margin-bottom: 0.5rem; -} -.metric-label { - font-size: 0.9rem; - color: rgba(255, 255, 255, 0.7); - margin-bottom: 0.5rem; -} -.metric-value { - font-size: 2rem; - font-weight: 600; - color: #2a9df4; - margin-bottom: 0.25rem; -} -.metric-unit { - font-size: 0.9rem; - color: rgba(255, 255, 255, 0.7); -} -.dev-tools-grid { - padding: 2rem 0; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); -} -.dev-tool-card { - padding: 1.5rem; - color: #fff; - transition: 0.3s; - border: 1px solid rgba(255, 255, 255, 0.1); - box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); - grid-template-columns: auto 1fr auto; - align-items: start; -} -.info-box, -.tool-icon { - background: rgba(42, 157, 244, 0.1); -} -.tool-icon { - font-size: 2rem; - width: 3rem; - height: 3rem; - display: flex; - align-items: center; - justify-content: center; - border-radius: 12px; -} -.tool-content { - flex: 1; -} -.tool-features { - list-style: none; - padding: 0; - margin: 0; - font-size: 0.9rem; - color: rgba(255, 255, 255, 0.7); -} -.tool-features li { - margin-bottom: 0.5rem; - display: flex; - align-items: center; -} -.tool-features li:before { - content: "•"; - color: #2a9df4; - margin-right: 0.5rem; - font-size: 1.2em; -} -.card-arrow { - font-size: 1.5rem; - color: rgba(255, 255, 255, 0.3); - transition: transform 0.2s; -} -.dev-tool-card:hover .card-arrow { - transform: translateX(4px); - color: #2a9df4; -} -.switch { - display: inline-block; - width: 60px; - height: 34px; -} -.switch .slider { - position: absolute; - inset: 0; - background: #03254c; - border-radius: 34px; - transition: 0.4s; -} -.switch .slider:before { - position: absolute; - content: ""; - height: 26px; - width: 26px; - left: 4px; - bottom: 4px; - background: #fff; - border-radius: 50%; - transition: 0.4s; -} -input:checked + .slider:before { - transform: translateX(26px); -} -.tooltip { - border-bottom: 1px dotted rgba(255, 255, 255, 0.3); - cursor: help; -} -.tooltip .tooltiptext { - visibility: hidden; - width: 200px; - background: #03254c; - color: #fff; - text-align: center; - border-radius: 6px; - padding: 0.5rem; - position: absolute; - z-index: 1; - bottom: 125%; - left: 50%; - transform: translateX(-50%); - opacity: 0; - transition: opacity 0.3s; -} -.tooltip:hover .tooltiptext { - visibility: visible; - opacity: 1; -} -.info-box { - border-left: 4px solid #2a9df4; - padding: 1.5rem; - margin-bottom: 2rem; - border-radius: 0 4px 4px 0; -} -.note { - font-style: italic; - color: rgba(255, 255, 255, 0.8); - font-size: 0.9rem; - margin-top: 1rem; -} -.button-container { - text-align: center; - margin-top: 2rem; -} -.primary-button, -.secondary-button, -.warning-button { - padding: 0.75rem 1.5rem; - border: none; - border-radius: 4px; - font-weight: 500; - cursor: pointer; - transition: 0.2s; -} -.primary-button { - background: #2a9df4; - color: #fff; -} -.primary-button:hover { - background: #1b8fe3; -} -.secondary-button, -.status-message.info { - background: rgba(255, 255, 255, 0.1); - color: #fff; -} -.secondary-button:hover { - background: rgba(255, 255, 255, 0.2); -} -.status-message.error, -.warning-button { - background: #dc3545; - color: #fff; -} -.warning-button:hover { - background: #c82333; -} -.status-message { - padding: 1rem; - margin: 1rem 0; - border-radius: 4px; - animation: 0.3s fadeIn; -} -.status-message.success { - background: #28a745; - color: #fff; -} -.watermark { - position: fixed; - top: 50%; - left: 50%; - transform: translate(-50%, -50%) rotate(45deg); - font-size: 5rem; - color: rgba(255, 255, 255, 0.2); - pointer-events: none; - z-index: 0; -} -footer { - margin-top: 2rem; - padding: 1rem 0; - border-top: 1px solid rgba(255, 255, 255, 0.1); - display: flex; - justify-content: space-between; - align-items: center; -} -.dev-links { - display: flex; - align-items: center; - gap: 1rem; -} -.dev-link { - color: rgba(255, 255, 255, 0.7); - font-size: 0.9rem; -} -.separator { - color: rgba(255, 255, 255, 0.3); -} -@keyframes fadeIn { - from { - opacity: 0; - transform: translateY(-10px); - } - to { - opacity: 1; - transform: translateY(0); - } -} -@media (max-width: 768px) { - .button-group, - .input-group { - flex-direction: column; - } - .dev-tools-grid, - .menu-grid, - .metrics-grid, - .status-grid { - grid-template-columns: 1fr; - } - .number-input, - .scan-button { - width: 100%; - } - .settings-section { - padding: 1rem; - } - .adjust-button { - min-width: 32px; - } - .slider-container { - min-width: 0; - } - .input-group { - align-items: stretch; - } - .unit { - text-align: right; - } - .shift-button { - height: 100px; - } - .menu-item, - .metric-card, - .status-group { - padding: 1.25rem; - } - .value-display { - flex-direction: column; - gap: 0.5rem; - text-align: center; - } - .auto-update { - justify-content: center; - } - .debug-console { - height: 50vh; - } - .dev-links { - flex-direction: column; - gap: 0.5rem; - } - .separator { - display: none; - } +:root{--primary:#2a9df4;--bg-dark:#03245c;--bg-main:#1167b1;--bg-overlay:rgba(3,37,76,.6);--bg-item:rgba(0,0,0,.2);--text:#fff;--text-secondary:rgba(255,255,255,.7);--border:rgba(255,255,255,.1);--shadow-sm:0 2px 4px rgba(0,0,0,.1);--shadow-md:0 8px 16px rgba(0,0,0,.2);--shadow-lg:0 12px 24px rgba(0,0,0,.25);--radius-sm:4px;--radius-md:8px;--radius-lg:12px} +html{font-family:system-ui,-apple-system,sans-serif;line-height:1.4;background:var(--bg-dark);color:var(--text);-webkit-text-size-adjust:100%} +body{margin:0;min-height:100vh;background:var(--bg-main)} +h1,h2{color:var(--primary);margin:0 0 1rem} +h1{font-size:2rem;font-weight:700} +h2{font-size:1.2rem;font-weight:600} +p{margin:.5rem 0;line-height:1.6} +a{color:var(--text);text-decoration:none;transition:color .2s} +a:hover,.dev-tool-card:hover .card-arrow{color:var(--primary)} +.page-container{max-width:1200px;margin:0 auto;padding:1rem} +header,nav{display:flex;justify-content:space-between;padding:1rem 0} +header{align-items:center} +nav{align-items:center;width:100%} +.brand{font-size:2.5rem;font-weight:700;text-align:center;text-shadow:0 4px 8px rgba(0,0,0,.5);margin:1rem 0;width:100%;letter-spacing:1px;color:var(--text)} +nav a{color:var(--text);padding:.5rem} +nav a:hover{text-decoration:underline} +.menu-grid,.dev-tools-grid,.metrics-grid{display:grid;gap:1.5rem} +.menu-grid,.dev-tools-grid{padding:2rem 0;grid-template-columns:repeat(auto-fit,minmax(300px,1fr))} +.menu-grid{max-width:800px;margin:0 auto} +.menu-item,.dev-tool-card,.metric-card,.status-group,.shifter-container,.debug-section,.scan-section,.upload-container,.device-status{background:var(--bg-overlay);border-radius:var(--radius-lg);padding:1.5rem;border:1px solid var(--border)} +.menu-item,.dev-tool-card,.shifter-container{transition:.3s;box-shadow:var(--shadow-md);text-decoration:none;display:block} +.device-status{background:rgba(3,37,76,.8)} +.status-group,.device-status,.debug-section,.scan-section,.shifter-container,.upload-container{margin-bottom:1.5rem} +.menu-item:hover,.dev-tool-card:hover,.shifter-container:hover{background:rgba(42,157,244,.15);border-color:rgba(42,157,244,.5);transform:translateY(-2px);box-shadow:var(--shadow-lg)} +.menu-content{padding:.5rem} +.menu-content h2{margin:0 0 .75rem;font-size:1.3rem;font-weight:600;color:var(--primary)} +.menu-content p{margin:0;opacity:.9;font-size:1rem;line-height:1.5;color:var(--text)} +.device-status h2,.status-group h2{margin:0 0 1.5rem;color:var(--primary);font-size:1.2rem;border-bottom:1px solid rgba(42,157,244,.3);padding-bottom:.5rem} +.status-grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(250px,1fr))} +.status-item{background:var(--bg-item);padding:1rem;border-radius:var(--radius-md);display:flex;flex-direction:column;gap:.5rem;font-weight:500;color:var(--primary)} +.status-item label,.follow-toggle,.metric-label{color:var(--text-secondary);font-size:.9rem;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.5px} +.status-item label,.follow-toggle{display:block} +.status-item input,.debug-console,.gear-display{box-sizing:border-box;width:100%} +.status-item input{padding:.75rem;background:var(--bg-overlay);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--primary);font-size:1.1rem;font-weight:500;text-align:center} +.debug-header,.card-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem} +.debug-header h2{margin:0;color:var(--primary);font-size:1.2rem} +.follow-toggle{display:flex;align-items:center;gap:.5rem} +.debug-console{margin:0;padding:1rem;background-color:#000;background-image:radial-gradient(rgba(0,150,0,.75),#000 120%);height:40vh;resize:both;border:1px solid var(--border);border-radius:var(--radius-md);color:var(--text);font-family:Inconsolata,monospace;font-size:1.1rem;line-height:1.4;overflow:auto;text-shadow:0 0 4px rgba(200,200,200,.5)} +.shifter-container{max-width:600px;margin:2rem auto;padding:2rem;transition:.3s} +.shift-controls{display:flex;flex-direction:column;gap:2rem;align-items:center} +.shift-button{width:100%;height:80px;border:none;border-radius:var(--radius-md);color:var(--text);font-size:1.2rem;font-weight:600;cursor:pointer;transition:.2s;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.5rem;padding:1rem;background:var(--bg-overlay)} +.shift-button:active,.shift-button.active,.scan-button:active{transform:translateY(1px);box-shadow:var(--shadow-sm)} +.shift-up{background:linear-gradient(to bottom,#2ecc71,#27ae60)} +.shift-up:hover{background:linear-gradient(to bottom,#27ae60,#219a52)} +.shift-down{background:linear-gradient(to bottom,#e74c3c,#c0392b)} +.shift-down:hover{background:linear-gradient(to bottom,#c0392b,#a93224)} +.shift-arrow{font-size:1.5rem;line-height:1} +.shift-label,.reset-defaults-button,.metric-label{text-transform:uppercase;letter-spacing:.5px} +.shift-label{font-size:1rem;letter-spacing:1px} +.gear-display{background:var(--bg-item);padding:2rem;border-radius:var(--radius-md);text-align:center} +.gear-label{display:block;font-size:1.2rem;margin-bottom:1rem;color:rgba(255,255,255,.9)} +.gear-value{font-size:2.5rem;font-weight:700;color:var(--primary);background:0 0;border:none;width:100%;padding:0;text-align:center} +.input-group,.toggle-group,.slider-group{display:flex;padding:1rem;background:var(--bg-item);border-radius:var(--radius-sm)} +.input-group{align-items:center;gap:1rem;margin-bottom:1.5rem;padding:2em} +.toggle-group{justify-content:space-between;align-items:center} +.slider-group{align-items:center;gap:0.5rem;min-height:60px;justify-content:center;padding:0.75rem;width:auto;box-sizing:border-box} +.number-input,.device-select{padding:.75rem;border:1px solid rgba(255,255,255,.2);border-radius:var(--radius-sm);background:rgba(255,255,255,.1);color:var(--text);font-size:1.1rem;transition:.3s} +.number-input{width:120px;padding:0;text-align:center} +.number-input:focus,.device-select:focus{outline:0;border-color:var(--primary);box-shadow:0 0 0 3px rgba(42,157,244,.4)} +.number-input::-webkit-inner-spin-button,.number-input::-webkit-outer-spin-button{opacity:1} +.unit,.value-display{font-weight:500;color:var(--primary)} +.unit{min-width:40px} +.settings-grid{display:grid;gap:2rem;padding:1rem 0;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));max-width:100%;margin:0 auto} +.settings-section{background:rgba(255,255,255,.1);border-radius:var(--radius-md);padding:1.5rem;margin-bottom:.5rem} +.setting-group{margin-bottom:1.5rem;background:var(--bg-overlay);border-radius:6px;padding:0.75rem;box-shadow:var(--shadow-sm);border:1px solid var(--border);overflow:hidden;box-sizing:border-box} +.setting-group input[type="password"],.setting-group input[type="text"]{width:100%;padding:.75rem;background:rgba(255,255,255,.219);border:1px solid rgba(255,255,255,.2);border-radius:var(--radius-sm);color:var(--text);font-size:1rem;box-sizing:border-box} +.slider-container{flex:1;display:flex;flex-direction:column;align-items:center;gap:.25rem;width:100%;max-width:260px;margin:0 auto;box-sizing:border-box} +.slider-container input[type="range"]{width:100%;max-width:100%} +.value-display{display:flex;align-items:center;justify-content:center;margin-bottom:0.5rem} +.value-display span{margin-left:10px} +.adjust-button{width:36px;height:36px;border:none;background:#03254c;color:var(--text);border-radius:50%;cursor:pointer;font-size:1rem;display:flex;align-items:center;justify-content:center;transition:background .2s;flex-shrink:0} +.adjust-button:hover,input:checked+.slider{background:var(--primary)} +.button-group{display:flex;gap:1rem;margin-top:2rem;justify-content:flex-end} +.reset-defaults-button{font-size:1.1em;padding:1rem 2rem;border:2px solid rgba(255,255,255,.2);font-weight:600;animation:2s infinite pulse} +.primary-button,.secondary-button,.warning-button{padding:.75rem 1.5rem;border:none;border-radius:var(--radius-sm);font-weight:500;cursor:pointer;transition:.2s} +.primary-button{background:var(--primary);color:var(--text)} +.primary-button:hover{background:#1b8fe3} +.secondary-button,.status-message.info{background:rgba(255,255,255,.1);color:var(--text)} +.secondary-button:hover{background:rgba(255,255,255,.2)} +.warning-button,.status-message.error{background:#dc3545;color:var(--text)} +.warning-button:hover{background:#c82333} +.button-container{text-align:center;margin-top:2rem} +.device-select{width:100%;font-size:1rem;cursor:pointer} +.device-select:hover{background:rgba(255,255,255,.15)} +.device-select option{background:var(--bg-dark);color:var(--text);padding:.5rem} +.scan-section{margin-top:3rem;text-align:center} +.scan-button{display:flex;align-items:center;justify-content:center;gap:1rem;width:100%;max-width:300px;margin:0 auto;padding:1rem;background:linear-gradient(to right,var(--primary),#1b8fe3);border:none;border-radius:var(--radius-md);color:var(--text);font-size:1.1rem;font-weight:600;cursor:pointer;transition:.3s;box-shadow:0 4px 6px rgba(0,0,0,.1)} +.scan-button:hover{transform:translateY(-2px);box-shadow:0 6px 12px rgba(0,0,0,.15);background:linear-gradient(to right,#1b8fe3,#0d7ac9)} +.scan-icon{font-size:1.5rem;animation:2s linear infinite spin;display:inline-block} +.scan-note{margin-top:1.5rem;font-size:.9rem;color:rgba(255,255,255,.8);line-height:1.6} +.scan-note em{color:var(--primary);font-style:normal} +.file-upload{display:flex;flex-direction:column;align-items:center;gap:1rem;padding:1rem;border:2px dashed rgba(255,255,255,.2);border-radius:var(--radius-md);cursor:pointer;transition:.3s} +.file-upload:hover{border-color:var(--primary);background:rgba(42,157,244,.1)} +.upload-icon{font-size:2.5rem;color:var(--primary)} +.file-input,.switch input{display:none} +.metrics-grid{grid-template-columns:repeat(auto-fit,minmax(100px,.5fr));margin:.5rem} +.metric-card{padding:.5rem;text-align:center} +.metric-icon{font-size:2rem;margin-bottom:.5rem} +.metric-value{font-size:2rem;font-weight:600;color:var(--primary);margin-bottom:.25rem} +.metric-unit{font-size:.9rem;color:var(--text-secondary)} +.dev-tool-card{color:var(--text);grid-template-columns:auto 1fr auto;align-items:start} +.tool-icon,.info-box{background:rgba(42,157,244,.1)} +.tool-icon{font-size:2rem;width:3rem;height:3rem;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-lg)} +.info-box{border-left:4px solid var(--primary);padding:1.5rem;margin-bottom:2rem;border-radius:0 4px 4px 0} +.tool-content{flex:1} +.tool-features{list-style:none;padding:0;margin:0;font-size:.9rem;color:var(--text-secondary)} +.tool-features li{margin-bottom:.5rem;display:flex;align-items:center} +.tool-features li:before{content:"•";color:var(--primary);margin-right:.5rem;font-size:1.2em} +.card-arrow{font-size:1.5rem;color:rgba(255,255,255,.3);transition:transform .2s} +.dev-tool-card:hover .card-arrow{transform:translateX(4px)} +.switch,.tooltip{position:relative} +.switch{display:inline-block;width:60px;height:34px} +.switch .slider{position:absolute;inset:0;background:#03254c;border-radius:34px;transition:.4s} +.switch .slider:before{position:absolute;content:"";height:26px;width:26px;left:4px;bottom:4px;background:#fff;border-radius:50%;transition:.4s} +input:checked+.slider:before{transform:translateX(26px)} +input:focus+.slider{box-shadow:0 0 0 3px rgba(42,157,244,.4)} +.tooltip{border-bottom:1px dotted rgba(255,255,255,.3);cursor:help} +.tooltip .tooltiptext{visibility:hidden;width:200px;background:#03254c;color:var(--text);text-align:center;border-radius:6px;padding:.5rem;position:absolute;z-index:1;bottom:125%;left:50%;transform:translateX(-50%);opacity:0;transition:opacity .3s} +.tooltip:hover .tooltiptext{visibility:visible;opacity:1} +.status-message{padding:1rem;margin:1rem 0;border-radius:var(--radius-sm);animation:.3s fadeIn} +.status-message.success{background:#28a745;color:var(--text)} +.note{font-style:italic;color:rgba(255,255,255,.8);font-size:.9rem;margin-top:1rem} +.watermark{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(45deg);font-size:5rem;color:rgba(255,255,255,.2);pointer-events:none;z-index:0} +footer{margin-top:2rem;padding:1rem 0;border-top:1px solid var(--border);display:flex;justify-content:space-between;align-items:center} +.dev-links{display:flex;align-items:center;gap:1rem} +.dev-link{color:var(--text-secondary);font-size:.9rem} +.separator{color:rgba(255,255,255,.3)} +@keyframes fadeIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}} +@keyframes spin{from{transform:rotate(0)}to{transform:rotate(360deg)}} +@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(220,53,69,.4)}70%{box-shadow:0 0 0 10px rgba(220,53,69,0)}100%{box-shadow:0 0 0 0 rgba(220,53,69,0)}} +@media (max-width:768px){ +.input-group,.button-group,.value-display,.dev-links{flex-direction:column} +.menu-grid,.status-grid,.metrics-grid,.dev-tools-grid{grid-template-columns:1fr} +.number-input,.scan-button{width:100%} +.settings-section{padding:1rem} +.adjust-button{min-width:32px} +.slider-container{min-width:0} +.input-group{align-items:stretch} +.unit{text-align:right} +.shift-button{height:100px} +.menu-item,.status-group,.metric-card{padding:1.25rem} +.value-display{gap:.5rem;text-align:center} +.auto-update{justify-content:center} +.debug-console{height:50vh} +.dev-links{gap:.5rem} +.separator{display:none} } From fd5fe1c8a413a0d4e693ff031f2383057bb73b82 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Mon, 17 Mar 2025 11:15:34 -0500 Subject: [PATCH 124/451] build settings page with javascript --- data/settings.html | 524 +++++++++++++++++++++------------------------ 1 file changed, 242 insertions(+), 282 deletions(-) diff --git a/data/settings.html b/data/settings.html index 316b77c1..8b6b37fc 100644 --- a/data/settings.html +++ b/data/settings.html @@ -22,264 +22,8 @@

Settings

-
- -
-

WiFi SSID

-

- Network name - - WiFi network name. If it doesn't exist I will create a network with this name. - -

- -
- -
-

WiFi Password

-

- Network password - - Password for the WiFi network. - -

-
- - -
-
- -
-

Device Name

-

- MDNS Name - - DNS Name the device will use on the network. - -

- -
- - -
-

Shift Amount

-

- Sim Mode step size - - Amount to move stepper per gear shift. Try to target ~30watt changes. - -

-
-
- 0 -
-
- - - -
-
-
- -
-

Incline Multiplier

-

- Sim Mode hill effect - - Increase to make incline changes more noticeable. Adjust until hills feel realistic. - -

-
-
- 0x -
-
- - - -
-
-
- -
-

ERG Sensitivity

-

- Response strength - - Increase to make ERG Mode more aggressive. - -

-
-
- 1.0 -
-
- - - -
-
-
- -
-

Min Brake Watts

-

- Bike power floor - - Set the minimum watts until stepper stops. 0 disables check. - -

-
-
- 0W -
-
- - - -
-
-
- -
-

Max Brake Watts

-

- Bike power ceiling - - Set the most watts you've ever seen your bike absorb while you're pedaling. 0 disables check. - -

-
-
- 0W -
-
- - - -
-
-
- -
-

Stepper Motor Power

-

- Motor current - - Amount in milliamps for stepper motor. Set to the minimum required to move knob smoothly. - -

-
-
- 0ma -
-
- - - -
-
-
- - -
-

Stepper StealthChop

-

- Silent operation mode - - Make stepper silent at expense of torque - -

-
- -
-
- -
-

Automatic Updates

-

- OTA firmware - - Check for new firmware on boot? - -

-
- -
-
- -
-

Stepper Motor Direction

-

- Reverse rotation - - Change Stepper Direction - -

-
- -
-
- -
-

Shifter Direction

-

- Reverse input - Change Shifter Direction -

-
- -
-
- -
-

UDP Logging

-

- Network diagnostics - Sending log-messages via UDP Port 10.000 -

-
- -
-
- -
-

PowerTable For Power

-

- Use internal calculation - Use the PowerTable for Power instead of PM -

-
- -
-
+
+
@@ -306,8 +50,222 @@

Reset to Defaults?

Need Help?
- From 1983f6faaefea20f7a2d72ff7f540dc88f56133d Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Mon, 17 Mar 2025 11:17:37 -0500 Subject: [PATCH 125/451] Update CHANGELOG.md Co-Authored-By: Bannus Van der Kloot <1330640+bannus@users.noreply.github.com> --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4303084..ec8f1da7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added ### Changed - +- Multiple html and css improvements. ### Hardware From f9e302c0d613d33facce38a21115bffce400b2af Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Mon, 17 Mar 2025 14:25:13 -0500 Subject: [PATCH 126/451] more spline modificiations --- include/Power_Table.h | 5 +- src/Power_Table.cpp | 964 ++++++++++++++++++++---------------------- 2 files changed, 471 insertions(+), 498 deletions(-) diff --git a/include/Power_Table.h b/include/Power_Table.h index f676008c..e75c336e 100644 --- a/include/Power_Table.h +++ b/include/Power_Table.h @@ -132,10 +132,13 @@ class PowerTable { // Display power table in log void toLog(); - void fillEmptyTable(int outerIndex, const std::vector& emptyIndices, const std::vector& x, const std::vector& y, bool horizontal); + void fillEmptyTable(int outerValue, const std::vector& emptyIndices, const std::vector& x, const std::vector& y, bool horizontal, bool useNaturalSpline); void findTableDirection(bool horizontal); + void extrapFillTableDirection(bool horizontal); + + void extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, const std::vector& x, const std::vector& y, bool horizontal, bool naturalSpline); private: unsigned long lastSaveTime = millis(); TestResults testNeighbors(int i, int j, int value); diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 4b0adf40..6b682649 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -365,67 +365,70 @@ double linearInterpolate(const std::vector& x, const std::vector return std::max(minValue, std::min(maxValue, interpolated_value)); } -// double linearExtrapolate(const std::vector& x, const std::vector& y, double j) { -// if (j < x.front()) { -// double x0 = x[0], x1 = x[1]; -// double y0 = y[0], y1 = y[1]; -// double slope = (y1 - y0) / (x1 - x0); -// return y0 + slope * (j - x0); -// } else if (j > x.back()) { -// double x0 = x[x.size() - 2], x1 = x[x.size() - 1]; -// double y0 = y[y.size() - 2], y1 = y[y.size() - 1]; -// double slope = (y1 - y0) / (x1 - x0); -// return y1 + slope * (j - x1); -// } else { -// // Standard Linear Interpolation -// auto upper = std::upper_bound(x.begin(), x.end(), j); -// auto lower = upper - 1; -// double x0 = *lower, x1 = *upper; -// double y0 = y[lower - x.begin()], y1 = y[upper - x.begin()]; -// return y0 + (y1 - y0) * (j - x0) / (x1 - x0); -// } -// } +double linearExtrapolate(const std::vector& x, const std::vector& y, double j) { + if (j < x.front()) { + double x0 = x[0], x1 = x[1]; + double y0 = y[0], y1 = y[1]; + double slope = (y1 - y0) / (x1 - x0); + return y0 + slope * (j - x0); + } else if (j > x.back()) { + double x0 = x[x.size() - 2], x1 = x[x.size() - 1]; + double y0 = y[y.size() - 2], y1 = y[y.size() - 1]; + double slope = (y1 - y0) / (x1 - x0); + return y1 + slope * (j - x1); + } else { + // Standard Linear Interpolation + auto upper = std::upper_bound(x.begin(), x.end(), j); + auto lower = upper - 1; + double x0 = *lower, x1 = *upper; + double y0 = y[lower - x.begin()], y1 = y[upper - x.begin()]; + return y0 + (y1 - y0) * (j - x0) / (x1 - x0); + } +} class CubicSpline { public: - void set_points(const std::vector& x, const std::vector& y) { + void set_points(const std::vector& x, const std::vector& y, bool natural = true) { + int n = x.size() - 1; + this->x = x; + this->y = y; + h.resize(n); alpha.resize(n + 1); l.resize(n + 1); mu.resize(n + 1); z.resize(n + 1); - c.resize(n + 1); + c.resize(n + 1, 0.0); b.resize(n); d.resize(n); - this->x = x; - this->y = y; - - for (int i = 0; i < n; ++i) - h[i] = x[i + 1] - x[i]; - - double f_prime_start = (y[1] - y[0]) / (x[1] - x[0]); - double f_prime_end = (y[n] - y[n - 1]) / (x[n] - x[n - 1]); - - alpha[0] = (3.0 / h[0]) * (y[1] - y[0]) - 3.0 * f_prime_start; - alpha[n] = 3.0 * f_prime_end - (3.0 / h[n - 1]) * (y[n] - y[n - 1]); + // Compute alpha values for (int i = 1; i < n; ++i) alpha[i] = (3.0 / h[i]) * (y[i + 1] - y[i]) - (3.0 / h[i - 1]) * (y[i] - y[i - 1]); - l[0] = 2.0 * h[0]; - mu[0] = 0.5; - z[0] = alpha[0] / l[0]; + // Boundary conditions + if (natural) { + alpha[0] = alpha[n] = 0.0; + } else { + double f_prime_start = (y[1] - y[0]) / h[0]; + double f_prime_end = (y[n] - y[n - 1]) / h[n - 1]; + alpha[0] = 3.0 * (f_prime_start - (y[1] - y[0]) / h[0]); + alpha[n] = 3.0 * ((y[n] - y[n - 1]) / h[n - 1] - f_prime_end); + } + // Compute l, mu, and z + l[0] = 1.0; + mu[0] = z[0] = 0.0; + for (int i = 1; i < n; ++i) { l[i] = 2.0 * (x[i + 1] - x[i - 1]) - h[i - 1] * mu[i - 1]; mu[i] = h[i] / l[i]; z[i] = (alpha[i] - h[i - 1] * z[i - 1]) / l[i]; } - l[n] = h[n - 1] * (2.0 - mu[n - 1]); - z[n] = (alpha[n] - h[n - 1] * z[n - 1]) / l[n]; - c[n] = z[n]; + l[n] = 1.0; + z[n] = c[n] = 0.0; for (int j = n - 1; j >= 0; --j) { c[j] = z[j] - mu[j] * c[j + 1]; @@ -461,27 +464,38 @@ class CubicSpline { std::vector x, y, h, alpha, l, mu, z, c, b, d; }; +bool shouldUseNaturalSpline(const std::vector& x, const std::vector& y) { + if (x.size() < 3) return true; // Default to natural spline for small data sets + + // Compute approximate first derivatives at endpoints + double startSlope = (y[1] - y[0]) / (x[1] - x[0]); + double endSlope = (y[y.size() - 1] - y[y.size() - 2]) / (x[x.size() - 1] - x[x.size() - 2]); + + // If the slope is significantly changing, use a clamped spline + double slopeThreshold = 10.0; // Adjust based on expected smoothness + if (std::abs(startSlope) > slopeThreshold || std::abs(endSlope) > slopeThreshold) { + return false; // Use clamped spline + } + + return true; // Default to natural spline +} + void PowerTable::fillTable() { - findTableDirection(true); // Horizontal - findTableDirection(false); // Vertical + this->findTableDirection(true); // Horizontal + this->findTableDirection(false); // Vertical } void PowerTable::findTableDirection(bool horizontal) { - - // Check to see if we are going through row or column. int outerSize = horizontal ? POWERTABLE_CAD_SIZE : POWERTABLE_WATT_SIZE; int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; - // Go through outerSize, could be row or column for (int outerValue = 0; outerValue < outerSize; ++outerValue) { std::map unique_xy; std::vector emptyIndices; - // Set a range either the row or column to find points int rangeStart = std::max(0, innerSize / 2 - 10); int rangeEnd = std::min(innerSize, innerSize / 2 + 10); - // Collect unique points for (int innerValue = rangeStart; innerValue < rangeEnd; ++innerValue) { int i = horizontal ? outerValue : innerValue; int j = horizontal ? innerValue : outerValue; @@ -493,7 +507,7 @@ void PowerTable::findTableDirection(bool horizontal) { } } - if (unique_xy.size() < 2) continue; // Skip if not enough points + if (unique_xy.size() < 2) continue; // Skip if not enough points std::vector x, y; for (const auto& it : unique_xy) { @@ -501,34 +515,37 @@ void PowerTable::findTableDirection(bool horizontal) { y.push_back(static_cast(it.second)); } - fillEmptyTable(outerValue, emptyIndices, x, y, horizontal); + // Determine if we should use a natural or clamped spline + bool useNaturalSpline = shouldUseNaturalSpline(x, y); + + // Fill empty table entries using the determined spline type + fillEmptyTable(outerValue, emptyIndices, x, y, horizontal, useNaturalSpline); } } -void PowerTable::fillEmptyTable(int outerValue, const std::vector& emptyIndices, const std::vector& x, const std::vector& y, bool horizontal) { +void PowerTable::fillEmptyTable(int outerValue, const std::vector& emptyIndices, const std::vector& x, const std::vector& y, bool horizontal, bool useNaturalSpline) { int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; - if (x.size() == 1) { // If only one point, fill row with the value + if (x.size() == 1) { // If only one point, fill row with the value double singleValue = y.front(); for (int innerValue : emptyIndices) { int i = horizontal ? outerValue : innerValue; int j = horizontal ? innerValue : outerValue; this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); } - } else if (x.size() == 2) { // If two points, we do linear interpolation + } else if (x.size() == 2) { // If two points, do linear interpolation for (int innerValue : emptyIndices) { int i = horizontal ? outerValue : innerValue; int j = horizontal ? innerValue : outerValue; double interpolated_value = linearInterpolate(x, y, innerValue); - int tempValue = static_cast(std::round(interpolated_value)); if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } - } else if (x.size() >= 3) { // If three points, we do cubic spline interpolation + } else if (x.size() >= 3) { // If three or more points, use cubic spline interpolation bool validForSpline = true; for (size_t i = 1; i < x.size(); ++i) { if (x[i] <= x[i - 1]) { @@ -541,8 +558,9 @@ void PowerTable::fillEmptyTable(int outerValue, const std::vector& emptyInd return; } + // Create and initialize the spline with the desired type (natural or clamped) CubicSpline spline; - spline.set_points(x, y); + spline.set_points(x, y, useNaturalSpline); for (int innerValue : emptyIndices) { int i = horizontal ? outerValue : innerValue; @@ -550,6 +568,10 @@ void PowerTable::fillEmptyTable(int outerValue, const std::vector& emptyInd double interpolated_value = spline.interpolate(innerValue); + double minValue = *std::min_element(y.begin(), y.end()); + double maxValue = *std::max_element(y.begin(), y.end()); + interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); + int tempValue = static_cast(std::round(interpolated_value)); if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { @@ -561,503 +583,451 @@ void PowerTable::fillEmptyTable(int outerValue, const std::vector& emptyInd } } -void PowerTable::extrapFillTable() { - // Find the center of the known data - int sumRow = 0, sumCol = 0, count = 0; - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - sumRow += i; - sumCol += j; - count++; - } - } - } - - // prevent divide by zero - if (count == 0) { - return; - } - - int centerRow = sumRow / count; - int centerCol = sumCol / count; - int tempValue = INT16_MIN; - - // Function to extrapolate a single cell based on its neighbors - auto extrapolateCell = [&](int i, int j) { - // Find nearest left non-empty cell - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - - // Find nearest right non-empty cell - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear extrapolation - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - if (j < left) { - // Extrapolate to the left - tempValue = this->tableRow[i].tableEntry[left].targetPosition - - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } else if (j > right) { - // Extrapolate to the right - tempValue = this->tableRow[i].tableEntry[right].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } else if (left - 1 >= 0) { - // Only left value available, extrapolate to the right - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (right + 1 < POWERTABLE_WATT_SIZE) { - // Only right value available, extrapolate to the left - if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - tempValue = - this->tableRow[i].tableEntry[right].targetPosition - - (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - }; - - // Extrapolate horizontally and vertically starting from the center - for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { - for (int i = centerRow - distance; i <= centerRow + distance; ++i) { - for (int j = centerCol - distance; j <= centerCol + distance; ++j) { - if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - extrapolateCell(i, j); - } - } - } - } - // Extrapolate each empty cell - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - // Extrapolate horizontally - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest left non-empty cell - int left = j - 1; - while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - - // Find nearest right non-empty cell - int right = j + 1; - while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { - if (left >= 0 && right < POWERTABLE_WATT_SIZE) { - // Linear extrapolation - if (j < left) { - // Extrapolate to the left - tempValue = this->tableRow[i].tableEntry[left].targetPosition - - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - - } else if (j > right) { - // Extrapolate to the right - tempValue = this->tableRow[i].tableEntry[right].targetPosition + - (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (left >= 1) { - // Only left value available, extrapolate to the right - if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[left].targetPosition + - (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (right + 1 < POWERTABLE_WATT_SIZE) { - // Only right value available, extrapolate to the left - if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { - tempValue = this->tableRow[i].tableEntry[right].targetPosition - - (right - j) * - (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } - } - } - } - - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - // Extrapolate vertically - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top non-empty cell - int top = i - 1; - while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; - - // Find nearest bottom non-empty cell - int bottom = i + 1; - while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; - - if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { - // Linear extrapolation - if (i < top) { - // Extrapolate upwards - tempValue = this->tableRow[top].tableEntry[j].targetPosition - - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } else if (i > bottom) { - // Extrapolate downwards - tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + - (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (top >= 1) { - // Only top value available, extrapolate downwards - if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { - tempValue = this->tableRow[top].tableEntry[j].targetPosition + - (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } else { - } - } - } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { - // Only bottom value available, extrapolate upwards - if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { - tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - - (bottom - i) * - (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } - } - } -} - -void PowerTable::extrapolateDiagonal() { - int tempValue = INT16_MIN; - - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // Find nearest top-left non-empty cell - int topLeftRow = i - 1, topLeftCol = j - 1; - while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { - topLeftRow--; - topLeftCol--; - } - - // Find nearest bottom-right non-empty cell - int bottomRightRow = i + 1, bottomRightCol = j + 1; - while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && - this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { - bottomRightRow++; - bottomRightCol++; - } - - // Perform diagonal extrapolation (top-left to bottom-right) - if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { - tempValue = - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + - ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / - (bottomRightCol - topLeftCol); - - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - - // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left - if (tempValue == INT16_MIN) { - // Find nearest top-right non-empty cell - int topRightRow = i - 1, topRightCol = j + 1; - while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { - topRightRow--; - topRightCol++; - } - - // Find nearest bottom-left non-empty cell - int bottomLeftRow = i + 1, bottomLeftCol = j - 1; - while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { - bottomLeftRow++; - bottomLeftCol--; - } - - // Perform diagonal extrapolation (top-right to bottom-left) - if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { - tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + - ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * - (j - bottomLeftCol)) / - (topRightCol - bottomLeftCol); - - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } - } - } - } -} - // void PowerTable::extrapFillTable() { -// // Horizontal extrapolation +// // Find the center of the known data +// int sumRow = 0, sumCol = 0, count = 0; // for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// std::map unique_xy; -// std::vector emptyIndices; - -// // Collect data points -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { -// unique_xy[j] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); -// } else { -// emptyIndices.push_back(j); -// } +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { +// sumRow += i; +// sumCol += j; +// count++; // } +// } +// } -// if (unique_xy.size() < 2) continue; // Skip if not enough data - -// std::vector x, y; -// for (const auto& it : unique_xy) { -// x.push_back(static_cast(it.first)); -// y.push_back(static_cast(it.second)); -// } +// // prevent divide by zero +// if (count == 0) { +// return; +// } -// if (x.size() == 1) { -// int singleValue = static_cast(std::round(y.front())); -// for (int j : emptyIndices) { -// this->tableRow[i].tableEntry[j].targetPosition = singleValue; +// int centerRow = sumRow / count; +// int centerCol = sumCol / count; +// int tempValue = INT16_MIN; + +// // Function to extrapolate a single cell based on its neighbors +// auto extrapolateCell = [&](int i, int j) { +// // Find nearest left non-empty cell +// int left = j - 1; +// while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + +// // Find nearest right non-empty cell +// int right = j + 1; +// while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; + +// if (left >= 0 && right < POWERTABLE_WATT_SIZE) { +// // Linear extrapolation +// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { +// if (j < left) { +// // Extrapolate to the left +// tempValue = this->tableRow[i].tableEntry[left].targetPosition - +// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } else if (j > right) { +// // Extrapolate to the right +// tempValue = this->tableRow[i].tableEntry[right].targetPosition + +// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } // } -// continue; // } - -// if (x.size() == 2) { -// for (int j : emptyIndices) { - -// double extrapolated_value = linearExtrapolate(x, y, j); - -// int tempValue = static_cast(std::round(extrapolated_value)); -// if (testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// continue; +// } else if (left - 1 >= 0) { +// // Only left value available, extrapolate to the right +// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { +// tempValue = this->tableRow[i].tableEntry[left].targetPosition + +// (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } // } -// if(x.size() >= 3){ - -// bool validForSpline = true; -// for (size_t i = 1; i < x.size(); ++i) { -// if (x[i] <= x[i - 1]) { // Make sure x is in ascending order and not a duplicate -// validForSpline = false; -// break; -// } +// } else if (right + 1 < POWERTABLE_WATT_SIZE) { +// // Only right value available, extrapolate to the left +// if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { +// tempValue = +// this->tableRow[i].tableEntry[right].targetPosition - +// (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; // } -// if (!validForSpline) { -// SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); -// continue; // Skip spline interpolation +// } +// } +// }; + +// // Extrapolate horizontally and vertically starting from the center +// for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { +// for (int i = centerRow - distance; i <= centerRow + distance; ++i) { +// for (int j = centerCol - distance; j <= centerCol + distance; ++j) { +// if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// extrapolateCell(i, j); // } +// } +// } +// } +// // Extrapolate each empty cell +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// // Extrapolate horizontally +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// // Find nearest left non-empty cell +// int left = j - 1; +// while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; + +// // Find nearest right non-empty cell +// int right = j + 1; +// while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; +// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { +// if (left >= 0 && right < POWERTABLE_WATT_SIZE) { +// // Linear extrapolation +// if (j < left) { +// // Extrapolate to the left +// tempValue = this->tableRow[i].tableEntry[left].targetPosition - +// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } -// CubicSpline spline; -// spline.set_points(x, y); - -// for (int j : emptyIndices) { -// double extrapolated_value = spline.extrapolate(j); -// double minVal = *std::min_element(y.begin(), y.end()); -// double maxVal = *std::max_element(y.begin(), y.end()); -// double range = maxVal - minVal; -// extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); -// int tempValue = static_cast(std::round(extrapolated_value)); -// if (testNeighbors(i, j, tempValue).allNeighborsPassed) { +// } else if (j > right) { +// // Extrapolate to the right +// tempValue = this->tableRow[i].tableEntry[right].targetPosition + +// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } else if (left >= 1) { +// // Only left value available, extrapolate to the right +// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { +// tempValue = this->tableRow[i].tableEntry[left].targetPosition + +// (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { // this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } else if (right + 1 < POWERTABLE_WATT_SIZE) { +// // Only right value available, extrapolate to the left +// if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { +// tempValue = this->tableRow[i].tableEntry[right].targetPosition - +// (right - j) * +// (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } // } +// } // } // } +// } // } -// // Vertical extrapolation // for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// std::map unique_xy; -// std::vector emptyIndices; - -// // Collect data points -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { -// unique_xy[i] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); -// } else { -// emptyIndices.push_back(i); +// // Extrapolate vertically +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// // Find nearest top non-empty cell +// int top = i - 1; +// while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; + +// // Find nearest bottom non-empty cell +// int bottom = i + 1; +// while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; + +// if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { +// // Linear extrapolation +// if (i < top) { +// // Extrapolate upwards +// tempValue = this->tableRow[top].tableEntry[j].targetPosition - +// (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } else if (i > bottom) { +// // Extrapolate downwards +// tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + +// (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } +// } else if (top >= 1) { +// // Only top value available, extrapolate downwards +// if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { +// tempValue = this->tableRow[top].tableEntry[j].targetPosition + +// (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } else { +// } +// } +// } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { +// // Only bottom value available, extrapolate upwards +// if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { +// tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - +// (bottom - i) * +// (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); +// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } // } +// } // } +// } +// } +// } -// if (unique_xy.size() < 2) continue; +// void PowerTable::extrapolateDiagonal() { +// int tempValue = INT16_MIN; -// std::vector x, y; -// for (const auto& it : unique_xy) { -// x.push_back(static_cast(it.first)); -// y.push_back(static_cast(it.second)); -// } +// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { +// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { +// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { +// // Find nearest top-left non-empty cell +// int topLeftRow = i - 1, topLeftCol = j - 1; +// while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { +// topLeftRow--; +// topLeftCol--; +// } -// if (x.size() == 1) { -// int singleValue = static_cast(std::round(y.front())); -// for (int i : emptyIndices) { -// this->tableRow[i].tableEntry[j].targetPosition = singleValue; +// // Find nearest bottom-right non-empty cell +// int bottomRightRow = i + 1, bottomRightCol = j + 1; +// while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && +// this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { +// bottomRightRow++; +// bottomRightCol++; // } -// continue; -// } -// if (x.size() == 2) { +// // Perform diagonal extrapolation (top-left to bottom-right) +// if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { +// tempValue = +// this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + +// ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / +// (bottomRightCol - topLeftCol); -// for (int i : emptyIndices) { +// if (testNeighbors(i, j, tempValue).allNeighborsPassed) { +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// } +// } -// double extrapolated_value = linearExtrapolate(x, y, i); +// // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left +// if (tempValue == INT16_MIN) { +// // Find nearest top-right non-empty cell +// int topRightRow = i - 1, topRightCol = j + 1; +// while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { +// topRightRow--; +// topRightCol++; +// } -// int tempValue = static_cast(std::round(extrapolated_value)); -// if (testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } +// // Find nearest bottom-left non-empty cell +// int bottomLeftRow = i + 1, bottomLeftCol = j - 1; +// while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { +// bottomLeftRow++; +// bottomLeftCol--; // } -// continue; -// } -// if(x.size() >= 3){ -// bool validForSpline = true; -// for (size_t i = 1; i < x.size(); ++i) { -// if (x[i] <= x[i - 1]) { // Make sure x is in ascending order and not a duplicate -// validForSpline = false; -// break; -// } -// } -// if (!validForSpline) { -// SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); -// continue; // Skip spline interpolation -// } +// // Perform diagonal extrapolation (top-right to bottom-left) +// if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { +// tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + +// ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * +// (j - bottomLeftCol)) / +// (topRightCol - bottomLeftCol); -// CubicSpline spline; -// spline.set_points(x, y); - -// for (int i : emptyIndices) { -// double extrapolated_value = spline.extrapolate(i); -// double minVal = *std::min_element(y.begin(), y.end()); -// double maxVal = *std::max_element(y.begin(), y.end()); -// double range = maxVal - minVal; -// extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); -// int tempValue = static_cast(std::round(extrapolated_value)); // if (testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; +// this->tableRow[i].tableEntry[j].targetPosition = tempValue; // } +// } // } // } +// } // } // } -// void PowerTable::extrapolateDiagonal() { -// for (int d = 1 - POWERTABLE_WATT_SIZE; d < POWERTABLE_CAD_SIZE; ++d) { -// std::map unique_xy; -// std::vector> emptyIndices; - -// // Collect known values for this diagonal -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// int j = i - d; -// if (j >= 0 && j < POWERTABLE_WATT_SIZE) { -// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { -// unique_xy[i] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); -// } else { -// emptyIndices.emplace_back(i, j); -// } -// } -// } +void PowerTable::extrapFillTable() { + extrapFillTableDirection(true); // Horizontal + extrapFillTableDirection(false); // Vertical +} -// if (unique_xy.size() < 2) continue; // Skip if not enough data +void PowerTable::extrapFillTableDirection(bool horizontal) { + int outerSize = horizontal ? POWERTABLE_CAD_SIZE : POWERTABLE_WATT_SIZE; + int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; -// std::vector x, y; -// for (const auto& it : unique_xy) { -// x.push_back(it.first); -// y.push_back(it.second); -// } + for (int outerIndex = 0; outerIndex < outerSize; ++outerIndex) { + std::map unique_xy; + std::vector emptyIndices; -// if (x.size() == 1) { -// int singleValue = static_cast(std::round(y.front())); -// for (const auto& it : emptyIndices) { -// this->tableRow[it.first].tableEntry[it.second].targetPosition = singleValue; -// } -// continue; -// } + // Collect data points + for (int innerIndex = 0; innerIndex < innerSize; ++innerIndex) { + int i = horizontal ? outerIndex : innerIndex; + int j = horizontal ? innerIndex : outerIndex; + + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + unique_xy[innerIndex] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); + } else { + emptyIndices.push_back(innerIndex); + } + } + + if (unique_xy.size() < 2) continue; // Skip if not enough data -// if (x.size() == 2) { + std::vector x, y; + for (const auto& it : unique_xy) { + x.push_back(static_cast(it.first)); + y.push_back(static_cast(it.second)); + } + + // Determine spline type (natural or clamped) + bool useNaturalSpline = shouldUseNaturalSpline(x, y); + + // Fill empty table entries using the determined spline type + extrapolateEmptyIndices(outerIndex, emptyIndices, x, y, horizontal, useNaturalSpline); + } +} + +void PowerTable::extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, const std::vector& x, const std::vector& y, bool horizontal, bool naturalSpline) { + int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; + + if (x.size() == 1) { + int singleValue = static_cast(std::round(y.front())); + for (int innerIndex : emptyIndices) { + int i = horizontal ? outerIndex : innerIndex; + int j = horizontal ? innerIndex : outerIndex; + this->tableRow[i].tableEntry[j].targetPosition = singleValue; + } + } else if (x.size() == 2) { + for (int innerIndex : emptyIndices) { + int i = horizontal ? outerIndex : innerIndex; + int j = horizontal ? innerIndex : outerIndex; + + double extrapolated_value = linearExtrapolate(x, y, innerIndex); + int tempValue = static_cast(std::round(extrapolated_value)); + + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (x.size() >= 3) { + bool validForSpline = true; + for (size_t i = 1; i < x.size(); ++i) { + if (x[i] <= x[i - 1]) { + validForSpline = false; + break; + } + } + if (!validForSpline) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); + return; + } + + CubicSpline spline; + spline.set_points(x, y, naturalSpline); // Pass spline type + + for (int innerIndex : emptyIndices) { + int i = horizontal ? outerIndex : innerIndex; + int j = horizontal ? innerIndex : outerIndex; + + double extrapolated_value = spline.extrapolate(innerIndex); + double minVal = *std::min_element(y.begin(), y.end()); + double maxVal = *std::max_element(y.begin(), y.end()); + double range = maxVal - minVal; + extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); + int tempValue = static_cast(std::round(extrapolated_value)); + + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } +} + +void PowerTable::extrapolateDiagonal() { + for (int d = 1 - POWERTABLE_WATT_SIZE; d < POWERTABLE_CAD_SIZE; ++d) { + std::map unique_xy; + std::vector> emptyIndices; + + // Collect known values for this diagonal + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + int j = i - d; + if (j >= 0 && j < POWERTABLE_WATT_SIZE) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + unique_xy[i] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); + } else { + emptyIndices.emplace_back(i, j); + } + } + } + + if (unique_xy.size() < 2) continue; // Skip if not enough data + + std::vector x, y; + for (const auto& it : unique_xy) { + x.push_back(it.first); + y.push_back(it.second); + } + + if (x.size() == 1) { + int singleValue = static_cast(std::round(y.front())); + for (const auto& it : emptyIndices) { + this->tableRow[it.first].tableEntry[it.second].targetPosition = singleValue; + } + continue; + } + + if (x.size() == 2) { -// for (const auto& it : emptyIndices) { -// int i = it.first; -// int j = it.second; + for (const auto& it : emptyIndices) { + int i = it.first; + int j = it.second; -// double extrapolated_value = linearExtrapolate(x, y, i); + double extrapolated_value = linearExtrapolate(x, y, i); -// int tempValue = static_cast(std::round(extrapolated_value)); + int tempValue = static_cast(std::round(extrapolated_value)); -// if (testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// continue; -// } + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + continue; + } -// if (x.size() >= 3) { + if (x.size() >= 3) { -// bool validForSpline = true; -// for (size_t i = 1; i < x.size(); ++i) { -// if (x[i] <= x[i - 1]) { // Make sure x is in ascending order and not a duplicate -// validForSpline = false; -// break; -// } -// } -// if (!validForSpline) { -// SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); -// continue; -// } + bool validForSpline = true; + for (size_t i = 1; i < x.size(); ++i) { + if (x[i] <= x[i - 1]) { // Make sure x is in ascending order and not a duplicate + validForSpline = false; + break; + } + } + if (!validForSpline) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); + continue; + } -// CubicSpline spline; -// spline.set_points(x, y); + CubicSpline spline; + spline.set_points(x, y); -// for (const auto& it : emptyIndices) { -// int i = it.first; -// int j = it.second; + for (const auto& it : emptyIndices) { + int i = it.first; + int j = it.second; -// if (i < 0 || i >= POWERTABLE_CAD_SIZE || j < 0 || j >= POWERTABLE_WATT_SIZE) continue; + if (i < 0 || i >= POWERTABLE_CAD_SIZE || j < 0 || j >= POWERTABLE_WATT_SIZE) continue; -// double extrapolated_value = spline.extrapolate(i); + double extrapolated_value = spline.extrapolate(i); -// double minVal = *std::min_element(y.begin(), y.end()); -// double maxVal = *std::max_element(y.begin(), y.end()); -// double range = maxVal - minVal; -// extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); + double minVal = *std::min_element(y.begin(), y.end()); + double maxVal = *std::max_element(y.begin(), y.end()); + double range = maxVal - minVal; + extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); -// int tempValue = static_cast(std::round(extrapolated_value)); -// if (testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// } -// } + int tempValue = static_cast(std::round(extrapolated_value)); + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } +} int PowerTable::getNumEntries() { int ret = 0; From 3b6cb1a0dd9ac3f26a91034b57ce442c37a4a2a1 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Mon, 17 Mar 2025 15:00:39 -0500 Subject: [PATCH 127/451] diagonal modification --- src/Power_Table.cpp | 196 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 151 insertions(+), 45 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 6b682649..2f0f8ae8 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -485,40 +485,48 @@ void PowerTable::fillTable() { this->findTableDirection(false); // Vertical } -void PowerTable::findTableDirection(bool horizontal) { - int outerSize = horizontal ? POWERTABLE_CAD_SIZE : POWERTABLE_WATT_SIZE; +void PowerTable::findTableDirection(bool horizontal) { + int outerSize = horizontal ? POWERTABLE_CAD_SIZE : POWERTABLE_WATT_SIZE; int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; + std::vector> unique_xy; + std::vector emptyIndices; + std::vector x, y; + for (int outerValue = 0; outerValue < outerSize; ++outerValue) { - std::map unique_xy; - std::vector emptyIndices; + unique_xy.clear(); + emptyIndices.clear(); + x.clear(); + y.clear(); - int rangeStart = std::max(0, innerSize / 2 - 10); + int rangeStart = std::max(0, innerSize / 2 - 10); int rangeEnd = std::min(innerSize, innerSize / 2 + 10); for (int innerValue = rangeStart; innerValue < rangeEnd; ++innerValue) { int i = horizontal ? outerValue : innerValue; int j = horizontal ? innerValue : outerValue; - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - unique_xy[innerValue] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); + int targetPos = this->tableRow[i].tableEntry[j].targetPosition; + if (targetPos != INT16_MIN) { + unique_xy.emplace_back(innerValue, static_cast(targetPos)); } else { - emptyIndices.push_back(innerValue); + // Store a subset of empty indices (every 5th) + if (emptyIndices.empty() || innerValue - emptyIndices.back() >= 5) { + emptyIndices.push_back(innerValue); + } } } - if (unique_xy.size() < 2) continue; // Skip if not enough points + if (unique_xy.size() < 2) continue; - std::vector x, y; - for (const auto& it : unique_xy) { - x.push_back(static_cast(it.first)); - y.push_back(static_cast(it.second)); + std::sort(unique_xy.begin(), unique_xy.end()); + + for (const auto& [xi, yi] : unique_xy) { + x.push_back(xi); + y.push_back(yi); } - // Determine if we should use a natural or clamped spline bool useNaturalSpline = shouldUseNaturalSpline(x, y); - - // Fill empty table entries using the determined spline type fillEmptyTable(outerValue, emptyIndices, x, y, horizontal, useNaturalSpline); } } @@ -852,9 +860,15 @@ void PowerTable::extrapFillTableDirection(bool horizontal) { int outerSize = horizontal ? POWERTABLE_CAD_SIZE : POWERTABLE_WATT_SIZE; int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; + std::vector> unique_xy; + std::vector emptyIndices; + std::vector x, y; + for (int outerIndex = 0; outerIndex < outerSize; ++outerIndex) { - std::map unique_xy; - std::vector emptyIndices; + unique_xy.clear(); + emptyIndices.clear(); + x.clear(); + y.clear(); // Collect data points for (int innerIndex = 0; innerIndex < innerSize; ++innerIndex) { @@ -862,7 +876,7 @@ void PowerTable::extrapFillTableDirection(bool horizontal) { int j = horizontal ? innerIndex : outerIndex; if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - unique_xy[innerIndex] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); + unique_xy.emplace_back(innerIndex, static_cast(this->tableRow[i].tableEntry[j].targetPosition)); } else { emptyIndices.push_back(innerIndex); } @@ -870,7 +884,8 @@ void PowerTable::extrapFillTableDirection(bool horizontal) { if (unique_xy.size() < 2) continue; // Skip if not enough data - std::vector x, y; + std::sort(unique_xy.begin(), unique_xy.end()); + for (const auto& it : unique_xy) { x.push_back(static_cast(it.first)); y.push_back(static_cast(it.second)); @@ -941,16 +956,20 @@ void PowerTable::extrapolateEmptyIndices(int outerIndex, const std::vector& } void PowerTable::extrapolateDiagonal() { - for (int d = 1 - POWERTABLE_WATT_SIZE; d < POWERTABLE_CAD_SIZE; ++d) { - std::map unique_xy; - std::vector> emptyIndices; + std::vector> unique_xy; // Use vector for memory efficiency + std::vector> emptyIndices; + + // Iterate over different diagonals + for (int sum = 0; sum < POWERTABLE_CAD_SIZE + POWERTABLE_WATT_SIZE - 1; ++sum) { + unique_xy.clear(); + emptyIndices.clear(); - // Collect known values for this diagonal + // Collect known values for this diagonal (sum of indices is constant) for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - int j = i - d; + int j = sum - i; if (j >= 0 && j < POWERTABLE_WATT_SIZE) { if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - unique_xy[i] = static_cast(this->tableRow[i].tableEntry[j].targetPosition); + unique_xy.emplace_back(i, static_cast(this->tableRow[i].tableEntry[j].targetPosition)); } else { emptyIndices.emplace_back(i, j); } @@ -959,6 +978,8 @@ void PowerTable::extrapolateDiagonal() { if (unique_xy.size() < 2) continue; // Skip if not enough data + std::sort(unique_xy.begin(), unique_xy.end()); // Sort by the 'x' coordinate (i) + std::vector x, y; for (const auto& it : unique_xy) { x.push_back(it.first); @@ -974,38 +995,36 @@ void PowerTable::extrapolateDiagonal() { } if (x.size() == 2) { - for (const auto& it : emptyIndices) { int i = it.first; int j = it.second; - double extrapolated_value = linearExtrapolate(x, y, i); - + double extrapolated_value = linearExtrapolate(x, y, i); + int tempValue = static_cast(std::round(extrapolated_value)); if (testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } - continue; + continue; } if (x.size() >= 3) { + bool validForSpline = true; + for (size_t k = 1; k < x.size(); ++k) { + if (x[k] <= x[k - 1]) { + validForSpline = false; + break; + } + } + if (!validForSpline) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected for diagonal!"); + continue; + } - bool validForSpline = true; - for (size_t i = 1; i < x.size(); ++i) { - if (x[i] <= x[i - 1]) { // Make sure x is in ascending order and not a duplicate - validForSpline = false; - break; - } - } - if (!validForSpline) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); - continue; - } - - CubicSpline spline; - spline.set_points(x, y); + CubicSpline spline; + spline.set_points(x, y); for (const auto& it : emptyIndices) { int i = it.first; @@ -1013,7 +1032,7 @@ void PowerTable::extrapolateDiagonal() { if (i < 0 || i >= POWERTABLE_CAD_SIZE || j < 0 || j >= POWERTABLE_WATT_SIZE) continue; - double extrapolated_value = spline.extrapolate(i); + double extrapolated_value = spline.extrapolate(i); double minVal = *std::min_element(y.begin(), y.end()); double maxVal = *std::max_element(y.begin(), y.end()); @@ -1027,6 +1046,93 @@ void PowerTable::extrapolateDiagonal() { } } } + + // Iterate over other set of diagonals (where difference of indices is constant) + // for (int diff = POWERTABLE_CAD_SIZE - 1; diff >= 1 - POWERTABLE_WATT_SIZE; --diff) { + // unique_xy.clear(); + // emptyIndices.clear(); + + // for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + // int j = i - diff; + // if (j >= 0 && j < POWERTABLE_WATT_SIZE) { + // if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + // unique_xy.emplace_back(i, static_cast(this->tableRow[i].tableEntry[j].targetPosition)); + // } else { + // emptyIndices.emplace_back(i, j); + // } + // } + // } + + // if (unique_xy.size() < 2) continue; + + // std::sort(unique_xy.begin(), unique_xy.end()); + + // std::vector x, y; + // for (const auto& it : unique_xy) { + // x.push_back(it.first); + // y.push_back(it.second); + // } + + // if (x.size() == 1) { + // int singleValue = static_cast(std::round(y.front())); + // for (const auto& it : emptyIndices) { + // this->tableRow[it.first].tableEntry[it.second].targetPosition = singleValue; + // } + // continue; + // } + + // if (x.size() == 2) { + // for (const auto& it : emptyIndices) { + // int i = it.first; + // int j = it.second; + + // double extrapolated_value = linearExtrapolate(x, y, i); + + // int tempValue = static_cast(std::round(extrapolated_value)); + + // if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + // this->tableRow[i].tableEntry[j].targetPosition = tempValue; + // } + // } + // continue; + // } + + // if (x.size() >= 3) { + // bool validForSpline = true; + // for (size_t k = 1; k < x.size(); ++k) { + // if (x[k] <= x[k - 1]) { + // validForSpline = false; + // break; + // } + // } + // if (!validForSpline) { + // SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected for diagonal!"); + // continue; + // } + + // CubicSpline spline; + // spline.set_points(x, y); + + // for (const auto& it : emptyIndices) { + // int i = it.first; + // int j = it.second; + + // if (i < 0 || i >= POWERTABLE_CAD_SIZE || j < 0 || j >= POWERTABLE_WATT_SIZE) continue; + + // double extrapolated_value = spline.extrapolate(i); + + // double minVal = *std::min_element(y.begin(), y.end()); + // double maxVal = *std::max_element(y.begin(), y.end()); + // double range = maxVal - minVal; + // extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); + + // int tempValue = static_cast(std::round(extrapolated_value)); + // if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + // this->tableRow[i].tableEntry[j].targetPosition = tempValue; + // } + // } + // } + // } } int PowerTable::getNumEntries() { From d6b0c4062e03403736a1c37cc287789203d94cc7 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Mon, 17 Mar 2025 16:57:32 -0500 Subject: [PATCH 128/451] small calculation changes --- src/Power_Table.cpp | 348 +++++++++++++++++++++++--------------------- 1 file changed, 182 insertions(+), 166 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 2f0f8ae8..b948065e 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -388,54 +388,57 @@ double linearExtrapolate(const std::vector& x, const std::vector class CubicSpline { public: - void set_points(const std::vector& x, const std::vector& y, bool natural = true) { - - int n = x.size() - 1; - this->x = x; - this->y = y; - - h.resize(n); - alpha.resize(n + 1); - l.resize(n + 1); - mu.resize(n + 1); - z.resize(n + 1); - c.resize(n + 1, 0.0); - b.resize(n); - d.resize(n); - - // Compute alpha values - for (int i = 1; i < n; ++i) - alpha[i] = (3.0 / h[i]) * (y[i + 1] - y[i]) - (3.0 / h[i - 1]) * (y[i] - y[i - 1]); - - // Boundary conditions - if (natural) { - alpha[0] = alpha[n] = 0.0; - } else { - double f_prime_start = (y[1] - y[0]) / h[0]; - double f_prime_end = (y[n] - y[n - 1]) / h[n - 1]; - alpha[0] = 3.0 * (f_prime_start - (y[1] - y[0]) / h[0]); - alpha[n] = 3.0 * ((y[n] - y[n - 1]) / h[n - 1] - f_prime_end); - } - - // Compute l, mu, and z - l[0] = 1.0; - mu[0] = z[0] = 0.0; - - for (int i = 1; i < n; ++i) { - l[i] = 2.0 * (x[i + 1] - x[i - 1]) - h[i - 1] * mu[i - 1]; - mu[i] = h[i] / l[i]; - z[i] = (alpha[i] - h[i - 1] * z[i - 1]) / l[i]; - } - - l[n] = 1.0; - z[n] = c[n] = 0.0; - - for (int j = n - 1; j >= 0; --j) { - c[j] = z[j] - mu[j] * c[j + 1]; - b[j] = (y[j + 1] - y[j]) / h[j] - h[j] * (c[j + 1] + 2.0 * c[j]) / 3.0; - d[j] = (c[j + 1] - c[j]) / (3.0 * h[j]); - } - } + void set_points(const std::vector& x, const std::vector& y, bool natural = true) { + int n = x.size() - 1; + this->x = x; + this->y = y; + + h.resize(n); + alpha.resize(n + 1); + l.resize(n + 1); + mu.resize(n + 1); + z.resize(n + 1); + c.resize(n + 1, 0.0); + b.resize(n); + d.resize(n); + + // Compute h values + for (int i = 0; i < n; ++i) + h[i] = x[i + 1] - x[i]; + + // Compute alpha values + for (int i = 1; i < n; ++i) + alpha[i] = (3.0 / h[i]) * (y[i + 1] - y[i]) - (3.0 / h[i - 1]) * (y[i] - y[i - 1]); + + // Boundary conditions + if (natural) { + alpha[0] = alpha[n] = 0.0; + } else { + double f_prime_start = (y[1] - y[0]) / h[0]; + double f_prime_end = (y[n] - y[n - 1]) / h[n - 1]; + alpha[0] = 3.0 * ( (y[1] - y[0]) / h[0] - f_prime_start ); + alpha[n] = 3.0 * ( f_prime_end - (y[n] - y[n - 1]) / h[n - 1] ); + } + + // Compute l, mu, and z + l[0] = 1.0; + mu[0] = z[0] = 0.0; + + for (int i = 1; i < n; ++i) { + l[i] = 2.0 * (x[i + 1] - x[i - 1]) - h[i - 1] * mu[i - 1]; + mu[i] = h[i] / l[i]; + z[i] = (alpha[i] - h[i - 1] * z[i - 1]) / l[i]; + } + + l[n] = 1.0; + z[n] = c[n] = 0.0; + + for (int j = n - 1; j >= 0; --j) { + c[j] = z[j] - mu[j] * c[j + 1]; + b[j] = (y[j + 1] - y[j]) / h[j] - h[j] * (c[j + 1] + 2.0 * c[j]) / 3.0; + d[j] = (c[j + 1] - c[j]) / (3.0 * h[j]); + } + } double interpolate(double x_val) const { if (x_val < x.front() || x_val > x.back()) { @@ -469,14 +472,27 @@ bool shouldUseNaturalSpline(const std::vector& x, const std::vector slopeThreshold || std::abs(endSlope) > slopeThreshold) { return false; // Use clamped spline } + // Second derivative (curvature) check for smoothness + double secondDerivativeStart = (y[2] - 2 * y[1] + y[0]) / ((x[1] - x[0]) * (x[2] - x[1])); + double secondDerivativeEnd = (y[y.size() - 1] - 2 * y[y.size() - 2] + y[y.size() - 3]) / + ((x[y.size() - 2] - x[y.size() - 3]) * (x[y.size() - 1] - x[y.size() - 2])); + + double curvatureThreshold = 1.0; // Adjust based on expected smoothness + if (std::abs(secondDerivativeStart) > curvatureThreshold || std::abs(secondDerivativeEnd) > curvatureThreshold) { + return false; // Use clamped spline + } + return true; // Default to natural spline } @@ -903,53 +919,53 @@ void PowerTable::extrapolateEmptyIndices(int outerIndex, const std::vector& int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; if (x.size() == 1) { - int singleValue = static_cast(std::round(y.front())); - for (int innerIndex : emptyIndices) { - int i = horizontal ? outerIndex : innerIndex; - int j = horizontal ? innerIndex : outerIndex; - this->tableRow[i].tableEntry[j].targetPosition = singleValue; - } + int singleValue = static_cast(std::round(y.front())); + for (int innerIndex : emptyIndices) { + int i = horizontal ? outerIndex : innerIndex; + int j = horizontal ? innerIndex : outerIndex; + this->tableRow[i].tableEntry[j].targetPosition = singleValue; + } } else if (x.size() == 2) { - for (int innerIndex : emptyIndices) { - int i = horizontal ? outerIndex : innerIndex; - int j = horizontal ? innerIndex : outerIndex; + for (int innerIndex : emptyIndices) { + int i = horizontal ? outerIndex : innerIndex; + int j = horizontal ? innerIndex : outerIndex; - double extrapolated_value = linearExtrapolate(x, y, innerIndex); - int tempValue = static_cast(std::round(extrapolated_value)); + double extrapolated_value = linearExtrapolate(x, y, innerIndex); + int tempValue = static_cast(std::round(extrapolated_value)); - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } } else if (x.size() >= 3) { bool validForSpline = true; for (size_t i = 1; i < x.size(); ++i) { - if (x[i] <= x[i - 1]) { - validForSpline = false; - break; - } + if (x[i] <= x[i - 1]) { + validForSpline = false; + break; + } } if (!validForSpline) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); - return; + SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); + return; } CubicSpline spline; spline.set_points(x, y, naturalSpline); // Pass spline type for (int innerIndex : emptyIndices) { - int i = horizontal ? outerIndex : innerIndex; - int j = horizontal ? innerIndex : outerIndex; + int i = horizontal ? outerIndex : innerIndex; + int j = horizontal ? innerIndex : outerIndex; - double extrapolated_value = spline.extrapolate(innerIndex); - double minVal = *std::min_element(y.begin(), y.end()); - double maxVal = *std::max_element(y.begin(), y.end()); - double range = maxVal - minVal; - extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); - int tempValue = static_cast(std::round(extrapolated_value)); + double extrapolated_value = spline.extrapolate(innerIndex); + double minVal = *std::min_element(y.begin(), y.end()); + double maxVal = *std::max_element(y.begin(), y.end()); + double range = maxVal - minVal; + extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); + int tempValue = static_cast(std::round(extrapolated_value)); if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } } @@ -1048,91 +1064,91 @@ void PowerTable::extrapolateDiagonal() { } // Iterate over other set of diagonals (where difference of indices is constant) - // for (int diff = POWERTABLE_CAD_SIZE - 1; diff >= 1 - POWERTABLE_WATT_SIZE; --diff) { - // unique_xy.clear(); - // emptyIndices.clear(); - - // for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - // int j = i - diff; - // if (j >= 0 && j < POWERTABLE_WATT_SIZE) { - // if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - // unique_xy.emplace_back(i, static_cast(this->tableRow[i].tableEntry[j].targetPosition)); - // } else { - // emptyIndices.emplace_back(i, j); - // } - // } - // } - - // if (unique_xy.size() < 2) continue; - - // std::sort(unique_xy.begin(), unique_xy.end()); - - // std::vector x, y; - // for (const auto& it : unique_xy) { - // x.push_back(it.first); - // y.push_back(it.second); - // } - - // if (x.size() == 1) { - // int singleValue = static_cast(std::round(y.front())); - // for (const auto& it : emptyIndices) { - // this->tableRow[it.first].tableEntry[it.second].targetPosition = singleValue; - // } - // continue; - // } - - // if (x.size() == 2) { - // for (const auto& it : emptyIndices) { - // int i = it.first; - // int j = it.second; - - // double extrapolated_value = linearExtrapolate(x, y, i); - - // int tempValue = static_cast(std::round(extrapolated_value)); - - // if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - // this->tableRow[i].tableEntry[j].targetPosition = tempValue; - // } - // } - // continue; - // } - - // if (x.size() >= 3) { - // bool validForSpline = true; - // for (size_t k = 1; k < x.size(); ++k) { - // if (x[k] <= x[k - 1]) { - // validForSpline = false; - // break; - // } - // } - // if (!validForSpline) { - // SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected for diagonal!"); - // continue; - // } - - // CubicSpline spline; - // spline.set_points(x, y); - - // for (const auto& it : emptyIndices) { - // int i = it.first; - // int j = it.second; - - // if (i < 0 || i >= POWERTABLE_CAD_SIZE || j < 0 || j >= POWERTABLE_WATT_SIZE) continue; - - // double extrapolated_value = spline.extrapolate(i); - - // double minVal = *std::min_element(y.begin(), y.end()); - // double maxVal = *std::max_element(y.begin(), y.end()); - // double range = maxVal - minVal; - // extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); - - // int tempValue = static_cast(std::round(extrapolated_value)); - // if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - // this->tableRow[i].tableEntry[j].targetPosition = tempValue; - // } - // } - // } - // } + for (int diff = POWERTABLE_CAD_SIZE - 1; diff >= 1 - POWERTABLE_WATT_SIZE; --diff) { + unique_xy.clear(); + emptyIndices.clear(); + + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + int j = i - diff; + if (j >= 0 && j < POWERTABLE_WATT_SIZE) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + unique_xy.emplace_back(i, static_cast(this->tableRow[i].tableEntry[j].targetPosition)); + } else { + emptyIndices.emplace_back(i, j); + } + } + } + + if (unique_xy.size() < 2) continue; + + std::sort(unique_xy.begin(), unique_xy.end()); + + std::vector x, y; + for (const auto& it : unique_xy) { + x.push_back(it.first); + y.push_back(it.second); + } + + if (x.size() == 1) { + int singleValue = static_cast(std::round(y.front())); + for (const auto& it : emptyIndices) { + this->tableRow[it.first].tableEntry[it.second].targetPosition = singleValue; + } + continue; + } + + if (x.size() == 2) { + for (const auto& it : emptyIndices) { + int i = it.first; + int j = it.second; + + double extrapolated_value = linearExtrapolate(x, y, i); + + int tempValue = static_cast(std::round(extrapolated_value)); + + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + continue; + } + + if (x.size() >= 3) { + bool validForSpline = true; + for (size_t k = 1; k < x.size(); ++k) { + if (x[k] <= x[k - 1]) { + validForSpline = false; + break; + } + } + if (!validForSpline) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected for diagonal!"); + continue; + } + + CubicSpline spline; + spline.set_points(x, y); + + for (const auto& it : emptyIndices) { + int i = it.first; + int j = it.second; + + if (i < 0 || i >= POWERTABLE_CAD_SIZE || j < 0 || j >= POWERTABLE_WATT_SIZE) continue; + + double extrapolated_value = spline.extrapolate(i); + + double minVal = *std::min_element(y.begin(), y.end()); + double maxVal = *std::max_element(y.begin(), y.end()); + double range = maxVal - minVal; + extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); + + int tempValue = static_cast(std::round(extrapolated_value)); + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } } int PowerTable::getNumEntries() { From 9e7e0a5702daef783119c185eeb81ca0002be15e Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Mon, 17 Mar 2025 21:39:59 -0500 Subject: [PATCH 129/451] old code cleanup --- src/Power_Table.cpp | 64 --------------------------------------------- 1 file changed, 64 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 312f782d..cbd4b2de 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -566,56 +566,6 @@ void PowerTable::fillEmptyTable(int outerValue, const std::vector& emptyInd } } -// Old Fill Function -// void PowerTable::fillTable() { -// int tempValue = INT16_MIN; - -// // Fill each empty cell by linear interpolation -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// // Interpolate horizontally -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// // Find nearest left and right non-empty cells -// int left = j - 1; -// while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; -// int right = j + 1; -// while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - -// if (left >= 0 && right < POWERTABLE_WATT_SIZE) { -// // Linear interpolation -// tempValue = this->tableRow[i].tableEntry[left].targetPosition + -// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) * (j - left) / (right - left); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// } -// } - -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// // Interpolate vertically -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// // Find nearest top and bottom non-empty cells -// int top = i - 1; -// while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; -// int bottom = i + 1; -// while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; - -// if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { -// // Linear interpolation -// tempValue = this->tableRow[top].tableEntry[j].targetPosition + -// (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) * (i - top) / (bottom - top); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// } -// } -// } - void PowerTable::extrapFillTable() { // Find the center of the known data int sumRow = 0, sumCol = 0, count = 0; @@ -1130,20 +1080,6 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } this->enterData(k, i, (int)targetPosition); - - // if (this->getNumEntries() > 4) { - // int entries = 0; - // int newEntries = 1; - // // loop until we can't calculate any new data - // while (entries < newEntries) { - // entries = newEntries; - // this->fillTable(); - // this->extrapFillTable(); - // this->extrapolateDiagonal(); - // newEntries = getNumEntries(); - // } - // } - BLE_ss2kCustomCharacteristic::notify(0x27, k); } From 7f2b4b789202109a8cf1612109b557a32c8a5a6d Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 18 Mar 2025 15:31:50 -0500 Subject: [PATCH 130/451] made btsimulator.html smaller --- data/btsimulator.html | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/data/btsimulator.html b/data/btsimulator.html index 8962a6dd..01c342d7 100644 --- a/data/btsimulator.html +++ b/data/btsimulator.html @@ -72,7 +72,7 @@

Simulate Power Output

Auto Update
@@ -102,7 +102,7 @@

Simulate Cadence

Auto Update
@@ -198,11 +198,7 @@

Simulate ERG Mode

.catch(error => console.error('Error:', error)); } - // Aliases for compatibility with existing code - function updateHrSlider() { updateSlider('hrSlider'); } - function updateWattsSlider() { updateSlider('wattsSlider'); } - function updateCadSlider() { updateSlider('cadSlider'); } - function updateTargetWattsSlider() { updateSlider('targetWattsSlider'); } + // All sliders now directly use updateSlider() with the proper ID function toggleTargetWattsCheckbox(element, updateServer) { document.getElementById("targetWattsSlider").disabled = !element.checked; @@ -289,15 +285,6 @@

Simulate ERG Mode

} } - // Aliases for compatibility with existing code - function autoUpdateWattsClick() { - autoUpdateClick('wattsSlider', 5); - } - - function autoUpdateCadenceClick() { - autoUpdateClick('cadSlider', 3); - } - window.addEventListener('load', () => { setTimeout(requestConfigValues, 500); }); From 664bc8dcb8540e71a7482953eb74abfa072a3143 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 18 Mar 2025 16:04:00 -0500 Subject: [PATCH 131/451] Added PowerCorrectionFactor back into WebUI --- data/settings.html | 15 ++++++++++++--- data/shift.html | 8 +------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/data/settings.html b/data/settings.html index 8b6b37fc..836446cd 100644 --- a/data/settings.html +++ b/data/settings.html @@ -81,16 +81,25 @@

Reset to Defaults?

tooltip: 'Sim Mode step size', tooltipText: 'Amount to move stepper per gear shift. Try to target ~30watt changes.', min: 10, max: 6000, step: 50, - defaultValue: 0, + defaultValue: 1200, unit: '' }, + powerCorrectionFactor: { + type: 'slider', + title: 'Power Multiplier', + tooltip: 'Power Meter Correction Factor', + tooltipText: 'Adjust this to calibrate the output of your power meter.', + min: 0.10, max: 2.10, step: 0.01, + defaultValue: 1.00, + unit: 'x' + }, inclineMultiplier: { type: 'slider', title: 'Incline Multiplier', tooltip: 'Sim Mode hill effect', tooltipText: 'Increase to make incline changes more noticeable. Adjust until hills feel realistic.', min: 1, max: 10, step: 1, - defaultValue: 0, + defaultValue: 5, unit: 'x' }, ERGSensitivity: { @@ -167,7 +176,7 @@

Reset to Defaults?

pTab4Pwr: { type: 'toggle', title: 'PowerTable For Power', - tooltip: 'Use internal calculation', + tooltip: 'Use cadence to calculate power output', tooltipText: 'Use the PowerTable for Power instead of PM', defaultValue: false } diff --git a/data/shift.html b/data/shift.html index 16a38cbd..2e105621 100644 --- a/data/shift.html +++ b/data/shift.html @@ -47,17 +47,12 @@

Web Shifter

function sendShift(direction) { const position = parseInt(shiftBox.value, 10); const newPosition = position + direction; - - // Optimistic UI update - shiftBox.value = newPosition; - - // Visual feedback + shiftBox.value = newPosition; const button = direction > 0 ? 'shiftUp' : 'shiftDown'; const elem = document.getElementById(button); elem.classList.add('active'); setTimeout(() => elem.classList.remove('active'), 200); - // Send request fetch('/shift?value=' + direction, { method: 'GET' }) .catch(error => { console.error('Shift error:', error); @@ -81,7 +76,6 @@

Web Shifter

.catch(() => startUpdate()); } - window.addEventListener('load', () => { setTimeout(requestConfigValues, 500); startUpdate(); From ac484165b18b64d193fdd3a253105575b4a55993 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 18 Mar 2025 16:41:45 -0500 Subject: [PATCH 132/451] Dynamically build the status page --- data/status.html | 164 +++++++++++++++++++++-------------------------- 1 file changed, 73 insertions(+), 91 deletions(-) diff --git a/data/status.html b/data/status.html index 12ff7996..ae883a61 100644 --- a/data/status.html +++ b/data/status.html @@ -21,81 +21,8 @@

System Status

- -
-

Network Configuration

-
-
- - -
-
- - -
-
-
- - -
-

Device Status

-
-
- - -
-
- - -
-
- - -
-
- - -
-
-
- - -
-

Configuration

-
-
- - -
-
- - -
-
- - -
-
- - -
-
-
- - -
-

Connected Devices

-
-
- - -
-
- - -
-
-
+
+
@@ -121,9 +48,10 @@

Debug Console

let lastLogMessageTime = 0; let websocket; let logEntries = []; + let updateCounter = 0; const maxLogentries = 1000; + const createdGroups = { settings: false, runtime: false }; - // Visibility change handling document.addEventListener("visibilitychange", onVisibilityChanged); document.addEventListener("mozvisibilitychange", onVisibilityChanged); document.addEventListener("webkitvisibilitychange", onVisibilityChanged); @@ -140,7 +68,13 @@

Debug Console

function startUpdate() { if (!updateTimer) { updateTimer = setInterval(() => { - requestRuntimeValues(); + updateCounter++; + if (updateCounter % 4 === 0) { + requestConfigValues(); + } else { + requestRuntimeValues(); + } + setupLogging(); }, 2500); } @@ -149,6 +83,66 @@

Debug Console

function stopUpdate() { clearInterval(updateTimer); updateTimer = undefined; + updateCounter = 0; // Reset counter when updates are stopped + } + + function formatKey(key) { + return key.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase()); + } + + function updateValuesFromJson(data, groupType) { + const containerId = `${groupType}-container`; + const container = document.getElementById(containerId); + let groupCreated = createdGroups[groupType]; + + if (!groupCreated) { + const groupElement = document.createElement('div'); + groupElement.className = 'status-group'; + + const heading = document.createElement('h2'); + heading.textContent = groupType === 'settings' ? 'Configuration' : 'Runtime Values'; + groupElement.appendChild(heading); + + const grid = document.createElement('div'); + grid.className = 'status-grid'; + grid.id = `${groupType}-grid`; + groupElement.appendChild(grid); + + container.appendChild(groupElement); + createdGroups[groupType] = true; + } + + const grid = document.getElementById(`${groupType}-grid`); + + Object.keys(data).forEach(key => { + if (key === 'password') return; + + const elementId = `${groupType}-${key}`; + let statusItem = document.getElementById(elementId); + + if (!statusItem) { + statusItem = document.createElement('div'); + statusItem.className = 'status-item'; + statusItem.id = elementId; + + const label = document.createElement('label'); + label.setAttribute('for', key); + label.textContent = formatKey(key); + + const input = document.createElement('input'); + input.type = 'text'; + input.id = key; + input.name = key; + input.value = 'loading'; + input.readOnly = true; + + statusItem.appendChild(label); + statusItem.appendChild(input); + grid.appendChild(statusItem); + } + + document.getElementById(key).value = data[key]; + }); } function requestConfigValues() { @@ -158,12 +152,7 @@

Debug Console

fetch('/configJSON') .then(response => response.json()) .then(data => { - document.getElementById("ssid").value = data.ssid; - document.getElementById("connectedHeartMonitor").value = data.connectedHeartMonitor; - document.getElementById("deviceName").value = data.deviceName; - document.getElementById("shiftStep").value = data.shiftStep; - document.getElementById("inclineMultiplier").value = data.inclineMultiplier; - document.getElementById("connectedPowerMeter").value = data.connectedPowerMeter; + updateValuesFromJson(data, 'settings'); }) .catch(error => console.error('Error:', error)) .finally(() => updatePending = false); @@ -176,12 +165,7 @@

Debug Console

fetch('/runtimeConfigJSON') .then(response => response.json()) .then(data => { - document.getElementById("currentIncline").value = data.currentIncline; - document.getElementById("targetIncline").value = data.targetIncline; - document.getElementById("simulatedHr").value = data.hr; - document.getElementById("simulatedWatts").value = data.watts; - document.getElementById("targetWatts").value = data.targetWatts; - document.getElementById("simulatedCad").value = data.cad; + updateValuesFromJson(data, 'runtime'); }) .catch(error => console.error('Error:', error)) .finally(() => updatePending = false); @@ -251,8 +235,6 @@

Debug Console

document.body.removeChild(a); URL.revokeObjectURL(url); }); - - \ No newline at end of file From a700f2751ebe4c08b494d1f66b0a021d9649e432 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 18 Mar 2025 17:32:49 -0500 Subject: [PATCH 133/451] pruned style.css, removing unused elements --- data/style.css | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/data/style.css b/data/style.css index fbb4f9bb..54caee98 100644 --- a/data/style.css +++ b/data/style.css @@ -14,25 +14,20 @@ nav{align-items:center;width:100%} .brand{font-size:2.5rem;font-weight:700;text-align:center;text-shadow:0 4px 8px rgba(0,0,0,.5);margin:1rem 0;width:100%;letter-spacing:1px;color:var(--text)} nav a{color:var(--text);padding:.5rem} nav a:hover{text-decoration:underline} -.menu-grid,.dev-tools-grid,.metrics-grid{display:grid;gap:1.5rem} -.menu-grid,.dev-tools-grid{padding:2rem 0;grid-template-columns:repeat(auto-fit,minmax(300px,1fr))} -.menu-grid{max-width:800px;margin:0 auto} -.menu-item,.dev-tool-card,.metric-card,.status-group,.shifter-container,.debug-section,.scan-section,.upload-container,.device-status{background:var(--bg-overlay);border-radius:var(--radius-lg);padding:1.5rem;border:1px solid var(--border)} -.menu-item,.dev-tool-card,.shifter-container{transition:.3s;box-shadow:var(--shadow-md);text-decoration:none;display:block} +.dev-tools-grid,.metrics-grid{display:grid;gap:1.5rem} +.dev-tools-grid{padding:2rem 0;grid-template-columns:repeat(auto-fit,minmax(300px,1fr))} +.dev-tool-card,.metric-card,.status-group,.shifter-container,.debug-section,.scan-section,.upload-container,.device-status{background:var(--bg-overlay);border-radius:var(--radius-lg);padding:1.5rem;border:1px solid var(--border)} +.dev-tool-card,.shifter-container{transition:.3s;box-shadow:var(--shadow-md);text-decoration:none;display:block} .device-status{background:rgba(3,37,76,.8)} .status-group,.device-status,.debug-section,.scan-section,.shifter-container,.upload-container{margin-bottom:1.5rem} -.menu-item:hover,.dev-tool-card:hover,.shifter-container:hover{background:rgba(42,157,244,.15);border-color:rgba(42,157,244,.5);transform:translateY(-2px);box-shadow:var(--shadow-lg)} -.menu-content{padding:.5rem} -.menu-content h2{margin:0 0 .75rem;font-size:1.3rem;font-weight:600;color:var(--primary)} -.menu-content p{margin:0;opacity:.9;font-size:1rem;line-height:1.5;color:var(--text)} +.dev-tool-card:hover,.shifter-container:hover{background:rgba(42,157,244,.15);border-color:rgba(42,157,244,.5);transform:translateY(-2px);box-shadow:var(--shadow-lg)} .device-status h2,.status-group h2{margin:0 0 1.5rem;color:var(--primary);font-size:1.2rem;border-bottom:1px solid rgba(42,157,244,.3);padding-bottom:.5rem} .status-grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(250px,1fr))} .status-item{background:var(--bg-item);padding:1rem;border-radius:var(--radius-md);display:flex;flex-direction:column;gap:.5rem;font-weight:500;color:var(--primary)} -.status-item label,.follow-toggle,.metric-label{color:var(--text-secondary);font-size:.9rem;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.5px} -.status-item label,.follow-toggle{display:block} -.status-item input,.debug-console,.gear-display{box-sizing:border-box;width:100%} -.status-item input{padding:.75rem;background:var(--bg-overlay);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--primary);font-size:1.1rem;font-weight:500;text-align:center} -.debug-header,.card-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem} +.follow-toggle,.metric-label{color:var(--text-secondary);font-size:.9rem;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.5px} +.follow-toggle{display:block} +.debug-console,.gear-display{box-sizing:border-box;width:100%} +.debug-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem} .debug-header h2{margin:0;color:var(--primary);font-size:1.2rem} .follow-toggle{display:flex;align-items:center;gap:.5rem} .debug-console{margin:0;padding:1rem;background-color:#000;background-image:radial-gradient(rgba(0,150,0,.75),#000 120%);height:40vh;resize:both;border:1px solid var(--border);border-radius:var(--radius-md);color:var(--text);font-family:Inconsolata,monospace;font-size:1.1rem;line-height:1.4;overflow:auto;text-shadow:0 0 4px rgba(200,200,200,.5)} @@ -45,7 +40,7 @@ nav a:hover{text-decoration:underline} .shift-down{background:linear-gradient(to bottom,#e74c3c,#c0392b)} .shift-down:hover{background:linear-gradient(to bottom,#c0392b,#a93224)} .shift-arrow{font-size:1.5rem;line-height:1} -.shift-label,.reset-defaults-button,.metric-label{text-transform:uppercase;letter-spacing:.5px} +.shift-label,.metric-label{text-transform:uppercase;letter-spacing:.5px} .shift-label{font-size:1rem;letter-spacing:1px} .gear-display{background:var(--bg-item);padding:2rem;border-radius:var(--radius-md);text-align:center} .gear-label{display:block;font-size:1.2rem;margin-bottom:1rem;color:rgba(255,255,255,.9)} @@ -71,7 +66,6 @@ nav a:hover{text-decoration:underline} .adjust-button{width:36px;height:36px;border:none;background:#03254c;color:var(--text);border-radius:50%;cursor:pointer;font-size:1rem;display:flex;align-items:center;justify-content:center;transition:background .2s;flex-shrink:0} .adjust-button:hover,input:checked+.slider{background:var(--primary)} .button-group{display:flex;gap:1rem;margin-top:2rem;justify-content:flex-end} -.reset-defaults-button{font-size:1.1em;padding:1rem 2rem;border:2px solid rgba(255,255,255,.2);font-weight:600;animation:2s infinite pulse} .primary-button,.secondary-button,.warning-button{padding:.75rem 1.5rem;border:none;border-radius:var(--radius-sm);font-weight:500;cursor:pointer;transition:.2s} .primary-button{background:var(--primary);color:var(--text)} .primary-button:hover{background:#1b8fe3} @@ -130,7 +124,7 @@ footer{margin-top:2rem;padding:1rem 0;border-top:1px solid var(--border);display @keyframes pulse{0%{box-shadow:0 0 0 0 rgba(220,53,69,.4)}70%{box-shadow:0 0 0 10px rgba(220,53,69,0)}100%{box-shadow:0 0 0 0 rgba(220,53,69,0)}} @media (max-width:768px){ .input-group,.button-group,.value-display,.dev-links{flex-direction:column} -.menu-grid,.status-grid,.metrics-grid,.dev-tools-grid{grid-template-columns:1fr} +.status-grid,.metrics-grid,.dev-tools-grid{grid-template-columns:1fr} .number-input,.scan-button{width:100%} .settings-section{padding:1rem} .adjust-button{min-width:32px} @@ -138,7 +132,7 @@ footer{margin-top:2rem;padding:1rem 0;border-top:1px solid var(--border);display .input-group{align-items:stretch} .unit{text-align:right} .shift-button{height:100px} -.menu-item,.status-group,.metric-card{padding:1.25rem} +.status-group,.metric-card{padding:1.25rem} .value-display{gap:.5rem;text-align:center} .auto-update{justify-content:center} .debug-console{height:50vh} From 0a6c9307551c339237ff47afba8b8a24d22e8fd6 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 18 Mar 2025 17:47:05 -0500 Subject: [PATCH 134/451] Cap penalty at 0 --- src/Power_Table.cpp | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index cbd4b2de..f7216398 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -937,13 +937,11 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { (this->testNeighbors(testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.leftNeighbor.targetPosition).allNeighborsPassed))) { SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); - // this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); } } else { SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed left (%d)(%d)(%d), readings (%d)", testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.leftNeighbor.targetPosition, this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings); - // this->tableRow[testResults.leftNeighbor.i].tableEntry[testResults.leftNeighbor.j].readings--; this->downVoteData(testResults.leftNeighbor.i, testResults.leftNeighbor.j, targetPosition, testResults.leftNeighbor.targetPosition); } } @@ -980,13 +978,11 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { (this->testNeighbors(testResults.leftNeighbor.i, testResults.leftNeighbor.j, testResults.rightNeighbor.targetPosition).allNeighborsPassed))) { SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); - // this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); } } else { SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed right (%d)(%d)(%d), readings (%d)", testResults.rightNeighbor.i, testResults.rightNeighbor.j, testResults.rightNeighbor.targetPosition, this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings); - // this->tableRow[testResults.rightNeighbor.i].tableEntry[testResults.rightNeighbor.j].readings--; this->downVoteData(testResults.rightNeighbor.i, testResults.rightNeighbor.j, targetPosition, testResults.rightNeighbor.targetPosition); } } @@ -1023,13 +1019,11 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { (this->testNeighbors(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.topNeighbor.targetPosition).allNeighborsPassed))) { SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - // this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); } } else { SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed top (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - // this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings--; this->downVoteData(testResults.topNeighbor.i, testResults.topNeighbor.j, targetPosition, testResults.topNeighbor.targetPosition); } } @@ -1066,13 +1060,11 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { (this->testNeighbors(testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.bottomNeighbor.targetPosition).allNeighborsPassed))) { SS2K_LOG(POWERTABLE_LOG_TAG, "All test failed bottom (%d)(%d)(%d), readings (%d)", testResults.topNeighbor.i, testResults.topNeighbor.j, testResults.topNeighbor.targetPosition, this->tableRow[testResults.topNeighbor.i].tableEntry[testResults.topNeighbor.j].readings); - // this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); } } else { SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed bottom (%d)(%d)(%d), readings (%d)", testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, testResults.bottomNeighbor.targetPosition, this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings); - // this->tableRow[testResults.bottomNeighbor.i].tableEntry[testResults.bottomNeighbor.j].readings--; this->downVoteData(testResults.bottomNeighbor.i, testResults.bottomNeighbor.j, targetPosition, testResults.bottomNeighbor.targetPosition); } } @@ -1084,7 +1076,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } void PowerTable::enterData(int i, int j, int pos) { - if (this->tableRow[i].tableEntry[j].readings == 0) { // if first reading in this entry + if (this->tableRow[i].tableEntry[j].readings <= 0) { // if first reading in this entry this->tableRow[i].tableEntry[j].targetPosition = pos; SS2K_LOG(POWERTABLE_LOG_TAG, "New entry recorded (%d)(%d)(%d)", i, j, this->tableRow[i].tableEntry[j].targetPosition); } else { // Average and update the readings. @@ -1132,12 +1124,11 @@ void PowerTable::downVoteData(int i, int j, float target, int neighbor) { // determine penalty amount before applying to failed neighbor int penalty = weightedDownVote(target, neighbor); - // make sure downvotes isn't at max - if (this->tableRow[i].tableEntry[j].readings > MAX_NEIGHBOR_WEIGHT) { - this->tableRow[i].tableEntry[j].readings = MAX_NEIGHBOR_WEIGHT; - penalty = 0; + if (this->tableRow[i].tableEntry[j].readings < penalty) { + this->tableRow[i].tableEntry[j].readings = 0; + } else { + this->tableRow[i].tableEntry[j].readings -= penalty; } - this->tableRow[i].tableEntry[j].readings -= penalty; SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed (%d)(%d)(%d), readings (%d)", i, j, neighbor, this->tableRow[i].tableEntry[j].readings); } From a94641f6a3745c0c5fcc657a7ca3f5fa823601f6 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 18 Mar 2025 18:07:36 -0500 Subject: [PATCH 135/451] fix for re-connection crash. --- include/BLE_Common.h | 2 +- src/BLE_Client.cpp | 54 ++++++++++++++++++++++++++------------------ 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/include/BLE_Common.h b/include/BLE_Common.h index 0e781a65..d3e0988a 100644 --- a/include/BLE_Common.h +++ b/include/BLE_Common.h @@ -175,7 +175,7 @@ class SpinBLEAdvertisedDevice { void setPostConnected(bool pc) { isPostConnected = pc; } bool getPostConnected() { return isPostConnected; } void set(const NimBLEAdvertisedDevice* device, int id = BLE_HS_CONN_HANDLE_NONE, BLEUUID inServiceUUID = (uint16_t)0x0000, BLEUUID inCharUUID = (uint16_t)0x0000); - void reset(); + void reset(bool resetAdvertisedDevice = true); void print(); bool enqueueData(uint8_t data[NOTIFY_DATA_QUEUE_SIZE], size_t length, NimBLEUUID serviceUUID, NimBLEUUID charUUID); NotifyData dequeueData(); diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index 82f19e52..3211701f 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -227,9 +227,8 @@ bool SpinBLEClient::connectToServer() { } if (myDevice->getServiceUUIDCount() > 0) { String deviceName = myDevice->haveName() ? String(myDevice->getName().c_str()) : "Unknown"; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Getting service info for device: %s with %d services", - deviceName.c_str(), myDevice->getServiceUUIDCount()); - + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Getting service info for device: %s with %d services", deviceName.c_str(), myDevice->getServiceUUIDCount()); + const BLEServiceInfo *serviceInfo = getDeviceServiceInfo(myDevice, deviceName); if (!serviceInfo) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "No supported service UUID found for device: %s", deviceName.c_str()); @@ -239,8 +238,7 @@ bool SpinBLEClient::connectToServer() { serviceUUID = serviceInfo->serviceUUID; charUUID = serviceInfo->characteristicUUID; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Trying to connect to %s (Service UUID: %s)", - serviceInfo->name.c_str(), serviceUUID.toString().c_str()); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Trying to connect to %s (Service UUID: %s)", serviceInfo->name.c_str(), serviceUUID.toString().c_str()); } else { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Device has no Service UUID"); spinBLEClient.myBLEDevices[device_number].reset(); @@ -361,12 +359,6 @@ void MyClientCallback::onDisconnect(NimBLEClient *pClient, int reason) { for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { if (addr == spinBLEClient.myBLEDevices[i].peerAddress) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Detected %s Disconnect", spinBLEClient.myBLEDevices[i].serviceUUID.toString().c_str()); - // did another task disconnect this device? - if (!spinBLEClient.intentionalDisconnect) { - spinBLEClient.myBLEDevices[i].doConnect = true; - } else { - spinBLEClient.intentionalDisconnect--; - } 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) || (spinBLEClient.myBLEDevices[i].charUUID == CYCLINGPOWERSERVICE_UUID) || (spinBLEClient.myBLEDevices[i].charUUID == CSCSERVICE_UUID)) { @@ -380,7 +372,15 @@ void MyClientCallback::onDisconnect(NimBLEClient *pClient, int reason) { if ((spinBLEClient.myBLEDevices[i].charUUID == HID_REPORT_DATA_UUID)) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Deregistered Remote on Disconnect"); } - spinBLEClient.myBLEDevices[i].reset(); + // did another task disconnect this device? + if (!spinBLEClient.intentionalDisconnect) { + spinBLEClient.myBLEDevices[i].doConnect = true; + spinBLEClient.myBLEDevices[i].reset(false); + } else { + spinBLEClient.intentionalDisconnect--; + spinBLEClient.myBLEDevices[i].reset(); + } + } } return; @@ -431,7 +431,7 @@ void ScanCallbacks::onResult(const NimBLEAdvertisedDevice *advertisedDevice) { SS2K_LOGE(BLE_CLIENT_LOG_TAG, "onResult received NULL advertisedDevice!"); return; } - + Serial.printf("Advertised Device found: %s\n", advertisedDevice->toString().c_str()); // Define granular constants for maximal reuse during logging const char *const MATCHED = "Matched "; @@ -744,21 +744,20 @@ NotifyData SpinBLEAdvertisedDevice::dequeueData() { // Initialize to safe values receivedNotifyData.length = 0; memset(receivedNotifyData.data, 0, NOTIFY_DATA_QUEUE_SIZE); - + if (this->dataBufferQueue == nullptr) { SS2K_LOGW(BLE_CLIENT_LOG_TAG, "Queue not created. Skipping dequeue of data."); return receivedNotifyData; } - + if (xQueueReceive(this->dataBufferQueue, &receivedNotifyData, 0) == pdTRUE) { // Validate data length to prevent buffer overruns if (receivedNotifyData.length > NOTIFY_DATA_QUEUE_SIZE) { - SS2K_LOGE(BLE_CLIENT_LOG_TAG, "Invalid data length %d (max %d). Discarding.", - receivedNotifyData.length, NOTIFY_DATA_QUEUE_SIZE); + SS2K_LOGE(BLE_CLIENT_LOG_TAG, "Invalid data length %d (max %d). Discarding.", receivedNotifyData.length, NOTIFY_DATA_QUEUE_SIZE); receivedNotifyData.length = 0; } } - + // Return data (either valid dequeued data or empty initialized data) return receivedNotifyData; } @@ -931,14 +930,14 @@ void SpinBLEAdvertisedDevice::set(const NimBLEAdvertisedDevice *device, int id, SS2K_LOGE(BLE_CLIENT_LOG_TAG, "ERROR: Attempt to set null device!"); return; } - + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Setting Device %s", device->getAddress().toString().c_str()); this->advertisedDevice = const_cast(device); this->peerAddress = device->getAddress(); this->connectedClientID = id; this->serviceUUID = BLEUUID(inServiceUUID); this->charUUID = BLEUUID(inCharUUID); - + // Create the queue if it doesn't exist if (this->dataBufferQueue == nullptr) { this->dataBufferQueue = xQueueCreate(6, sizeof(NotifyData)); @@ -980,13 +979,24 @@ void SpinBLEAdvertisedDevice::set(const NimBLEAdvertisedDevice *device, int id, // During initial discovery, just store the device info without registering services } -void SpinBLEAdvertisedDevice::reset() { +/** + * @brief Resets the state of the SpinBLEAdvertisedDevice instance. + * + * This method clears the internal state of the device, including connection + * identifiers, service and characteristic UUIDs, and various flags indicating + * the type of device and its connection status. Optionally, it can also reset + * the advertised device reference. + * + * @param resetAdvertisedDevice If true, the advertised device reference will + * be set to nullptr. + */ +void SpinBLEAdvertisedDevice::reset(bool resetAdvertisedDevice) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Resetting Device: %d", this->connectedClientID); if (this->isHRM) spinBLEClient.connectedHRM = false; if (this->isPM) spinBLEClient.connectedPM = false; if (this->isCSC) spinBLEClient.connectedCD = false; spinBLEClient.connectedSpeed = false; - advertisedDevice = nullptr; + if (resetAdvertisedDevice) advertisedDevice = nullptr; // NimBLEAddress peerAddress; this->connectedClientID = BLE_HS_CONN_HANDLE_NONE; this->serviceUUID = (uint16_t)0x0000; From 6860ba668c458b003f3646fb30f32e45c4d620e6 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Wed, 19 Mar 2025 16:55:03 -0500 Subject: [PATCH 136/451] cubic spline takes pointers instead of vectors, and modified fill functions --- include/Power_Table.h | 7 +- src/Power_Table.cpp | 841 +++++++++++------------------------------- 2 files changed, 229 insertions(+), 619 deletions(-) diff --git a/include/Power_Table.h b/include/Power_Table.h index e70dda04..d3710b55 100644 --- a/include/Power_Table.h +++ b/include/Power_Table.h @@ -132,13 +132,16 @@ class PowerTable { // Display power table in log void toLog(); - void fillEmptyTable(int outerValue, const std::vector& emptyIndices, const std::vector& x, const std::vector& y, bool horizontal, bool useNaturalSpline); + void fillEmptyTable(int outerValue, const std::vector& emptyIndices, const double* x, const double* y, size_t n, bool horizontal, bool useNaturalSpline); void findTableDirection(bool horizontal); void extrapFillTableDirection(bool horizontal); - void extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, const std::vector& x, const std::vector& y, bool horizontal, bool naturalSpline); + void extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, const double* x, const double* y, size_t n, bool horizontal, bool naturalSpline); + + void extrapolateDiagonalEntries(const std::vector>& emptyIndices, const double* x, const double* y, size_t n); + private: unsigned long lastSaveTime = millis(); TestResults testNeighbors(int i, int j, int value); diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 44e0a08c..fdaf479e 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -369,250 +369,169 @@ TestResults PowerTable::testNeighbors(int i, int j, int testValue) { * due to invalid input (e.g., duplicate x values), the function logs an error * and returns `INT16_MIN`. */ -double linearInterpolate(const std::vector& x, const std::vector& y, double j) { - auto upper = std::upper_bound(x.begin(), x.end(), j); +double linearInterpolate(const double* x, const double* y, size_t n, double j) { + auto upper = std::upper_bound(x, x + n, j); - if (upper == x.end()) return y.back(); // Extrapolate using last value - if (upper == x.begin()) return y.front(); // Extrapolate using first value + if (upper == x + n) return y[n - 1]; // Extrapolate using last value + if (upper == x) return y[0]; // Extrapolate using first value auto lower = upper - 1; double x0 = *lower, x1 = *upper; - double y0 = y[lower - x.begin()], y1 = y[upper - x.begin()]; - // log and comment if x1-x0 is 0 + double y0 = y[lower - x], y1 = y[upper - x]; + + // Log and comment if x1 - x0 is 0 if (x1 - x0 == 0) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Linear Interpolation failed, x1-x0 is 0"); - return INT16_MIN; + SS2K_LOG(POWERTABLE_LOG_TAG, "Linear Interpolation failed, x1 - x0 is 0"); + return INT16_MIN; } + double interpolated_value = y0 + (y1 - y0) * (j - x0) / (x1 - x0); - double minValue = *std::min_element(y.begin(), y.end()); - double maxValue = *std::max_element(y.begin(), y.end()); + double minValue = *std::min_element(y, y + n); + double maxValue = *std::max_element(y, y + n); return std::max(minValue, std::min(maxValue, interpolated_value)); } -class CubicSpline { - public: - void set_points(const std::vector& x, const std::vector& y) { - int n = x.size() - 1; - h.resize(n); - alpha.resize(n + 1); - l.resize(n + 1); - mu.resize(n + 1); - z.resize(n + 1); - c.resize(n + 1); - b.resize(n); - d.resize(n); - this->x = x; - this->y = y; - - for (int i = 0; i < n; ++i) h[i] = x[i + 1] - x[i]; - - double f_prime_start = (y[1] - y[0]) / (x[1] - x[0]); - double f_prime_end = (y[n] - y[n - 1]) / (x[n] - x[n - 1]); - - alpha[0] = (3.0 / h[0]) * (y[1] - y[0]) - 3.0 * f_prime_start; - alpha[n] = 3.0 * f_prime_end - (3.0 / h[n - 1]) * (y[n] - y[n - 1]); - - for (int i = 1; i < n; ++i) alpha[i] = (3.0 / h[i]) * (y[i + 1] - y[i]) - (3.0 / h[i - 1]) * (y[i] - y[i - 1]); - - l[0] = 2.0 * h[0]; - mu[0] = 0.5; - z[0] = alpha[0] / l[0]; - - for (int i = 1; i < n; ++i) { - l[i] = 2.0 * (x[i + 1] - x[i - 1]) - h[i - 1] * mu[i - 1]; - mu[i] = h[i] / l[i]; - z[i] = (alpha[i] - h[i - 1] * z[i - 1]) / l[i]; - } - - l[n] = h[n - 1] * (2.0 - mu[n - 1]); - z[n] = (alpha[n] - h[n - 1] * z[n - 1]) / l[n]; - c[n] = z[n]; +double linearExtrapolate(const double* x, const double* y, size_t n, double j) { + double x0, x1, y0, y1; - for (int j = n - 1; j >= 0; --j) { - c[j] = z[j] - mu[j] * c[j + 1]; - b[j] = (y[j + 1] - y[j]) / h[j] - h[j] * (c[j + 1] + 2.0 * c[j]) / 3.0; - d[j] = (c[j + 1] - c[j]) / (3.0 * h[j]); - } + if (j < x[0]) { + x0 = x[0], x1 = x[1]; + y0 = y[0], y1 = y[1]; + } else if (j > x[n - 1]) { + x0 = x[n - 2], x1 = x[n - 1]; + y0 = y[n - 2], y1 = y[n - 1]; + } else { + auto upper = std::upper_bound(x, x + n, j); + auto lower = upper - 1; + x0 = *lower, x1 = *upper; + y0 = y[lower - x], y1 = y[upper - x]; } - double interpolate(double x_val) const { - if (x_val < x.front() || x_val > x.back()) { + if (x1 - x0 == 0) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Linear Extrapolation failed, x1 - x0 is 0"); return INT16_MIN; - } - - int i = std::upper_bound(x.begin(), x.end(), x_val) - x.begin() - 1; - double dx = x_val - x[i]; - return y[i] + b[i] * dx + c[i] * dx * dx + d[i] * dx * dx * dx; } - double extrapolate(double x_val) const { - if (x_val < x.front()) { - double dx = x_val - x[0]; - return y[0] + b[0] * dx + c[0] * dx * dx + d[0] * dx * dx * dx; - } - if (x_val > x.back()) { - int n = x.size() - 1; - double dx = x_val - x[n]; - return y[n] + b[n - 1] * dx + c[n - 1] * dx * dx + d[n - 1] * dx * dx * dx; - } - return INT16_MIN; - } - - private: - std::vector x, y, h, alpha, l, mu, z, c, b, d; -}; - - -double linearInterpolate(const std::vector& x, const std::vector& y, double j) { - auto upper = std::upper_bound(x.begin(), x.end(), j); - - if (upper == x.end()) return y.back(); // Extrapolate using last value - if (upper == x.begin()) return y.front(); // Extrapolate using first value - - - auto lower = upper - 1; - double x0 = *lower, x1 = *upper; - double y0 = y[lower - x.begin()], y1 = y[upper - x.begin()]; - - double interpolated_value = y0 + (y1 - y0) * (j - x0) / (x1 - x0); - - double minValue = *std::min_element(y.begin(), y.end()); - double maxValue = *std::max_element(y.begin(), y.end()); - return std::max(minValue, std::min(maxValue, interpolated_value)); + double slope = (y1 - y0) / (x1 - x0); + return y0 + slope * (j - x0); } -double linearExtrapolate(const std::vector& x, const std::vector& y, double j) { - if (j < x.front()) { - double x0 = x[0], x1 = x[1]; - double y0 = y[0], y1 = y[1]; - double slope = (y1 - y0) / (x1 - x0); - return y0 + slope * (j - x0); - } else if (j > x.back()) { - double x0 = x[x.size() - 2], x1 = x[x.size() - 1]; - double y0 = y[y.size() - 2], y1 = y[y.size() - 1]; - double slope = (y1 - y0) / (x1 - x0); - return y1 + slope * (j - x1); - } else { - // Standard Linear Interpolation - auto upper = std::upper_bound(x.begin(), x.end(), j); - auto lower = upper - 1; - double x0 = *lower, x1 = *upper; - double y0 = y[lower - x.begin()], y1 = y[upper - x.begin()]; - return y0 + (y1 - y0) * (j - x0) / (x1 - x0); - } -} class CubicSpline { public: - void set_points(const std::vector& x, const std::vector& y, bool natural = true) { - int n = x.size() - 1; - this->x = x; - this->y = y; + void set_points(const double* x_vals, const double* y_vals, size_t n, bool natural = true) { + + if (n < 2) return; // Safe check to make sure we have enough points + + size_t last_index = n - 1; + x.assign(x_vals, x_vals + n); + y.assign(y_vals, y_vals + n); - h.resize(n); - alpha.resize(n + 1); - l.resize(n + 1); - mu.resize(n + 1); - z.resize(n + 1); - c.resize(n + 1, 0.0); - b.resize(n); - d.resize(n); + h.resize(last_index); + alpha.resize(n); + l.resize(n); + mu.resize(n); + z.resize(n); + c.resize(n, 0.0); + b.resize(last_index); + d.resize(last_index); - // Compute h values - for (int i = 0; i < n; ++i) + // Get h values + for (size_t i = 0; i < last_index; ++i) h[i] = x[i + 1] - x[i]; - // Compute alpha values - for (int i = 1; i < n; ++i) + // gEt alpha values + for (size_t i = 1; i < last_index; ++i) alpha[i] = (3.0 / h[i]) * (y[i + 1] - y[i]) - (3.0 / h[i - 1]) * (y[i] - y[i - 1]); - // Boundary conditions + // Check if we are using natural or clamped spline calculations if (natural) { - alpha[0] = alpha[n] = 0.0; + alpha[0] = alpha[last_index] = 0.0; } else { double f_prime_start = (y[1] - y[0]) / h[0]; - double f_prime_end = (y[n] - y[n - 1]) / h[n - 1]; - alpha[0] = 3.0 * ( (y[1] - y[0]) / h[0] - f_prime_start ); - alpha[n] = 3.0 * ( f_prime_end - (y[n] - y[n - 1]) / h[n - 1] ); + double f_prime_end = (y[last_index] - y[last_index - 1]) / h[last_index - 1]; + alpha[0] = 3.0 * ((y[1] - y[0]) / h[0] - f_prime_start); + alpha[last_index] = 3.0 * (f_prime_end - (y[last_index] - y[last_index - 1]) / h[last_index - 1]); } - // Compute l, mu, and z + // Get l, mu, and z l[0] = 1.0; mu[0] = z[0] = 0.0; - for (int i = 1; i < n; ++i) { + for (size_t i = 1; i < last_index; ++i) { l[i] = 2.0 * (x[i + 1] - x[i - 1]) - h[i - 1] * mu[i - 1]; mu[i] = h[i] / l[i]; z[i] = (alpha[i] - h[i - 1] * z[i - 1]) / l[i]; } - l[n] = 1.0; - z[n] = c[n] = 0.0; + l[last_index] = 1.0; + z[last_index] = c[last_index] = 0.0; - for (int j = n - 1; j >= 0; --j) { + for (int j = last_index - 1; j >= 0; --j) { c[j] = z[j] - mu[j] * c[j + 1]; b[j] = (y[j + 1] - y[j]) / h[j] - h[j] * (c[j + 1] + 2.0 * c[j]) / 3.0; d[j] = (c[j + 1] - c[j]) / (3.0 * h[j]); } } - - double interpolate(double x_val) const { - if (x_val < x.front() || x_val > x.back()) { - return INT16_MIN; + + double interpolate(double x_val) const { + if (x_val < x.front() || x_val > x.back()) { + return INT16_MIN; // Out of range + } + + int i = std::upper_bound(x.begin(), x.end(), x_val) - x.begin() - 1; + double dx = x_val - x[i]; + return y[i] + b[i] * dx + c[i] * dx * dx + d[i] * dx * dx * dx; } - - int i = std::upper_bound(x.begin(), x.end(), x_val) - x.begin() - 1; - double dx = x_val - x[i]; - return y[i] + b[i] * dx + c[i] * dx * dx + d[i] * dx * dx * dx; - } - - double extrapolate(double x_val) const { - if (x_val < x.front()) { - double dx = x_val - x[0]; - return y[0] + b[0] * dx + c[0] * dx * dx + d[0] * dx * dx * dx; + + double extrapolate(double x_val) const { + if (x_val < x.front()) { + double dx = x_val - x[0]; + return y[0] + b[0] * dx + c[0] * dx * dx + d[0] * dx * dx * dx; + } + if (x_val > x.back()) { + int n = x.size() - 1; + double dx = x_val - x[n]; + return y[n] + b[n - 1] * dx + c[n - 1] * dx * dx + d[n - 1] * dx * dx * dx; + } + return INT16_MIN; // Out of range } - if (x_val > x.back()) { - int n = x.size() - 1; - double dx = x_val - x[n]; - return y[n] + b[n - 1] * dx + c[n - 1] * dx * dx + d[n - 1] * dx * dx * dx; + + private: + std::vector x, y, h, alpha, l, mu, z, c, b, d; + }; + + // Function to determine if a natural spline should be used + bool shouldUseNaturalSpline(const double* x, const double* y, size_t n) { + if (n < 3) return true; // Default to natural spline for small data sets + + // Compute approximate first derivatives at endpoints + double startSlope = (y[1] - y[0]) / (x[1] - x[0]); + double endSlope = (y[n - 1] - y[n - 2]) / (x[n - 1] - x[n - 2]); + + // Adaptive slope threshold + double dataRange = *std::max_element(y, y + n) - *std::min_element(y, y + n); + double slopeThreshold = 0.1 * dataRange; + + // If slope changes significantly, consider using a clamped spline + if (std::abs(startSlope) > slopeThreshold || std::abs(endSlope) > slopeThreshold) { + return false; // Use clamped spline } - return INT16_MIN; - } - -private: - std::vector x, y, h, alpha, l, mu, z, c, b, d; -}; - -bool shouldUseNaturalSpline(const std::vector& x, const std::vector& y) { - if (x.size() < 3) return true; // Default to natural spline for small data sets - - // Compute approximate first derivatives at endpoints - double startSlope = (y[1] - y[0]) / (x[1] - x[0]); - double endSlope = (y[y.size() - 1] - y[y.size() - 2]) / (x[y.size() - 1] - x[y.size() - 2]); - - // Adaptive slope threshold - double dataRange = *std::max_element(y.begin(), y.end()) - *std::min_element(y.begin(), y.end()); - double slopeThreshold = 0.1 * dataRange; - - // If slope changes significantly, consider using a clamped spline - if (std::abs(startSlope) > slopeThreshold || std::abs(endSlope) > slopeThreshold) { - return false; // Use clamped spline - } - - // Second derivative (curvature) check for smoothness - double secondDerivativeStart = (y[2] - 2 * y[1] + y[0]) / ((x[1] - x[0]) * (x[2] - x[1])); - double secondDerivativeEnd = (y[y.size() - 1] - 2 * y[y.size() - 2] + y[y.size() - 3]) / - ((x[y.size() - 2] - x[y.size() - 3]) * (x[y.size() - 1] - x[y.size() - 2])); - - double curvatureThreshold = 1.0; // Adjust based on expected smoothness - if (std::abs(secondDerivativeStart) > curvatureThreshold || std::abs(secondDerivativeEnd) > curvatureThreshold) { - return false; // Use clamped spline + + // Second derivative (curvature) check for smoothness + double secondDerivativeStart = (y[2] - 2 * y[1] + y[0]) / ((x[1] - x[0]) * (x[2] - x[1])); + double secondDerivativeEnd = (y[n - 1] - 2 * y[n - 2] + y[n - 3]) / + ((x[n - 2] - x[n - 3]) * (x[n - 1] - x[n - 2])); + + double curvatureThreshold = 1.0; // Adjust based on expected smoothness + if (std::abs(secondDerivativeStart) > curvatureThreshold || std::abs(secondDerivativeEnd) > curvatureThreshold) { + return false; // Use clamped spline + } + + return true; // Default to natural spline } - return true; // Default to natural spline -} - void PowerTable::fillTable() { this->findTableDirection(true); // Horizontal this->findTableDirection(false); // Vertical @@ -643,7 +562,6 @@ void PowerTable::findTableDirection(bool horizontal) { if (targetPos != INT16_MIN) { unique_xy.emplace_back(innerValue, static_cast(targetPos)); } else { - // Store a subset of empty indices (every 5th) if (emptyIndices.empty() || innerValue - emptyIndices.back() >= 5) { emptyIndices.push_back(innerValue); } @@ -654,41 +572,41 @@ void PowerTable::findTableDirection(bool horizontal) { std::sort(unique_xy.begin(), unique_xy.end()); - for (const auto& [xi, yi] : unique_xy) { - x.push_back(xi); - y.push_back(yi); - } + for (std::vector>::const_iterator it = unique_xy.begin(); it != unique_xy.end(); ++it) { + x.push_back(it->first); + y.push_back(it->second); + } - bool useNaturalSpline = shouldUseNaturalSpline(x, y); - fillEmptyTable(outerValue, emptyIndices, x, y, horizontal, useNaturalSpline); + bool useNaturalSpline = shouldUseNaturalSpline(x.data(), y.data(), x.size()); + fillEmptyTable(outerValue, emptyIndices, x.data(), y.data(), x.size(), horizontal, useNaturalSpline); } } -void PowerTable::fillEmptyTable(int outerValue, const std::vector& emptyIndices, const std::vector& x, const std::vector& y, bool horizontal, bool useNaturalSpline) { +void PowerTable::fillEmptyTable(int outerValue, const std::vector& emptyIndices, const double* x, const double* y, size_t n, bool horizontal, bool useNaturalSpline) { int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; - if (x.size() == 1) { // If only one point, fill row with the value - double singleValue = y.front(); + if (n == 1) { // If only one point, fill row with the value + double singleValue = y[0]; for (int innerValue : emptyIndices) { int i = horizontal ? outerValue : innerValue; int j = horizontal ? innerValue : outerValue; this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); } - } else if (x.size() == 2) { // If two points, do linear interpolation + } else if (n == 2) { // If two points, do linear interpolation for (int innerValue : emptyIndices) { int i = horizontal ? outerValue : innerValue; int j = horizontal ? innerValue : outerValue; - double interpolated_value = linearInterpolate(x, y, innerValue); + double interpolated_value = linearInterpolate(x, y, n, innerValue); int tempValue = static_cast(std::round(interpolated_value)); if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } - } else if (x.size() >= 3) { // If three or more points, use cubic spline interpolation + } else if (n >= 3) { // If three or more points, use cubic spline interpolation bool validForSpline = true; - for (size_t i = 1; i < x.size(); ++i) { + for (size_t i = 1; i < n; ++i) { if (x[i] <= x[i - 1]) { validForSpline = false; break; @@ -701,7 +619,7 @@ void PowerTable::fillEmptyTable(int outerValue, const std::vector& emptyInd // Create and initialize the spline with the desired type (natural or clamped) CubicSpline spline; - spline.set_points(x, y, useNaturalSpline); + spline.set_points(x, y, n, useNaturalSpline); for (int innerValue : emptyIndices) { int i = horizontal ? outerValue : innerValue; @@ -709,8 +627,8 @@ void PowerTable::fillEmptyTable(int outerValue, const std::vector& emptyInd double interpolated_value = spline.interpolate(innerValue); - double minValue = *std::min_element(y.begin(), y.end()); - double maxValue = *std::max_element(y.begin(), y.end()); + double minValue = *std::min_element(y, y + n); + double maxValue = *std::max_element(y, y + n); interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); int tempValue = static_cast(std::round(interpolated_value)); @@ -724,266 +642,6 @@ void PowerTable::fillEmptyTable(int outerValue, const std::vector& emptyInd } } -// void PowerTable::extrapFillTable() { -// // Find the center of the known data -// int sumRow = 0, sumCol = 0, count = 0; -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { -// sumRow += i; -// sumCol += j; -// count++; -// } -// } -// } - -// // prevent divide by zero -// if (count == 0) { -// return; -// } - -// int centerRow = sumRow / count; -// int centerCol = sumCol / count; -// int tempValue = INT16_MIN; - -// // Function to extrapolate a single cell based on its neighbors -// auto extrapolateCell = [&](int i, int j) { -// // Find nearest left non-empty cell -// int left = j - 1; -// while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - -// // Find nearest right non-empty cell -// int right = j + 1; -// while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; - -// if (left >= 0 && right < POWERTABLE_WATT_SIZE) { -// // Linear extrapolation -// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { -// if (j < left) { -// // Extrapolate to the left -// tempValue = this->tableRow[i].tableEntry[left].targetPosition - -// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } else if (j > right) { -// // Extrapolate to the right -// tempValue = this->tableRow[i].tableEntry[right].targetPosition + -// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// } else if (left - 1 >= 0) { -// // Only left value available, extrapolate to the right -// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { -// tempValue = this->tableRow[i].tableEntry[left].targetPosition + -// (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } else if (right + 1 < POWERTABLE_WATT_SIZE) { -// // Only right value available, extrapolate to the left -// if (this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { -// tempValue = -// this->tableRow[i].tableEntry[right].targetPosition - -// (right - j) * (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// }; - -// // Extrapolate horizontally and vertically starting from the center -// for (int distance = 0; distance <= std::max(centerRow, centerCol); ++distance) { -// for (int i = centerRow - distance; i <= centerRow + distance; ++i) { -// for (int j = centerCol - distance; j <= centerCol + distance; ++j) { -// if (i >= 0 && i < POWERTABLE_CAD_SIZE && j >= 0 && j < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// extrapolateCell(i, j); -// } -// } -// } -// } -// // Extrapolate each empty cell -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// // Extrapolate horizontally -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// // Find nearest left non-empty cell -// int left = j - 1; -// while (left >= 0 && this->tableRow[i].tableEntry[left].targetPosition == INT16_MIN) left--; - -// // Find nearest right non-empty cell -// int right = j + 1; -// while (right < POWERTABLE_WATT_SIZE && this->tableRow[i].tableEntry[right].targetPosition == INT16_MIN) right++; -// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN) { -// if (left >= 0 && right < POWERTABLE_WATT_SIZE) { -// // Linear extrapolation -// if (j < left) { -// // Extrapolate to the left -// tempValue = this->tableRow[i].tableEntry[left].targetPosition - -// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (left - j); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } - -// } else if (j > right) { -// // Extrapolate to the right -// tempValue = this->tableRow[i].tableEntry[right].targetPosition + -// (this->tableRow[i].tableEntry[right].targetPosition - this->tableRow[i].tableEntry[left].targetPosition) / (right - left) * (j - right); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } else if (left >= 1) { -// // Only left value available, extrapolate to the right -// if (this->tableRow[i].tableEntry[left].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[left - 1].targetPosition != INT16_MIN) { -// tempValue = this->tableRow[i].tableEntry[left].targetPosition + -// (j - left) * (left > 0 ? this->tableRow[i].tableEntry[left].targetPosition - this->tableRow[i].tableEntry[left - 1].targetPosition : 1); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } else if (right + 1 < POWERTABLE_WATT_SIZE) { -// // Only right value available, extrapolate to the left -// if (this->tableRow[i].tableEntry[right].targetPosition != INT16_MIN && this->tableRow[i].tableEntry[right + 1].targetPosition != INT16_MIN) { -// tempValue = this->tableRow[i].tableEntry[right].targetPosition - -// (right - j) * -// (right < POWERTABLE_WATT_SIZE - 1 ? this->tableRow[i].tableEntry[right + 1].targetPosition - this->tableRow[i].tableEntry[right].targetPosition : 1); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// } -// } -// } -// } - -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// // Extrapolate vertically -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// // Find nearest top non-empty cell -// int top = i - 1; -// while (top >= 0 && this->tableRow[top].tableEntry[j].targetPosition == INT16_MIN) top--; - -// // Find nearest bottom non-empty cell -// int bottom = i + 1; -// while (bottom < POWERTABLE_CAD_SIZE && this->tableRow[bottom].tableEntry[j].targetPosition == INT16_MIN) bottom++; - -// if (top >= 0 && bottom < POWERTABLE_CAD_SIZE) { -// // Linear extrapolation -// if (i < top) { -// // Extrapolate upwards -// tempValue = this->tableRow[top].tableEntry[j].targetPosition - -// (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (top - i); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } else if (i > bottom) { -// // Extrapolate downwards -// tempValue = this->tableRow[bottom].tableEntry[j].targetPosition + -// (this->tableRow[bottom].tableEntry[j].targetPosition - this->tableRow[top].tableEntry[j].targetPosition) / (bottom - top) * (i - bottom); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } else if (top >= 1) { -// // Only top value available, extrapolate downwards -// if (this->tableRow[top].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[top - 1].tableEntry[j].targetPosition != INT16_MIN) { -// tempValue = this->tableRow[top].tableEntry[j].targetPosition + -// (i - top) * (top > 0 ? this->tableRow[top].tableEntry[j].targetPosition - this->tableRow[top - 1].tableEntry[j].targetPosition : 1); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } else { -// } -// } -// } else if (bottom + 1 < POWERTABLE_CAD_SIZE) { -// // Only bottom value available, extrapolate upwards -// if (this->tableRow[bottom].tableEntry[j].targetPosition != INT16_MIN && this->tableRow[bottom + 1].tableEntry[j].targetPosition != INT16_MIN) { -// tempValue = this->tableRow[bottom].tableEntry[j].targetPosition - -// (bottom - i) * -// (bottom < POWERTABLE_CAD_SIZE - 1 ? this->tableRow[bottom + 1].tableEntry[j].targetPosition - this->tableRow[bottom].tableEntry[j].targetPosition : 1); -// if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// } -// } -// } -// } - -// void PowerTable::extrapolateDiagonal() { -// int tempValue = INT16_MIN; - -// for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { -// for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { -// if (this->tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { -// // Find nearest top-left non-empty cell -// int topLeftRow = i - 1, topLeftCol = j - 1; -// while (topLeftRow >= 0 && topLeftCol >= 0 && this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition == INT16_MIN) { -// topLeftRow--; -// topLeftCol--; -// } - -// // Find nearest bottom-right non-empty cell -// int bottomRightRow = i + 1, bottomRightCol = j + 1; -// while (bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE && -// this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition == INT16_MIN) { -// bottomRightRow++; -// bottomRightCol++; -// } - -// // Perform diagonal extrapolation (top-left to bottom-right) -// if (topLeftRow >= 0 && topLeftCol >= 0 && bottomRightRow < POWERTABLE_CAD_SIZE && bottomRightCol < POWERTABLE_WATT_SIZE) { -// tempValue = -// this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition + -// ((this->tableRow[bottomRightRow].tableEntry[bottomRightCol].targetPosition - this->tableRow[topLeftRow].tableEntry[topLeftCol].targetPosition) * (j - topLeftCol)) / -// (bottomRightCol - topLeftCol); - -// if (testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } - -// // If diagonal top-left to bottom-right is not enough, try top-right to bottom-left -// if (tempValue == INT16_MIN) { -// // Find nearest top-right non-empty cell -// int topRightRow = i - 1, topRightCol = j + 1; -// while (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition == INT16_MIN) { -// topRightRow--; -// topRightCol++; -// } - -// // Find nearest bottom-left non-empty cell -// int bottomLeftRow = i + 1, bottomLeftCol = j - 1; -// while (bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0 && this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition == INT16_MIN) { -// bottomLeftRow++; -// bottomLeftCol--; -// } - -// // Perform diagonal extrapolation (top-right to bottom-left) -// if (topRightRow >= 0 && topRightCol < POWERTABLE_WATT_SIZE && bottomLeftRow < POWERTABLE_CAD_SIZE && bottomLeftCol >= 0) { -// tempValue = this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition + -// ((this->tableRow[bottomLeftRow].tableEntry[bottomLeftCol].targetPosition - this->tableRow[topRightRow].tableEntry[topRightCol].targetPosition) * -// (j - bottomLeftCol)) / -// (topRightCol - bottomLeftCol); - -// if (testNeighbors(i, j, tempValue).allNeighborsPassed) { -// this->tableRow[i].tableEntry[j].targetPosition = tempValue; -// } -// } -// } -// } -// } -// } -// } - void PowerTable::extrapFillTable() { extrapFillTableDirection(true); // Horizontal extrapFillTableDirection(false); // Vertical @@ -1019,85 +677,87 @@ void PowerTable::extrapFillTableDirection(bool horizontal) { std::sort(unique_xy.begin(), unique_xy.end()); - for (const auto& it : unique_xy) { - x.push_back(static_cast(it.first)); - y.push_back(static_cast(it.second)); - } + for (std::vector>::const_iterator it = unique_xy.begin(); it != unique_xy.end(); ++it) { + x.push_back(it->first); + y.push_back(it->second); + } // Determine spline type (natural or clamped) - bool useNaturalSpline = shouldUseNaturalSpline(x, y); + bool useNaturalSpline = shouldUseNaturalSpline(x.data(), y.data(), x.size()); // Fill empty table entries using the determined spline type - extrapolateEmptyIndices(outerIndex, emptyIndices, x, y, horizontal, useNaturalSpline); + extrapolateEmptyIndices(outerIndex, emptyIndices, x.data(), y.data(), x.size(), horizontal, useNaturalSpline); } } -void PowerTable::extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, const std::vector& x, const std::vector& y, bool horizontal, bool naturalSpline) { - int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; +void PowerTable::extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, const double* x, const double* y, size_t n, bool horizontal, bool naturalSpline) { - if (x.size() == 1) { - int singleValue = static_cast(std::round(y.front())); - for (int innerIndex : emptyIndices) { - int i = horizontal ? outerIndex : innerIndex; - int j = horizontal ? innerIndex : outerIndex; - this->tableRow[i].tableEntry[j].targetPosition = singleValue; - } - } else if (x.size() == 2) { - for (int innerIndex : emptyIndices) { - int i = horizontal ? outerIndex : innerIndex; - int j = horizontal ? innerIndex : outerIndex; + int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; + + if (n == 1) { + int singleValue = static_cast(std::round(y[0])); + for (int innerIndex : emptyIndices) { + int i = horizontal ? outerIndex : innerIndex; + int j = horizontal ? innerIndex : outerIndex; + this->tableRow[i].tableEntry[j].targetPosition = singleValue; + } + } else if (n == 2) { + for (int innerIndex : emptyIndices) { + int i = horizontal ? outerIndex : innerIndex; + int j = horizontal ? innerIndex : outerIndex; - double extrapolated_value = linearExtrapolate(x, y, innerIndex); - int tempValue = static_cast(std::round(extrapolated_value)); + double extrapolated_value = linearExtrapolate(x, y, n, innerIndex); + int tempValue = static_cast(std::round(extrapolated_value)); - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } } - } else if (x.size() >= 3) { - bool validForSpline = true; - for (size_t i = 1; i < x.size(); ++i) { + } + } else if (n >= 3) { + bool validForSpline = true; + for (size_t i = 1; i < n; ++i) { if (x[i] <= x[i - 1]) { - validForSpline = false; - break; + validForSpline = false; + break; } - } - if (!validForSpline) { + } + if (!validForSpline) { SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); return; - } + } - CubicSpline spline; - spline.set_points(x, y, naturalSpline); // Pass spline type + CubicSpline spline; + spline.set_points(x, y, n, naturalSpline); // Pass pointer-based data - for (int innerIndex : emptyIndices) { + for (int innerIndex : emptyIndices) { int i = horizontal ? outerIndex : innerIndex; int j = horizontal ? innerIndex : outerIndex; double extrapolated_value = spline.extrapolate(innerIndex); - double minVal = *std::min_element(y.begin(), y.end()); - double maxVal = *std::max_element(y.begin(), y.end()); + double minVal = *std::min_element(y, y + n); + double maxVal = *std::max_element(y, y + n); double range = maxVal - minVal; extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); int tempValue = static_cast(std::round(extrapolated_value)); - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } } } } + void PowerTable::extrapolateDiagonal() { - std::vector> unique_xy; // Use vector for memory efficiency + std::vector> unique_xy; std::vector> emptyIndices; - // Iterate over different diagonals + // Iterate over different diagonals (sum of indices is constant) for (int sum = 0; sum < POWERTABLE_CAD_SIZE + POWERTABLE_WATT_SIZE - 1; ++sum) { unique_xy.clear(); emptyIndices.clear(); - // Collect known values for this diagonal (sum of indices is constant) + // Collect known values for this diagonal for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { int j = sum - i; if (j >= 0 && j < POWERTABLE_WATT_SIZE) { @@ -1111,73 +771,15 @@ void PowerTable::extrapolateDiagonal() { if (unique_xy.size() < 2) continue; // Skip if not enough data - std::sort(unique_xy.begin(), unique_xy.end()); // Sort by the 'x' coordinate (i) + std::sort(unique_xy.begin(), unique_xy.end()); std::vector x, y; - for (const auto& it : unique_xy) { - x.push_back(it.first); - y.push_back(it.second); - } - - if (x.size() == 1) { - int singleValue = static_cast(std::round(y.front())); - for (const auto& it : emptyIndices) { - this->tableRow[it.first].tableEntry[it.second].targetPosition = singleValue; - } - continue; + for (std::vector>::const_iterator it = unique_xy.begin(); it != unique_xy.end(); ++it) { + x.push_back(it->first); + y.push_back(it->second); } - if (x.size() == 2) { - for (const auto& it : emptyIndices) { - int i = it.first; - int j = it.second; - - double extrapolated_value = linearExtrapolate(x, y, i); - - int tempValue = static_cast(std::round(extrapolated_value)); - - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - continue; - } - - if (x.size() >= 3) { - bool validForSpline = true; - for (size_t k = 1; k < x.size(); ++k) { - if (x[k] <= x[k - 1]) { - validForSpline = false; - break; - } - } - if (!validForSpline) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected for diagonal!"); - continue; - } - - CubicSpline spline; - spline.set_points(x, y); - - for (const auto& it : emptyIndices) { - int i = it.first; - int j = it.second; - - if (i < 0 || i >= POWERTABLE_CAD_SIZE || j < 0 || j >= POWERTABLE_WATT_SIZE) continue; - - double extrapolated_value = spline.extrapolate(i); - - double minVal = *std::min_element(y.begin(), y.end()); - double maxVal = *std::max_element(y.begin(), y.end()); - double range = maxVal - minVal; - extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); - - int tempValue = static_cast(std::round(extrapolated_value)); - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } + extrapolateDiagonalEntries(emptyIndices, x.data(), y.data(), x.size()); } // Iterate over other set of diagonals (where difference of indices is constant) @@ -1206,68 +808,73 @@ void PowerTable::extrapolateDiagonal() { y.push_back(it.second); } - if (x.size() == 1) { - int singleValue = static_cast(std::round(y.front())); - for (const auto& it : emptyIndices) { - this->tableRow[it.first].tableEntry[it.second].targetPosition = singleValue; - } - continue; - } + extrapolateDiagonalEntries(emptyIndices, x.data(), y.data(), x.size()); + } +} - if (x.size() == 2) { - for (const auto& it : emptyIndices) { - int i = it.first; - int j = it.second; +void PowerTable::extrapolateDiagonalEntries(const std::vector>& emptyIndices, const double* x, const double* y, size_t n) { - double extrapolated_value = linearExtrapolate(x, y, i); + if (n == 1) { + int singleValue = static_cast(std::round(y[0])); + for (std::vector>::const_iterator it = emptyIndices.begin(); it != emptyIndices.end(); ++it) { + this->tableRow[it->first].tableEntry[it->second].targetPosition = singleValue; + } + return; + } - int tempValue = static_cast(std::round(extrapolated_value)); + if (n == 2) { + for (std::vector>::const_iterator it = emptyIndices.begin(); it != emptyIndices.end(); ++it) { + int i = it->first; + int j = it->second; - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + double extrapolated_value = linearExtrapolate(x, y, n, i); + int tempValue = static_cast(std::round(extrapolated_value)); + + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } - continue; } + return; + } - if (x.size() >= 3) { - bool validForSpline = true; - for (size_t k = 1; k < x.size(); ++k) { - if (x[k] <= x[k - 1]) { - validForSpline = false; - break; - } - } - if (!validForSpline) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected for diagonal!"); - continue; + if (n >= 3) { + bool validForSpline = true; + for (size_t k = 1; k < n; ++k) { + if (x[k] <= x[k - 1]) { + validForSpline = false; + break; } + } + if (!validForSpline) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected for diagonal!"); + return; + } - CubicSpline spline; - spline.set_points(x, y); + CubicSpline spline; + spline.set_points(x, y, n); - for (const auto& it : emptyIndices) { - int i = it.first; - int j = it.second; + for (std::vector>::const_iterator it = emptyIndices.begin(); it != emptyIndices.end(); ++it) { + int i = it->first; + int j = it->second; - if (i < 0 || i >= POWERTABLE_CAD_SIZE || j < 0 || j >= POWERTABLE_WATT_SIZE) continue; + if (i < 0 || i >= POWERTABLE_CAD_SIZE || j < 0 || j >= POWERTABLE_WATT_SIZE) continue; - double extrapolated_value = spline.extrapolate(i); + double extrapolated_value = spline.extrapolate(i); - double minVal = *std::min_element(y.begin(), y.end()); - double maxVal = *std::max_element(y.begin(), y.end()); - double range = maxVal - minVal; - extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); + double minVal = *std::min_element(y, y + n); + double maxVal = *std::max_element(y, y + n); + double range = maxVal - minVal; + extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); - int tempValue = static_cast(std::round(extrapolated_value)); - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } + int tempValue = static_cast(std::round(extrapolated_value)); + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; } } } } + int PowerTable::getNumEntries() { int ret = 0; for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { From 97fc85c6c9cb339b79de9f6f693c1ca469608638 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Thu, 20 Mar 2025 08:57:24 -0500 Subject: [PATCH 137/451] removed Telegram references, enabled ERG Guardrails --- include/HTTP_Server_Basic.h | 9 ----- include/settings.h | 19 +--------- src/BLE_Client.cpp | 3 -- src/BLE_Server.cpp | 3 -- src/HTTP_Server_Basic.cpp | 72 ------------------------------------- src/SensorCollector.cpp | 3 -- 6 files changed, 1 insertion(+), 108 deletions(-) diff --git a/include/HTTP_Server_Basic.h b/include/HTTP_Server_Basic.h index d2c3b1df..4fb684a7 100644 --- a/include/HTTP_Server_Basic.h +++ b/include/HTTP_Server_Basic.h @@ -30,15 +30,6 @@ class HTTP_Server { HTTP_Server() { internetConnection = false; } }; -#ifdef USE_TELEGRAM -#define SEND_TO_TELEGRAM(message) sendTelegram(message); - -void sendTelegram(String textToSend); -void telegramUpdate(void *pvParameters); -#else -#define SEND_TO_TELEGRAM(message) (void)message -#endif - // wifi Function void startWifi(); void stopWifi(); diff --git a/include/settings.h b/include/settings.h index e4f936eb..d292b0a6 100644 --- a/include/settings.h +++ b/include/settings.h @@ -254,7 +254,7 @@ const char* const DEFAULT_PASSWORD = "password"; #define RUNTIMECONFIG_JSON_SIZE 1000 + DEBUG_LOG_BUFFER_SIZE // Uncomment to use guardrails for ERG mode in the stepper loop. -// #define ERG_GUARDRAILS +#define ERG_GUARDRAILS //Uncomment to enable the use of the power table for ERG mode. #define ERG_MODE_USE_POWER_TABLE @@ -348,10 +348,6 @@ const char* const DEFAULT_PASSWORD = "password"; // Uncomment to enable stack size debugging info //#define DEBUG_STACK -// Uncomment to enable sending Telegram debug messages back to the chat -// specified in telegram_token.h -// #define USE_TELEGRAM - // Uncomment to enable HR->PWR debugging info. Always displays HR->PWR // Calculation. Never sets userConfig->setSimulatedPower(); // #define DEBUG_HR_TO_PWR @@ -365,16 +361,3 @@ const char* const DEFAULT_PASSWORD = "password"; // UNcomment to enable Custom Characteristic Logging // #define CUSTOM_CHAR_DEBUG -#ifdef USE_TELEGRAM -// Max number of telegram messages to send per session -#define MAX_TELEGRAM_MESSAGES 1 -// Filler definitions for if telegram_token.h is not included (because it has -// sensitive information). Do not change these as this file is tracked and -// therefore public. Enter your own Telegram info into telegram_token.h -#if __has_include("telegram_token.h") -#include "telegram_token.h" -#else -#define TELEGRAM_TOKEN "1234567890:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi" -#define TELEGRAM_CHAT_ID "1234567890" -#endif -#endif diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index 3211701f..7191f2b9 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -558,9 +558,6 @@ void ScanCallbacks::onScanEnd(const NimBLEScanResults &results, int reason) { String output; serializeJson(devices, output); // SS2K_LOG(BLE_CLIENT_LOG_TAG, "Found Devices: %s", output.c_str()); -#ifdef USE_TELEGRAM - SEND_TO_TELEGRAM("Bluetooth Client Found Devices: " + output); -#endif userConfig->setFoundDevices(output); // Save the updated JSON document } diff --git a/src/BLE_Server.cpp b/src/BLE_Server.cpp index 8c162674..70d3aea1 100644 --- a/src/BLE_Server.cpp +++ b/src/BLE_Server.cpp @@ -287,8 +287,5 @@ void logCharacteristic(char* buffer, const size_t bufferCapacity, const byte* da va_end(args); SS2K_LOG(BLE_SERVER_LOG_TAG, "%s", buffer); -#ifdef USE_TELEGRAM - SEND_TO_TELEGRAM(String(buffer)); -#endif #endif } diff --git a/src/HTTP_Server_Basic.cpp b/src/HTTP_Server_Basic.cpp index e17ef0e7..17e4c248 100644 --- a/src/HTTP_Server_Basic.cpp +++ b/src/HTTP_Server_Basic.cpp @@ -22,7 +22,6 @@ #include #include #include -#include File fsUploadFile; @@ -35,14 +34,6 @@ HTTP_Server httpServer; WiFiClientSecure client; WebServer server(80); -#ifdef USE_TELEGRAM -#include -TaskHandle_t telegramTask; -bool telegramMessageWaiting = false; -UniversalTelegramBot bot(TELEGRAM_TOKEN, client); -String telegramMessage = ""; -#endif // USE_TELEGRAM - void _staSetup() { WiFi.setHostname(userConfig->getDeviceName()); WiFi.mode(WIFI_STA); @@ -118,9 +109,6 @@ void startWifi() { MDNS.addService("http", "_tcp", 80); MDNS.addServiceTxt("http", "_tcp", "lf", "0"); SS2K_LOG(HTTP_SERVER_LOG_TAG, "Connected to %s IP address: %s", userConfig->getSsid(), myIP.toString().c_str()); -#ifdef USE_TELEGRAM - SEND_TO_TELEGRAM("Connected to " + String(userConfig->getSsid()) + " IP address: " + myIP.toString()); -#endif SS2K_LOG(HTTP_SERVER_LOG_TAG, "Open http://%s.local/", userConfig->getDeviceName()); WiFi.setTxPower(WIFI_POWER_19_5dBm); @@ -398,15 +386,6 @@ void HTTP_Server::start() { /********************************************End Server * Handlers*******************************/ -#ifdef USE_TELEGRAM - xTaskCreatePinnedToCore(telegramUpdate, /* Task function. */ - "telegramUpdate", /* name of task. */ - 4900, /* Stack size of task*/ - NULL, /* parameter of the task */ - 1, /* priority of the task - higher number is higher priority*/ - &telegramTask, /* Task handle to keep track of created task */ - 1); /* pin task to core 1 */ -#endif // USE_TELEGRAM server.begin(); server.enableDelay(false); SS2K_LOG(HTTP_SERVER_LOG_TAG, "HTTP server started"); @@ -774,54 +753,3 @@ void HTTP_Server::FirmwareUpdate() { } } -#ifdef USE_TELEGRAM -// Function to handle sending telegram text to the non blocking task -void sendTelegram(String textToSend) { - static int numberOfMessages = 0; - static uint64_t timeout = 120000; // reset every two minutes - static uint64_t startTime = millis(); - - if (millis() - startTime > timeout) { // Let one message send every two minutes - numberOfMessages = MAX_TELEGRAM_MESSAGES - 1; - telegramMessage += " " + String(userConfig->getSsid()) + " "; - startTime = millis(); - } - - if ((numberOfMessages < MAX_TELEGRAM_MESSAGES) && (WiFi.getMode() == WIFI_STA)) { - telegramMessage += "\n" + textToSend; - telegramMessageWaiting = true; - numberOfMessages++; - } -} - -// Non blocking task to send telegram message -void telegramUpdate(void *pvParameters) { - // client.setInsecure(); - client.setCACert(TELEGRAM_CERTIFICATE_ROOT); - for (;;) { - static int telegramFailures = 0; - if (telegramMessageWaiting && internetConnection) { - telegramMessageWaiting = false; - bool rm = (bot.sendMessage(TELEGRAM_CHAT_ID, telegramMessage, "")); - if (!rm) { - telegramFailures++; - SS2K_LOG(HTTP_SERVER_LOG_TAG, "Telegram failed to send! %s", TELEGRAM_CHAT_ID); - if (telegramFailures > 2) { - internetConnection = false; - } - } else { // Success - reset Telegram Failures - telegramFailures = 0; - } - - client.stop(); - telegramMessage = ""; - } -#ifdef DEBUG_STACK - Serial.printf("Telegram: %d \n", uxTaskGetStackHighWaterMark(telegramTask)); - Serial.printf("Web: %d \n", uxTaskGetStackHighWaterMark(webClientTask)); - Serial.printf("Free: %d \n", ESP.getFreeHeap()); -#endif // DEBUG_STACK - vTaskDelay(4000 / portTICK_RATE_MS); - } -} -#endif // USE_TELEGRAM diff --git a/src/SensorCollector.cpp b/src/SensorCollector.cpp index 3cf686aa..4c8af4ea 100644 --- a/src/SensorCollector.cpp +++ b/src/SensorCollector.cpp @@ -98,7 +98,4 @@ void collectAndSet(NimBLEUUID charUUID, NimBLEUUID serviceUUID, NimBLEAddress ad if (charUUID == PELOTON_DATA_UUID) lastTime = millis(); #endif -#ifdef USE_TELEGRAM - SEND_TO_TELEGRAM(String(logBuf)); -#endif } \ No newline at end of file From 9df75b2178e2213aeabbe5b8fb44ccc98c8e27a9 Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Thu, 20 Mar 2025 16:25:14 -0500 Subject: [PATCH 138/451] created new targetPosition function --- include/Power_Table.h | 2 ++ src/Power_Table.cpp | 82 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 69 insertions(+), 15 deletions(-) diff --git a/include/Power_Table.h b/include/Power_Table.h index d3710b55..abc9e9e0 100644 --- a/include/Power_Table.h +++ b/include/Power_Table.h @@ -142,6 +142,8 @@ class PowerTable { void extrapolateDiagonalEntries(const std::vector>& emptyIndices, const double* x, const double* y, size_t n); + float calculatePosition(float watts, float cad, float targetPos, int i, int k); + private: unsigned long lastSaveTime = millis(); TestResults testNeighbors(int i, int j, int value); diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index bba7a8f4..a011eff3 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -551,8 +551,8 @@ void PowerTable::findTableDirection(bool horizontal) { x.clear(); y.clear(); - int rangeStart = std::max(0, innerSize / 2 - 10); - int rangeEnd = std::min(innerSize, innerSize / 2 + 10); + int rangeStart = std::max(0, innerSize / 2 - 5); + int rangeEnd = std::min(innerSize, innerSize / 2 + 5); for (int innerValue = rangeStart; innerValue < rangeEnd; ++innerValue) { int i = horizontal ? outerValue : innerValue; @@ -562,9 +562,7 @@ void PowerTable::findTableDirection(bool horizontal) { if (targetPos != INT16_MIN) { unique_xy.emplace_back(innerValue, static_cast(targetPos)); } else { - if (emptyIndices.empty() || innerValue - emptyIndices.back() >= 5) { emptyIndices.push_back(innerValue); - } } } @@ -949,6 +947,8 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { return; } + targetPosition = this->calculatePosition(watts, cad, targetPosition, k, i); + // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table TestResults testResults = this->testNeighbors(k, i, targetPosition); if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { @@ -1127,20 +1127,20 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { BLE_ss2kCustomCharacteristic::notify(0x27, k); } -void PowerTable::enterData(int i, int j, int pos) { - if (this->tableRow[i].tableEntry[j].readings <= 0) { // if first reading in this entry - this->tableRow[i].tableEntry[j].targetPosition = pos; - SS2K_LOG(POWERTABLE_LOG_TAG, "New entry recorded (%d)(%d)(%d)", i, j, this->tableRow[i].tableEntry[j].targetPosition); +void PowerTable::enterData(int k, int i, int pos) { + if (this->tableRow[k].tableEntry[i].readings <= 0) { // if first reading in this entry + this->tableRow[k].tableEntry[i].targetPosition = pos; + SS2K_LOG(POWERTABLE_LOG_TAG, "New entry recorded (%d)(%d)(%d)", k, i, this->tableRow[k].tableEntry[i].targetPosition); } else { // Average and update the readings. - this->tableRow[i].tableEntry[j].targetPosition = - (pos + (this->tableRow[i].tableEntry[j].targetPosition * this->tableRow[i].tableEntry[j].readings)) / (this->tableRow[i].tableEntry[j].readings + 1.0); - SS2K_LOG(POWERTABLE_LOG_TAG, "Existing entry averaged (%d)(%d)(%d), readings(%d)", i, j, this->tableRow[i].tableEntry[j].targetPosition, - this->tableRow[i].tableEntry[j].readings); - if (this->tableRow[i].tableEntry[j].readings > POWER_SAMPLES * 2) { - this->tableRow[i].tableEntry[j].readings = POWER_SAMPLES * 2; // keep from diluting recent readings too far. + this->tableRow[k].tableEntry[i].targetPosition = + (pos + (this->tableRow[k].tableEntry[i].targetPosition * this->tableRow[k].tableEntry[i].readings)) / (this->tableRow[k].tableEntry[i].readings + 1.0); + SS2K_LOG(POWERTABLE_LOG_TAG, "Existing entry averaged (%d)(%d)(%d), readings(%d)", k, i, this->tableRow[k].tableEntry[i].targetPosition, + this->tableRow[k].tableEntry[i].readings); + if (this->tableRow[k].tableEntry[i].readings > POWER_SAMPLES * 2) { + this->tableRow[k].tableEntry[i].readings = POWER_SAMPLES * 2; // keep from diluting recent readings too far. } } - this->tableRow[i].tableEntry[j].readings++; + this->tableRow[k].tableEntry[i].readings++; if (this->getNumEntries() > 4) { int entries = 0; @@ -1156,6 +1156,58 @@ void PowerTable::enterData(int i, int j, int pos) { } } +float PowerTable::calculatePosition(float watts, float cad, float targetPos, int k, int i){ + + TestResults testResults = this->testNeighbors(k, i, targetPos); + + if(this->tableRow[k].tableEntry[i].targetPosition == INT16_MIN || + !(testResults.bottomNeighbor.passedTest || testResults.topNeighbor.passedTest || testResults.rightNeighbor.passedTest || testResults.leftNeighbor.passedTest) || + this->tableRow[k].tableEntry[i].targetPosition == targetPos) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Keep old targetPosition: (%f)", targetPos); + return targetPos; + } + + int wattPosition = POWERTABLE_WATT_INCREMENT * i; + int cadPosition = MINIMUM_TABLE_CAD + (POWERTABLE_CAD_INCREMENT * k); + + float rightValue = 0.0f, leftValue = 0.0f, topValue = 0.0f, bottomValue = 0.0f; + + int cellValue = this->tableRow[k].tableEntry[i].targetPosition; + float wattDelta = float(POWERTABLE_WATT_INCREMENT)/(abs(targetPos - float(cellValue))); + float cadDelta = float(POWERTABLE_CAD_INCREMENT)/(abs(targetPos - float(cellValue))); + + SS2K_LOG(POWERTABLE_LOG_TAG, "cellValue: (%d) wattDelta: (%f) cadDelta: (%f) allNeighborsPassed: (%d)", cellValue, wattDelta, cadDelta, testResults.allNeighborsPassed); + + int count = 0; + + if(testResults.rightNeighbor.passedTest){ + float x = abs(watts - float(wattPosition + POWERTABLE_WATT_INCREMENT)); + rightValue = targetPos - (x/wattDelta); + count++; + } + if(testResults.leftNeighbor.passedTest){ + float x = abs(watts - float(wattPosition - POWERTABLE_WATT_INCREMENT)); + leftValue = targetPos - (x/wattDelta); + count++; + } + if(testResults.bottomNeighbor.passedTest){ + float x = abs(cad - float(cadPosition + POWERTABLE_CAD_INCREMENT)); + bottomValue = targetPos - (x/cadDelta); + count++; + } + if(testResults.topNeighbor.passedTest){ + float x = abs(cad - float(cadPosition - POWERTABLE_CAD_INCREMENT)); + topValue = targetPos - (x/cadDelta); + count++; + } + + targetPos = (rightValue + leftValue + topValue + bottomValue)/float(count); + SS2K_LOG(POWERTABLE_LOG_TAG, "rightValue: (%f) leftValue: (%f) bottomValue: (%f) topValue: (%f) New averaged targetPosition: (%f) count: (%d)", + rightValue, leftValue, bottomValue, topValue, targetPos, count); + + return targetPos; +} + // function for weighted downvoting int weightedDownVote(int targetValue, int neighborValue) { // calculate diff between target and neighbor From cef9d1a593d8f356035971db466dcf5fe1c76e0f Mon Sep 17 00:00:00 2001 From: benv12 <151891474+benv12@users.noreply.github.com> Date: Thu, 20 Mar 2025 19:00:31 -0500 Subject: [PATCH 139/451] changed doubles to float, implemented range for extrap, and modified extrap functiosn --- include/Power_Table.h | 10 +- src/Power_Table.cpp | 663 ++++++++++++++++++++++-------------------- 2 files changed, 354 insertions(+), 319 deletions(-) diff --git a/include/Power_Table.h b/include/Power_Table.h index abc9e9e0..9f784ef6 100644 --- a/include/Power_Table.h +++ b/include/Power_Table.h @@ -132,18 +132,22 @@ class PowerTable { // Display power table in log void toLog(); - void fillEmptyTable(int outerValue, const std::vector& emptyIndices, const double* x, const double* y, size_t n, bool horizontal, bool useNaturalSpline); + void fillEmptyTable(int outerValue, const std::vector& emptyIndices, const float* x, const float* y, size_t n, bool horizontal, bool useNaturalSpline); void findTableDirection(bool horizontal); void extrapFillTableDirection(bool horizontal); - void extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, const double* x, const double* y, size_t n, bool horizontal, bool naturalSpline); + void extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, const float* x, const float* y, size_t n, bool horizontal, bool naturalSpline); - void extrapolateDiagonalEntries(const std::vector>& emptyIndices, const double* x, const double* y, size_t n); + void extrapolateDiagonalEntries(const std::vector>& emptyIndices, const float* x, const float* y, size_t n); float calculatePosition(float watts, float cad, float targetPos, int i, int k); + float linearInterpolate(const float* x, const float* y, size_t n, float j); + + float linearExtrapolate(const float* x, const float* y, size_t n, float j); + private: unsigned long lastSaveTime = millis(); TestResults testNeighbors(int i, int j, int value); diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index a011eff3..4b4fa663 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -369,31 +369,27 @@ TestResults PowerTable::testNeighbors(int i, int j, int testValue) { * due to invalid input (e.g., duplicate x values), the function logs an error * and returns `INT16_MIN`. */ -double linearInterpolate(const double* x, const double* y, size_t n, double j) { +float PowerTable::linearInterpolate(const float* x, const float* y, size_t n, float j) { auto upper = std::upper_bound(x, x + n, j); if (upper == x + n) return y[n - 1]; // Extrapolate using last value if (upper == x) return y[0]; // Extrapolate using first value auto lower = upper - 1; - double x0 = *lower, x1 = *upper; - double y0 = y[lower - x], y1 = y[upper - x]; + float x0 = *lower, x1 = *upper; + float y0 = y[lower - x], y1 = y[upper - x]; - // Log and comment if x1 - x0 is 0 if (x1 - x0 == 0) { SS2K_LOG(POWERTABLE_LOG_TAG, "Linear Interpolation failed, x1 - x0 is 0"); return INT16_MIN; } - double interpolated_value = y0 + (y1 - y0) * (j - x0) / (x1 - x0); + return y0 + (y1 - y0) * (j - x0) / (x1 - x0); - double minValue = *std::min_element(y, y + n); - double maxValue = *std::max_element(y, y + n); - return std::max(minValue, std::min(maxValue, interpolated_value)); } -double linearExtrapolate(const double* x, const double* y, size_t n, double j) { - double x0, x1, y0, y1; +float PowerTable::linearExtrapolate(const float* x, const float* y, size_t n, float j) { + float x0, x1, y0, y1; if (j < x[0]) { x0 = x[0], x1 = x[1]; @@ -413,15 +409,13 @@ double linearExtrapolate(const double* x, const double* y, size_t n, double j) { return INT16_MIN; } - double slope = (y1 - y0) / (x1 - x0); + float slope = (y1 - y0) / (x1 - x0); return y0 + slope * (j - x0); } - class CubicSpline { public: - void set_points(const double* x_vals, const double* y_vals, size_t n, bool natural = true) { - + void set_points(const float* x_vals, const float* y_vals, size_t n, bool natural = true) { if (n < 2) return; // Safe check to make sure we have enough points size_t last_index = n - 1; @@ -429,108 +423,120 @@ class CubicSpline { y.assign(y_vals, y_vals + n); h.resize(last_index); - alpha.resize(n); - l.resize(n); - mu.resize(n); - z.resize(n); - c.resize(n, 0.0); - b.resize(last_index); - d.resize(last_index); + alpha.resize(n, 0.0f); + l.resize(n, 0.0f); + mu.resize(n, 0.0f); + z.resize(n, 0.0f); + c.resize(n, 0.0f); + b.resize(last_index, 0.0f); + d.resize(last_index, 0.0f); // Get h values - for (size_t i = 0; i < last_index; ++i) + for (size_t i = 0; i < last_index; ++i) { h[i] = x[i + 1] - x[i]; + if (h[i] == 0.0f) { + SS2K_LOG(POWERTABLE_LOG_TAG, "CubicSpline: Duplicate x values detected."); + return; + } + } - // gEt alpha values - for (size_t i = 1; i < last_index; ++i) - alpha[i] = (3.0 / h[i]) * (y[i + 1] - y[i]) - (3.0 / h[i - 1]) * (y[i] - y[i - 1]); + // Get alpha values + for (size_t i = 1; i < last_index; ++i) { + alpha[i] = (3.0f / h[i]) * (y[i + 1] - y[i]) - (3.0f / h[i - 1]) * (y[i] - y[i - 1]); + } // Check if we are using natural or clamped spline calculations if (natural) { - alpha[0] = alpha[last_index] = 0.0; + alpha[0] = alpha[last_index] = 0.0f; } else { - double f_prime_start = (y[1] - y[0]) / h[0]; - double f_prime_end = (y[last_index] - y[last_index - 1]) / h[last_index - 1]; - alpha[0] = 3.0 * ((y[1] - y[0]) / h[0] - f_prime_start); - alpha[last_index] = 3.0 * (f_prime_end - (y[last_index] - y[last_index - 1]) / h[last_index - 1]); + float f_prime_start = (y[1] - y[0]) / h[0]; + float f_prime_end = (y[last_index] - y[last_index - 1]) / h[last_index - 1]; + alpha[0] = 3.0f * (f_prime_start - (y[1] - y[0]) / h[0]); + alpha[last_index] = 3.0f * ((y[last_index] - y[last_index - 1]) / h[last_index - 1] - f_prime_end); } // Get l, mu, and z - l[0] = 1.0; - mu[0] = z[0] = 0.0; + l[0] = 1.0f; + mu[0] = z[0] = 0.0f; for (size_t i = 1; i < last_index; ++i) { - l[i] = 2.0 * (x[i + 1] - x[i - 1]) - h[i - 1] * mu[i - 1]; + l[i] = 2.0f * (x[i + 1] - x[i - 1]) - h[i - 1] * mu[i - 1]; + if (l[i] == 0.0f) { + SS2K_LOG(POWERTABLE_LOG_TAG, "CubicSpline: Zero denominator detected in l[i]."); + return; + } mu[i] = h[i] / l[i]; z[i] = (alpha[i] - h[i - 1] * z[i - 1]) / l[i]; } - l[last_index] = 1.0; - z[last_index] = c[last_index] = 0.0; + l[last_index] = 1.0f; + z[last_index] = c[last_index] = 0.0f; for (int j = last_index - 1; j >= 0; --j) { c[j] = z[j] - mu[j] * c[j + 1]; - b[j] = (y[j + 1] - y[j]) / h[j] - h[j] * (c[j + 1] + 2.0 * c[j]) / 3.0; - d[j] = (c[j + 1] - c[j]) / (3.0 * h[j]); + b[j] = (y[j + 1] - y[j]) / h[j] - h[j] * (c[j + 1] + 2.0f * c[j]) / 3.0f; + d[j] = (c[j + 1] - c[j]) / (3.0f * h[j]); } } - double interpolate(double x_val) const { + float interpolate(float x_val) const { if (x_val < x.front() || x_val > x.back()) { return INT16_MIN; // Out of range } int i = std::upper_bound(x.begin(), x.end(), x_val) - x.begin() - 1; - double dx = x_val - x[i]; + float dx = x_val - x[i]; return y[i] + b[i] * dx + c[i] * dx * dx + d[i] * dx * dx * dx; } - double extrapolate(double x_val) const { + float extrapolate(float x_val) const { if (x_val < x.front()) { - double dx = x_val - x[0]; + float dx = x_val - x[0]; return y[0] + b[0] * dx + c[0] * dx * dx + d[0] * dx * dx * dx; } if (x_val > x.back()) { int n = x.size() - 1; - double dx = x_val - x[n]; + float dx = x_val - x[n]; return y[n] + b[n - 1] * dx + c[n - 1] * dx * dx + d[n - 1] * dx * dx * dx; } return INT16_MIN; // Out of range } private: - std::vector x, y, h, alpha, l, mu, z, c, b, d; + std::vector x, y, h, alpha, l, mu, z, c, b, d; }; - - // Function to determine if a natural spline should be used - bool shouldUseNaturalSpline(const double* x, const double* y, size_t n) { - if (n < 3) return true; // Default to natural spline for small data sets - - // Compute approximate first derivatives at endpoints - double startSlope = (y[1] - y[0]) / (x[1] - x[0]); - double endSlope = (y[n - 1] - y[n - 2]) / (x[n - 1] - x[n - 2]); - - // Adaptive slope threshold - double dataRange = *std::max_element(y, y + n) - *std::min_element(y, y + n); - double slopeThreshold = 0.1 * dataRange; - - // If slope changes significantly, consider using a clamped spline - if (std::abs(startSlope) > slopeThreshold || std::abs(endSlope) > slopeThreshold) { - return false; // Use clamped spline - } - - // Second derivative (curvature) check for smoothness - double secondDerivativeStart = (y[2] - 2 * y[1] + y[0]) / ((x[1] - x[0]) * (x[2] - x[1])); - double secondDerivativeEnd = (y[n - 1] - 2 * y[n - 2] + y[n - 3]) / - ((x[n - 2] - x[n - 3]) * (x[n - 1] - x[n - 2])); - - double curvatureThreshold = 1.0; // Adjust based on expected smoothness - if (std::abs(secondDerivativeStart) > curvatureThreshold || std::abs(secondDerivativeEnd) > curvatureThreshold) { - return false; // Use clamped spline - } - - return true; // Default to natural spline - } + + bool shouldUseNaturalSpline(const float* x, const float* y, size_t n) { + if (n < 3) return true; // Default to natural spline for small data sets + + // Compute approximate first derivatives at endpoints + float startSlope = (y[1] - y[0]) / (x[1] - x[0]); + float endSlope = (y[n - 1] - y[n - 2]) / (x[n - 1] - x[n - 2]); + + // Adaptive slope threshold + float dataRange = *std::max_element(y, y + n) - *std::min_element(y, y + n); + float slopeThreshold = 0.1f * dataRange; + + if (std::abs(startSlope) > slopeThreshold || std::abs(endSlope) > slopeThreshold) { + return false; // Use clamped spline + } + + if (n < 4) return true; // Not enough points for second derivative check + + // Compute second derivatives safely + float h0 = x[1] - x[0], h1 = x[2] - x[1]; + if (h0 == 0.0f || h1 == 0.0f) return true; // Avoid division by zero + + float secondDerivativeStart = (y[2] - 2 * y[1] + y[0]) / (h0 * h1); + + float hn1 = x[n - 2] - x[n - 3], hn2 = x[n - 1] - x[n - 2]; + if (hn1 == 0.0f || hn2 == 0.0f) return true; // Avoid division by zero + + float secondDerivativeEnd = (y[n - 1] - 2 * y[n - 2] + y[n - 3]) / (hn1 * hn2); + + float curvatureThreshold = 1.0f; + return !(std::abs(secondDerivativeStart) > curvatureThreshold || std::abs(secondDerivativeEnd) > curvatureThreshold); +} void PowerTable::fillTable() { this->findTableDirection(true); // Horizontal @@ -541,9 +547,15 @@ void PowerTable::findTableDirection(bool horizontal) { int outerSize = horizontal ? POWERTABLE_CAD_SIZE : POWERTABLE_WATT_SIZE; int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; - std::vector> unique_xy; + std::vector> unique_xy; std::vector emptyIndices; - std::vector x, y; + std::vector x, y; + + // Get previous x/y values and empty indices to reuse if we can + std::vector prevX, prevY; + std::vector prevEmptyIndices; + bool prevSplineValid = false; + bool prevNaturalSpline = false; for (int outerValue = 0; outerValue < outerSize; ++outerValue) { unique_xy.clear(); @@ -560,9 +572,9 @@ void PowerTable::findTableDirection(bool horizontal) { int targetPos = this->tableRow[i].tableEntry[j].targetPosition; if (targetPos != INT16_MIN) { - unique_xy.emplace_back(innerValue, static_cast(targetPos)); + unique_xy.emplace_back(innerValue, static_cast(targetPos)); } else { - emptyIndices.push_back(innerValue); + emptyIndices.push_back(innerValue); } } @@ -570,308 +582,327 @@ void PowerTable::findTableDirection(bool horizontal) { std::sort(unique_xy.begin(), unique_xy.end()); - for (std::vector>::const_iterator it = unique_xy.begin(); it != unique_xy.end(); ++it) { - x.push_back(it->first); - y.push_back(it->second); - } + for (const auto& it : unique_xy) { + x.push_back(it.first); + y.push_back(it.second); + } + + // Reuse spline if same values + if (prevSplineValid && x == prevX && y == prevY && emptyIndices == prevEmptyIndices) { + continue; + } bool useNaturalSpline = shouldUseNaturalSpline(x.data(), y.data(), x.size()); + + // Store values + prevX = x; + prevY = y; + prevEmptyIndices = emptyIndices; + prevNaturalSpline = useNaturalSpline; + prevSplineValid = true; + fillEmptyTable(outerValue, emptyIndices, x.data(), y.data(), x.size(), horizontal, useNaturalSpline); } } -void PowerTable::fillEmptyTable(int outerValue, const std::vector& emptyIndices, const double* x, const double* y, size_t n, bool horizontal, bool useNaturalSpline) { - int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; + void PowerTable::fillEmptyTable(int outerValue, const std::vector& emptyIndices, const float* x, const float* y, size_t n, bool horizontal, bool useNaturalSpline) { + int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; - if (n == 1) { // If only one point, fill row with the value - double singleValue = y[0]; - for (int innerValue : emptyIndices) { - int i = horizontal ? outerValue : innerValue; - int j = horizontal ? innerValue : outerValue; - this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); - } - } else if (n == 2) { // If two points, do linear interpolation - for (int innerValue : emptyIndices) { - int i = horizontal ? outerValue : innerValue; - int j = horizontal ? innerValue : outerValue; + if (n == 1) { // If only one point, fill row with the value + float singleValue = y[0]; + for (int innerValue : emptyIndices) { + int i = horizontal ? outerValue : innerValue; + int j = horizontal ? innerValue : outerValue; + this->tableRow[i].tableEntry[j].targetPosition = static_cast(std::round(singleValue)); + } + } else if (n == 2) { // If two points, do linear interpolation + for (int innerValue : emptyIndices) { + int i = horizontal ? outerValue : innerValue; + int j = horizontal ? innerValue : outerValue; - double interpolated_value = linearInterpolate(x, y, n, innerValue); - int tempValue = static_cast(std::round(interpolated_value)); + float interpolated_value = linearInterpolate(x, y, n, innerValue); + int tempValue = static_cast(std::round(interpolated_value)); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (n >= 3) { // If three or more points, use cubic spline interpolation - bool validForSpline = true; - for (size_t i = 1; i < n; ++i) { - if (x[i] <= x[i - 1]) { - validForSpline = false; - break; - } - } - if (!validForSpline) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); - return; - } + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (n >= 3) { // If three or more points, use cubic spline interpolation + bool validForSpline = true; + for (size_t i = 1; i < n; ++i) { + if (x[i] <= x[i - 1]) { + validForSpline = false; + break; + } + } + if (!validForSpline) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); + return; + } - // Create and initialize the spline with the desired type (natural or clamped) - CubicSpline spline; - spline.set_points(x, y, n, useNaturalSpline); + // Create and initialize the spline with the desired type (natural or clamped) + CubicSpline spline; + spline.set_points(x, y, n, useNaturalSpline); - for (int innerValue : emptyIndices) { - int i = horizontal ? outerValue : innerValue; - int j = horizontal ? innerValue : outerValue; + for (int innerValue : emptyIndices) { + int i = horizontal ? outerValue : innerValue; + int j = horizontal ? innerValue : outerValue; - double interpolated_value = spline.interpolate(innerValue); + float interpolated_value = spline.interpolate(innerValue); - double minValue = *std::min_element(y, y + n); - double maxValue = *std::max_element(y, y + n); - interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); + float minValue = *std::min_element(y, y + n); + float maxValue = *std::max_element(y, y + n); + interpolated_value = std::max(minValue, std::min(maxValue, interpolated_value)); - int tempValue = static_cast(std::round(interpolated_value)); + int tempValue = static_cast(std::round(interpolated_value)); - if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else { - SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); + if (this->testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else { + SS2K_LOG(POWERTABLE_LOG_TAG, "Error: No unique points found."); + } } -} - -void PowerTable::extrapFillTable() { - extrapFillTableDirection(true); // Horizontal - extrapFillTableDirection(false); // Vertical -} -void PowerTable::extrapFillTableDirection(bool horizontal) { - int outerSize = horizontal ? POWERTABLE_CAD_SIZE : POWERTABLE_WATT_SIZE; - int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; + void PowerTable::extrapFillTable() { + extrapFillTableDirection(true); // Horizontal + extrapFillTableDirection(false); // Vertical + } - std::vector> unique_xy; - std::vector emptyIndices; - std::vector x, y; + void PowerTable::extrapFillTableDirection(bool horizontal) { + int outerSize = horizontal ? POWERTABLE_CAD_SIZE : POWERTABLE_WATT_SIZE; + int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; - for (int outerIndex = 0; outerIndex < outerSize; ++outerIndex) { - unique_xy.clear(); - emptyIndices.clear(); - x.clear(); - y.clear(); + std::vector> unique_xy; + std::vector emptyIndices; + std::vector x, y; - // Collect data points - for (int innerIndex = 0; innerIndex < innerSize; ++innerIndex) { - int i = horizontal ? outerIndex : innerIndex; - int j = horizontal ? innerIndex : outerIndex; + // Store previous data to reuse + std::vector prevX, prevY; + std::vector prevEmptyIndices; + bool prevSplineValid = false; + bool prevNaturalSpline = false; - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - unique_xy.emplace_back(innerIndex, static_cast(this->tableRow[i].tableEntry[j].targetPosition)); - } else { - emptyIndices.push_back(innerIndex); - } - } + for (int outerIndex = 0; outerIndex < outerSize; ++outerIndex) { + unique_xy.clear(); + emptyIndices.clear(); + x.clear(); + y.clear(); - if (unique_xy.size() < 2) continue; // Skip if not enough data + int rangeStart = std::max(0, innerSize / 2 - 10); + int rangeEnd = std::min(innerSize, innerSize / 2 + 10); - std::sort(unique_xy.begin(), unique_xy.end()); + // Collect data points + for (int innerIndex = rangeStart; innerIndex < rangeEnd; ++innerIndex) { + int i = horizontal ? outerIndex : innerIndex; + int j = horizontal ? innerIndex : outerIndex; - for (std::vector>::const_iterator it = unique_xy.begin(); it != unique_xy.end(); ++it) { - x.push_back(it->first); - y.push_back(it->second); - } + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + unique_xy.emplace_back(innerIndex, static_cast(this->tableRow[i].tableEntry[j].targetPosition)); + } else { + emptyIndices.push_back(innerIndex); + } + } - // Determine spline type (natural or clamped) - bool useNaturalSpline = shouldUseNaturalSpline(x.data(), y.data(), x.size()); + if (unique_xy.size() < 2) continue; // Skip if not enough data - // Fill empty table entries using the determined spline type - extrapolateEmptyIndices(outerIndex, emptyIndices, x.data(), y.data(), x.size(), horizontal, useNaturalSpline); - } -} + std::sort(unique_xy.begin(), unique_xy.end()); -void PowerTable::extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, const double* x, const double* y, size_t n, bool horizontal, bool naturalSpline) { + for (const auto& it : unique_xy) { + x.push_back(it.first); + y.push_back(it.second); + } - int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; + if (prevSplineValid && x == prevX && y == prevY && emptyIndices == prevEmptyIndices) { + continue; + } - if (n == 1) { - int singleValue = static_cast(std::round(y[0])); - for (int innerIndex : emptyIndices) { - int i = horizontal ? outerIndex : innerIndex; - int j = horizontal ? innerIndex : outerIndex; - this->tableRow[i].tableEntry[j].targetPosition = singleValue; - } - } else if (n == 2) { - for (int innerIndex : emptyIndices) { - int i = horizontal ? outerIndex : innerIndex; - int j = horizontal ? innerIndex : outerIndex; + // Determine spline type (natural or clamped) + bool useNaturalSpline = shouldUseNaturalSpline(x.data(), y.data(), x.size()); - double extrapolated_value = linearExtrapolate(x, y, n, innerIndex); - int tempValue = static_cast(std::round(extrapolated_value)); + prevX = x; + prevY = y; + prevEmptyIndices = emptyIndices; + prevNaturalSpline = useNaturalSpline; + prevSplineValid = true; - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } else if (n >= 3) { - bool validForSpline = true; - for (size_t i = 1; i < n; ++i) { - if (x[i] <= x[i - 1]) { - validForSpline = false; - break; - } - } - if (!validForSpline) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); - return; - } + // Fill empty table entries using the determined spline type + extrapolateEmptyIndices(outerIndex, emptyIndices, x.data(), y.data(), x.size(), horizontal, useNaturalSpline); + } + } - CubicSpline spline; - spline.set_points(x, y, n, naturalSpline); // Pass pointer-based data + void PowerTable::extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, const float* x, const float* y, size_t n, bool horizontal, bool naturalSpline) { + int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; - for (int innerIndex : emptyIndices) { - int i = horizontal ? outerIndex : innerIndex; - int j = horizontal ? innerIndex : outerIndex; + if (n == 1) { + int singleValue = static_cast(std::round(y[0])); + for (int innerIndex : emptyIndices) { + int i = horizontal ? outerIndex : innerIndex; + int j = horizontal ? innerIndex : outerIndex; + this->tableRow[i].tableEntry[j].targetPosition = singleValue; + } + } else if (n == 2) { + for (int innerIndex : emptyIndices) { + int i = horizontal ? outerIndex : innerIndex; + int j = horizontal ? innerIndex : outerIndex; - double extrapolated_value = spline.extrapolate(innerIndex); - double minVal = *std::min_element(y, y + n); - double maxVal = *std::max_element(y, y + n); - double range = maxVal - minVal; - extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); - int tempValue = static_cast(std::round(extrapolated_value)); + float extrapolated_value = linearExtrapolate(x, y, n, innerIndex); + int tempValue = static_cast(std::round(extrapolated_value)); - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } -} + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } else if (n >= 3) { + bool validForSpline = true; + for (size_t i = 1; i < n; ++i) { + if (x[i] <= x[i - 1]) { + validForSpline = false; + break; + } + } + if (!validForSpline) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected!"); + return; + } + CubicSpline spline; + spline.set_points(x, y, n, naturalSpline); // Pass pointer-based data -void PowerTable::extrapolateDiagonal() { - std::vector> unique_xy; - std::vector> emptyIndices; + for (int innerIndex : emptyIndices) { + int i = horizontal ? outerIndex : innerIndex; + int j = horizontal ? innerIndex : outerIndex; - // Iterate over different diagonals (sum of indices is constant) - for (int sum = 0; sum < POWERTABLE_CAD_SIZE + POWERTABLE_WATT_SIZE - 1; ++sum) { - unique_xy.clear(); - emptyIndices.clear(); + float extrapolated_value = spline.extrapolate(innerIndex); + float minVal = *std::min_element(y, y + n); + float maxVal = *std::max_element(y, y + n); + float range = maxVal - minVal; + extrapolated_value = std::max(minVal - 0.1f * range, std::min(extrapolated_value, maxVal + 0.1f * range)); + int tempValue = static_cast(std::round(extrapolated_value)); - // Collect known values for this diagonal - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - int j = sum - i; - if (j >= 0 && j < POWERTABLE_WATT_SIZE) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - unique_xy.emplace_back(i, static_cast(this->tableRow[i].tableEntry[j].targetPosition)); - } else { - emptyIndices.emplace_back(i, j); - } - } - } + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } - if (unique_xy.size() < 2) continue; // Skip if not enough data + void PowerTable::extrapolateDiagonal() { + std::vector> unique_xy; + std::vector> emptyIndices; - std::sort(unique_xy.begin(), unique_xy.end()); + std::vector prevX, prevY; + std::vector> prevEmptyIndices; + bool prevSplineValid = false; - std::vector x, y; - for (std::vector>::const_iterator it = unique_xy.begin(); it != unique_xy.end(); ++it) { - x.push_back(it->first); - y.push_back(it->second); - } + int midCAD = POWERTABLE_CAD_SIZE / 2; + int midWATT = POWERTABLE_WATT_SIZE / 2; - extrapolateDiagonalEntries(emptyIndices, x.data(), y.data(), x.size()); - } + // Iterate over different diagonals (sum of indices is constant) + for (int sum = 0; sum < POWERTABLE_CAD_SIZE + POWERTABLE_WATT_SIZE - 1; ++sum) { + unique_xy.clear(); + emptyIndices.clear(); - // Iterate over other set of diagonals (where difference of indices is constant) - for (int diff = POWERTABLE_CAD_SIZE - 1; diff >= 1 - POWERTABLE_WATT_SIZE; --diff) { - unique_xy.clear(); - emptyIndices.clear(); + int rangeStart = std::max(0, sum / 2 - 10); + int rangeEnd = std::min(POWERTABLE_CAD_SIZE, sum / 2 + 10); - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - int j = i - diff; - if (j >= 0 && j < POWERTABLE_WATT_SIZE) { - if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - unique_xy.emplace_back(i, static_cast(this->tableRow[i].tableEntry[j].targetPosition)); - } else { - emptyIndices.emplace_back(i, j); - } - } - } + // Collect known values for this diagonal + for (int i = rangeStart; i < rangeEnd; ++i) { + int j = sum - i; + if (j >= 0 && j < POWERTABLE_WATT_SIZE) { + if (this->tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + unique_xy.emplace_back(i, static_cast(this->tableRow[i].tableEntry[j].targetPosition)); + } else { + emptyIndices.emplace_back(i, j); + } + } + } - if (unique_xy.size() < 2) continue; + if (unique_xy.size() < 2) continue; // Skip if not enough data - std::sort(unique_xy.begin(), unique_xy.end()); + std::sort(unique_xy.begin(), unique_xy.end()); - std::vector x, y; - for (const auto& it : unique_xy) { - x.push_back(it.first); - y.push_back(it.second); - } + std::vector x, y; + for (const auto& point : unique_xy) { + x.push_back(point.first); + y.push_back(point.second); + } - extrapolateDiagonalEntries(emptyIndices, x.data(), y.data(), x.size()); - } -} + if (prevSplineValid && x == prevX && emptyIndices == prevEmptyIndices) { + continue; + } -void PowerTable::extrapolateDiagonalEntries(const std::vector>& emptyIndices, const double* x, const double* y, size_t n) { + // Store for reuse + prevX = x; + prevY = y; + prevEmptyIndices = emptyIndices; + prevSplineValid = true; - if (n == 1) { - int singleValue = static_cast(std::round(y[0])); - for (std::vector>::const_iterator it = emptyIndices.begin(); it != emptyIndices.end(); ++it) { - this->tableRow[it->first].tableEntry[it->second].targetPosition = singleValue; - } - return; + extrapolateDiagonalEntries(emptyIndices, x.data(), y.data(), x.size()); + } } - if (n == 2) { - for (std::vector>::const_iterator it = emptyIndices.begin(); it != emptyIndices.end(); ++it) { - int i = it->first; - int j = it->second; + void PowerTable::extrapolateDiagonalEntries(const std::vector>& emptyIndices, const float* x, const float* y, size_t n) { + if (n == 1) { + int singleValue = static_cast(std::round(y[0])); + for (const auto& it : emptyIndices) { + this->tableRow[it.first].tableEntry[it.second].targetPosition = singleValue; + } + return; + } - double extrapolated_value = linearExtrapolate(x, y, n, i); - int tempValue = static_cast(std::round(extrapolated_value)); + if (n == 2) { + for (const auto& it : emptyIndices) { + int i = it.first; + int j = it.second; - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - return; - } + float extrapolated_value = linearExtrapolate(x, y, n, i); + int tempValue = static_cast(std::round(extrapolated_value)); - if (n >= 3) { - bool validForSpline = true; - for (size_t k = 1; k < n; ++k) { - if (x[k] <= x[k - 1]) { - validForSpline = false; - break; - } - } - if (!validForSpline) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected for diagonal!"); - return; - } + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + return; + } - CubicSpline spline; - spline.set_points(x, y, n); + if (n >= 3) { + bool validForSpline = true; + for (size_t k = 1; k < n; ++k) { + if (x[k] <= x[k - 1]) { + validForSpline = false; + break; + } + } + if (!validForSpline) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Duplicate or non-increasing x-values detected for diagonal!"); + return; + } - for (std::vector>::const_iterator it = emptyIndices.begin(); it != emptyIndices.end(); ++it) { - int i = it->first; - int j = it->second; + CubicSpline spline; + spline.set_points(x, y, n); - if (i < 0 || i >= POWERTABLE_CAD_SIZE || j < 0 || j >= POWERTABLE_WATT_SIZE) continue; + for (const auto& it : emptyIndices) { + int i = it.first; + int j = it.second; - double extrapolated_value = spline.extrapolate(i); + if (i < 0 || i >= POWERTABLE_CAD_SIZE || j < 0 || j >= POWERTABLE_WATT_SIZE) continue; - double minVal = *std::min_element(y, y + n); - double maxVal = *std::max_element(y, y + n); - double range = maxVal - minVal; - extrapolated_value = std::max(minVal - 0.1 * range, std::min(extrapolated_value, maxVal + 0.1 * range)); + float extrapolated_value = spline.extrapolate(i); - int tempValue = static_cast(std::round(extrapolated_value)); - if (testNeighbors(i, j, tempValue).allNeighborsPassed) { - this->tableRow[i].tableEntry[j].targetPosition = tempValue; - } - } - } -} + float minVal = *std::min_element(y, y + n); + float maxVal = *std::max_element(y, y + n); + float range = maxVal - minVal; + extrapolated_value = std::max(minVal - 0.1f * range, std::min(extrapolated_value, maxVal + 0.1f * range)); + int tempValue = static_cast(std::round(extrapolated_value)); + if (testNeighbors(i, j, tempValue).allNeighborsPassed) { + this->tableRow[i].tableEntry[j].targetPosition = tempValue; + } + } + } + } int PowerTable::getNumEntries() { int ret = 0; From 0295bdd44d429011919c1600c46a0511804e240d Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Fri, 21 Mar 2025 10:17:14 -0500 Subject: [PATCH 140/451] added @breif comments --- src/Power_Table.cpp | 120 ++++++++++++++++++++++++++++---------------- 1 file changed, 78 insertions(+), 42 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 4b4fa663..0e50b7c4 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -1158,6 +1158,19 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { BLE_ss2kCustomCharacteristic::notify(0x27, k); } +/** + * @brief Updates or enters data into the power table for a specific row and entry. + * + * This function records a new target position or averages the new position with + * existing data for a specific table entry. It ensures that the number of readings + * does not exceed a defined limit to prevent dilution of recent data. Additionally, + * it triggers table filling and extrapolation processes if the number of entries + * exceeds a threshold. + * + * @param k The index of the table row to update. + * @param i The index of the table entry within the row to update. + * @param pos The new target position to record or average. + */ void PowerTable::enterData(int k, int i, int pos) { if (this->tableRow[k].tableEntry[i].readings <= 0) { // if first reading in this entry this->tableRow[k].tableEntry[i].targetPosition = pos; @@ -1187,66 +1200,89 @@ void PowerTable::enterData(int k, int i, int pos) { } } -float PowerTable::calculatePosition(float watts, float cad, float targetPos, int k, int i){ +/** + * @brief Calculates the target position for a given power table entry based on neighboring values. + * + * This function determines the new target position for a power table entry by analyzing its neighbors + * and applying weighted adjustments based on the differences in watts and cadence. If the current entry + * is invalid or does not pass neighbor tests, the function retains the old target position. + * + * @param watts The power in watts for the current entry. + * @param cad The cadence in RPM for the current entry. + * @param targetPos The current target position to be adjusted. + * @param k The cadence index in the power table. + * @param i The watt index in the power table. + * @return The calculated target position after applying adjustments based on neighbors. + */ +float PowerTable::calculatePosition(float watts, float cad, float targetPos, int k, int i) { - TestResults testResults = this->testNeighbors(k, i, targetPos); + TestResults testResults = this->testNeighbors(k, i, targetPos); - if(this->tableRow[k].tableEntry[i].targetPosition == INT16_MIN || - !(testResults.bottomNeighbor.passedTest || testResults.topNeighbor.passedTest || testResults.rightNeighbor.passedTest || testResults.leftNeighbor.passedTest) || - this->tableRow[k].tableEntry[i].targetPosition == targetPos) { - SS2K_LOG(POWERTABLE_LOG_TAG, "Keep old targetPosition: (%f)", targetPos); - return targetPos; - } + if(this->tableRow[k].tableEntry[i].targetPosition == INT16_MIN || + !(testResults.bottomNeighbor.passedTest || testResults.topNeighbor.passedTest || testResults.rightNeighbor.passedTest || testResults.leftNeighbor.passedTest) || + this->tableRow[k].tableEntry[i].targetPosition == targetPos) { + SS2K_LOG(POWERTABLE_LOG_TAG, "Keep old targetPosition: (%f)", targetPos); + return targetPos; + } - int wattPosition = POWERTABLE_WATT_INCREMENT * i; - int cadPosition = MINIMUM_TABLE_CAD + (POWERTABLE_CAD_INCREMENT * k); + int wattPosition = POWERTABLE_WATT_INCREMENT * i; + int cadPosition = MINIMUM_TABLE_CAD + (POWERTABLE_CAD_INCREMENT * k); - float rightValue = 0.0f, leftValue = 0.0f, topValue = 0.0f, bottomValue = 0.0f; + float rightValue = 0.0f, leftValue = 0.0f, topValue = 0.0f, bottomValue = 0.0f; - int cellValue = this->tableRow[k].tableEntry[i].targetPosition; - float wattDelta = float(POWERTABLE_WATT_INCREMENT)/(abs(targetPos - float(cellValue))); - float cadDelta = float(POWERTABLE_CAD_INCREMENT)/(abs(targetPos - float(cellValue))); + int cellValue = this->tableRow[k].tableEntry[i].targetPosition; + float wattDelta = float(POWERTABLE_WATT_INCREMENT)/(abs(targetPos - float(cellValue))); + float cadDelta = float(POWERTABLE_CAD_INCREMENT)/(abs(targetPos - float(cellValue))); - SS2K_LOG(POWERTABLE_LOG_TAG, "cellValue: (%d) wattDelta: (%f) cadDelta: (%f) allNeighborsPassed: (%d)", cellValue, wattDelta, cadDelta, testResults.allNeighborsPassed); + SS2K_LOG(POWERTABLE_LOG_TAG, "cellValue: (%d) wattDelta: (%f) cadDelta: (%f) allNeighborsPassed: (%d)", cellValue, wattDelta, cadDelta, testResults.allNeighborsPassed); - int count = 0; + int count = 0; - if(testResults.rightNeighbor.passedTest){ - float x = abs(watts - float(wattPosition + POWERTABLE_WATT_INCREMENT)); - rightValue = targetPos - (x/wattDelta); - count++; - } - if(testResults.leftNeighbor.passedTest){ - float x = abs(watts - float(wattPosition - POWERTABLE_WATT_INCREMENT)); - leftValue = targetPos - (x/wattDelta); - count++; - } - if(testResults.bottomNeighbor.passedTest){ - float x = abs(cad - float(cadPosition + POWERTABLE_CAD_INCREMENT)); - bottomValue = targetPos - (x/cadDelta); - count++; - } - if(testResults.topNeighbor.passedTest){ - float x = abs(cad - float(cadPosition - POWERTABLE_CAD_INCREMENT)); - topValue = targetPos - (x/cadDelta); - count++; - } + if(testResults.rightNeighbor.passedTest){ + float x = abs(watts - float(wattPosition + POWERTABLE_WATT_INCREMENT)); + rightValue = targetPos - (x/wattDelta); + count++; + } + if(testResults.leftNeighbor.passedTest){ + float x = abs(watts - float(wattPosition - POWERTABLE_WATT_INCREMENT)); + leftValue = targetPos - (x/wattDelta); + count++; + } + if(testResults.bottomNeighbor.passedTest){ + float x = abs(cad - float(cadPosition + POWERTABLE_CAD_INCREMENT)); + bottomValue = targetPos - (x/cadDelta); + count++; + } + if(testResults.topNeighbor.passedTest){ + float x = abs(cad - float(cadPosition - POWERTABLE_CAD_INCREMENT)); + topValue = targetPos - (x/cadDelta); + count++; + } - targetPos = (rightValue + leftValue + topValue + bottomValue)/float(count); - SS2K_LOG(POWERTABLE_LOG_TAG, "rightValue: (%f) leftValue: (%f) bottomValue: (%f) topValue: (%f) New averaged targetPosition: (%f) count: (%d)", - rightValue, leftValue, bottomValue, topValue, targetPos, count); + targetPos = (rightValue + leftValue + topValue + bottomValue)/float(count); + SS2K_LOG(POWERTABLE_LOG_TAG, "rightValue: (%f) leftValue: (%f) bottomValue: (%f) topValue: (%f) New averaged targetPosition: (%f) count: (%d)", + rightValue, leftValue, bottomValue, topValue, targetPos, count); - return targetPos; + return targetPos; } -// function for weighted downvoting +/** + * @brief Calculates a penalty value for downvoting a neighbor entry in the power table. + * + * This function computes a penalty based on the difference between the target value + * and the neighbor value. The penalty is scaled by a predefined penalty factor and + * is used to reduce the reliability of a neighbor entry when it fails validation. + * + * @param targetValue The target position value being evaluated. + * @param neighborValue The neighbor position value being compared. + * @return The calculated penalty value to be applied to the neighbor entry. + */ int weightedDownVote(int targetValue, int neighborValue) { // calculate diff between target and neighbor int delta = abs(targetValue - neighborValue); int penalty; float penaltyFactor = 0.2; - // currently consistently getting a 0 for neighbor value... SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Target Value: (%d), NeighborValue: (%d)", targetValue, neighborValue); penalty = (delta * penaltyFactor); From fde870aef92934505cce1794bed65955afac0759 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Tue, 25 Mar 2025 21:58:39 +0000 Subject: [PATCH 141/451] Update changelog for version 25.3.13 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4339a01..ead6a6a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +### Changed + +### Hardware + + +## [25.3.13] + +### Added + ### Changed - Multiple html and css improvements. ### Hardware From 35aaff6fc8a5c5dd5c81c9062bd6d866b18ba15e Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 25 Mar 2025 17:19:06 -0500 Subject: [PATCH 142/451] added comment --- src/HTTP_Server_Basic.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/HTTP_Server_Basic.cpp b/src/HTTP_Server_Basic.cpp index 17e4c248..d3198048 100644 --- a/src/HTTP_Server_Basic.cpp +++ b/src/HTTP_Server_Basic.cpp @@ -669,6 +669,7 @@ void HTTP_Server::FirmwareUpdate() { if (httpCode == HTTP_CODE_OK) { // if version received bool updateAnyway = false; if (!LittleFS.exists("/index.html")) { + // force firmware update if index.html is missing // updateAnyway = true; SS2K_LOG(HTTP_SERVER_LOG_TAG, " -index.html not found."); } @@ -750,6 +751,8 @@ void HTTP_Server::FirmwareUpdate() { } else { // don't update SS2K_LOG(HTTP_SERVER_LOG_TAG, " - Current Version: %s", FIRMWARE_VERSION); } + }else{ + SS2K_LOG(HTTP_SERVER_LOG_TAG, "Could not connect to Github. httpCode: %d", httpCode); } } From 1018ba5ce63b4415fa30a73362c8f89566cfa403 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 25 Mar 2025 19:53:27 -0500 Subject: [PATCH 143/451] Root CA certificates are now updated automatically during every build. --- CHANGELOG.md | 1 + cert_updater.py | 443 ++++++++++++++++++++++++++++++++++++++++++++++++ include/cert.h | 53 +++--- platformio.ini | 8 +- 4 files changed, 469 insertions(+), 36 deletions(-) create mode 100644 cert_updater.py diff --git a/CHANGELOG.md b/CHANGELOG.md index ec8f1da7..9b0c94a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +-Root CA certificates are now updated automatically during every build. ### Changed - Multiple html and css improvements. diff --git a/cert_updater.py b/cert_updater.py new file mode 100644 index 00000000..aab1be7a --- /dev/null +++ b/cert_updater.py @@ -0,0 +1,443 @@ +#!/usr/bin/env python3 +""" +This script fetches the current CA certificate for raw.githubusercontent.com +and updates the cert.h file with it during compilation. + +Similar to git_tag_macro.py, this script is run as part of the build process +to ensure the certificate is always up to date. + +This script can be run in two ways: +1. Directly: python cert_updater.py +2. As a PlatformIO pre-script: extra_scripts = pre:cert_updater.py +""" + +import os +import ssl +import socket +import datetime +import re +import urllib.request +from pathlib import Path +import sys + +# Define constants +CERT_FILE_PATH = "include/cert.h" +GITHUB_HOST = "raw.githubusercontent.com" +GITHUB_PORT = 443 +CERT_FILE_HEADER = """/* + * Copyright (C) 2020 Anthony Doud & Joel Baranick + * All rights reserved + * + * SPDX-License-Identifier: GPL-2.0-only + */ + +/* + * Automatically updated CA certificate for raw.githubusercontent.com + * Last updated: {date} + */ + +#pragma once + +// certificate for https://raw.githubusercontent.com +// {cert_description}, valid until {valid_until}, size: {cert_size} bytes +const char* rootCACertificate = +""" + +def determine_root_ca_from_github(): + """ + Connect to raw.githubusercontent.com and determine the root CA used + + Returns a tuple (organization_name, common_name) of the root CA + """ + try: + print(f"Connecting to {GITHUB_HOST} to determine root CA...") + + # Create SSL context and connect + context = ssl.create_default_context() + with socket.create_connection((GITHUB_HOST, GITHUB_PORT), timeout=10) as sock: + with context.wrap_socket(sock, server_hostname=GITHUB_HOST) as ssock: + # Get certificate chain + cert_der = ssock.getpeercert(binary_form=True) + + # Parse certificate to get issuer information + from cryptography import x509 + from cryptography.hazmat.backends import default_backend + + cert = x509.load_der_x509_certificate(cert_der, default_backend()) + + # Extract issuer information - this is the immediate CA, not root + issuer = cert.issuer + + # We need to get the complete chain to find the root CA + # Get current certificate in text form for comparison + cert_pem = ssl.DER_cert_to_PEM_cert(cert_der) + + # Get certificate chain in text form + chain = [] + for der_cert in context.get_ca_certs(binary_form=True): + pem_cert = ssl.DER_cert_to_PEM_cert(der_cert) + chain.append(pem_cert) + + print(f"Found {len(chain)} certificates in chain") + + # Extract root CA information (last in chain or self-signed) + root_ca_org = None + root_ca_cn = None + + for i, attr in enumerate(issuer): + attr_name = attr.oid._name + if attr_name == 'organizationName': + root_ca_org = attr.value + print(f"Root CA Organization: {root_ca_org}") + elif attr_name == 'commonName': + root_ca_cn = attr.value + print(f"Root CA Common Name: {root_ca_cn}") + + # If we couldn't extract from the cert object, fall back to standard method + if not (root_ca_org and root_ca_cn): + cert_info = ssock.getpeercert() + issuer = dict(x[0] for x in cert_info['issuer']) + root_ca_org = issuer.get('organizationName', 'Unknown') + root_ca_cn = issuer.get('commonName', 'Unknown') + print(f"Root CA (fallback method): {root_ca_org} {root_ca_cn}") + + return root_ca_org, root_ca_cn + + except ImportError: + try: + # Fall back to simpler method without cryptography library + context = ssl.create_default_context() + with socket.create_connection((GITHUB_HOST, GITHUB_PORT), timeout=10) as sock: + with context.wrap_socket(sock, server_hostname=GITHUB_HOST) as ssock: + cert_info = ssock.getpeercert() + issuer = dict(x[0] for x in cert_info['issuer']) + org = issuer.get('organizationName', 'Unknown') + cn = issuer.get('commonName', 'Unknown') + print(f"Root CA (simple method): {org} {cn}") + return org, cn + except Exception as e: + print(f"Error getting certificate info: {e}") + return None, None + + except Exception as e: + print(f"Error connecting to GitHub: {e}") + return None, None + +def extract_certificates_from_mozilla(target_org=None, target_cn=None): + """ + Extract certificates from Mozilla's bundle matching the target organization and common name + + Args: + target_org: Organization name to search for + target_cn: Common name to search for + + Returns: + A list of matching certificates, or all certificates if no target specified + """ + try: + cert_url = "https://curl.se/ca/cacert.pem" + print(f"Downloading certificates from {cert_url}...") + + with urllib.request.urlopen(cert_url) as response: + cert_bundle = response.read().decode('utf-8') + + # Find all certificates in the bundle + print("Parsing certificate bundle...") + all_certs = re.findall( + r'(-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----)', + cert_bundle, re.DOTALL + ) + print(f"Found {len(all_certs)} certificates in bundle") + + # Extract certificates with their names from the bundle + named_certs = [] + for cert in all_certs: + # Try to extract the certificate name from comments in the bundle + cert_start_pos = cert_bundle.find(cert) + if cert_start_pos > 0: + # Look for certificate name in comments before certificate + name_search = cert_bundle[max(0, cert_start_pos-500):cert_start_pos] + name_match = re.search(r'^###\s+([^\n]+)', name_search, re.MULTILINE) + if name_match: + cert_name = name_match.group(1).strip() + named_certs.append((cert_name, cert)) + + # If we have target information, check for matches + if target_org and target_cn: + if (target_org.lower() in cert_name.lower() and + target_cn.lower() in cert_name.lower()): + print(f"*** Found matching certificate: {cert_name} ***") + return [cert] + elif target_org: + if target_org.lower() in cert_name.lower(): + print(f"*** Found certificate with matching org: {cert_name} ***") + return [cert] + + # If we have specific targets but didn't find a match by name, search in cert contents + if target_org or target_cn: + print(f"Searching certificate contents for {target_org} {target_cn}...") + matches = [] + for cert in all_certs: + match_org = target_org and re.search(re.escape(target_org), cert, re.IGNORECASE) + match_cn = target_cn and re.search(re.escape(target_cn), cert, re.IGNORECASE) + + if (target_org and target_cn and match_org and match_cn) or \ + (target_org and not target_cn and match_org) or \ + (target_cn and not target_org and match_cn): + print(f"Found certificate containing target strings") + matches.append(cert) + + if matches: + return matches + + # If still no matches or no target specified, return either named certs or all certs + if named_certs: + return [cert for _, cert in named_certs] + else: + print("Returning all certificates for testing") + return all_certs + + except Exception as e: + print(f"Warning: Certificate bundle fetch failed: {e}") + + return [] + +def test_certificate(cert_text, host=GITHUB_HOST, port=GITHUB_PORT): + """ + Test if a certificate works for connecting to the specified host + + Returns a tuple of (success, error_message) + """ + import tempfile + + # Create temporary certificate file + with tempfile.NamedTemporaryFile(delete=False) as cert_file: + cert_file.write(cert_text.encode('utf-8')) + cert_file_path = cert_file.name + + try: + # Create SSL context using the certificate + context = ssl.create_default_context(cafile=cert_file_path) + with socket.create_connection((host, port), timeout=10) as sock: + with context.wrap_socket(sock, server_hostname=host) as ssock: + # Get certificate info for validation + cert_info = ssock.getpeercert() + valid_until = datetime.datetime.strptime( + cert_info['notAfter'], '%b %d %H:%M:%S %Y %Z' + ).strftime('%a %b %d %Y') + + issuer = dict(x[0] for x in cert_info['issuer']) + cert_description = issuer.get('organizationName', 'Unknown') + if 'commonName' in issuer: + cert_description = f"{cert_description} {issuer['commonName']}" + + os.unlink(cert_file_path) # Clean up + return True, (cert_description, valid_until) + + except Exception as e: + # Clean up and return the error + if os.path.exists(cert_file_path): + os.unlink(cert_file_path) + return False, str(e) + +def get_certificate(): + """ + Fetch and test the appropriate root certificate for raw.githubusercontent.com + + This function first determines which root CA is used by GitHub, then gets that + certificate from Mozilla's bundle and tests it + """ + # First, determine the root CA that GitHub is using + root_ca_org, root_ca_cn = determine_root_ca_from_github() + + if not root_ca_org and not root_ca_cn: + print("Error: Could not determine root CA for GitHub") + return None, None, None + + print(f"Fetching {root_ca_org} {root_ca_cn} certificate for {GITHUB_HOST}...") + + # Get matching certificates from Mozilla's bundle + matching_certs = extract_certificates_from_mozilla(target_org=root_ca_org, target_cn=root_ca_cn) + + if not matching_certs: + print(f"Error: Could not find certificate for {root_ca_org} {root_ca_cn}") + return None, None, None + + # Try each certificate until we find one that works + for i, cert in enumerate(matching_certs): + print(f"Testing certificate {i+1}/{len(matching_certs)}...") + success, result = test_certificate(cert) + + if success: + cert_description, valid_until = result + print(f"Certificate works: {cert_description}, valid until {valid_until}") + return cert, cert_description, valid_until + else: + print(f"Certificate test {i+1} failed: {result}") + + # If we couldn't find a working certificate, try a fallback method with USERTrust + # (keeping this for backward compatibility) + print("Trying fallback method with USERTrust certificate...") + usertrust_certs = extract_certificates_from_mozilla(target_org="USERTrust") + + for i, cert in enumerate(usertrust_certs): + print(f"Testing USERTrust certificate {i+1}/{len(usertrust_certs)}...") + success, result = test_certificate(cert) + + if success: + cert_description, valid_until = result + print(f"USERTrust certificate works: {cert_description}, valid until {valid_until}") + return cert, cert_description, valid_until + else: + print(f"USERTrust certificate test {i+1} failed: {result}") + + print("All certificate tests failed") + return None, None, None + +def format_certificate(cert_text): + """ + Format the certificate for inclusion in a C/C++ header file + """ + lines = cert_text.strip().split('\n') + formatted_lines = [f' "{line}\\n"' for line in lines] + return '\n'.join(formatted_lines) + +def update_cert_file(cert_text, cert_description, valid_until, is_quiet=False): + """ + Update the cert.h file with the new certificate + + Args: + cert_text: The certificate text + cert_description: Description of the certificate + valid_until: Expiration date of the certificate + is_quiet: If True, suppresses console output + """ + if not cert_text: + if not is_quiet: + print("ERROR: No valid certificate found for raw.githubusercontent.com") + cert_file = Path(CERT_FILE_PATH) + if cert_file.exists(): + print(f"Keeping existing certificate in {CERT_FILE_PATH}") + print("WARNING: The existing certificate may not work with current GitHub servers") + print(" This could cause SSL verification errors during firmware updates") + else: + print(f"No existing {CERT_FILE_PATH} found") + print("HTTPS connections to GitHub will fail until a valid certificate is installed") + return False + + formatted_cert = format_certificate(cert_text) + cert_size = len(cert_text) + + header = CERT_FILE_HEADER.format( + date=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + cert_description=cert_description or "Unknown Certificate", + valid_until=valid_until or "Unknown", + cert_size=cert_size + ) + + # Generate the new content + new_content = f"{header}{formatted_cert};" + + # Write to the cert.h file + cert_file = Path(CERT_FILE_PATH) + + # Only update if the certificate has actually changed + if cert_file.exists(): + try: + current_content = cert_file.read_text() + if formatted_cert in current_content: + if not is_quiet: + print("Certificate is up to date. No changes needed.") + return True + except Exception as e: + if not is_quiet: + print(f"Warning: Could not read current {CERT_FILE_PATH}: {e}") + print("Will create a new certificate file.") + + try: + # Ensure parent directory exists + cert_file.parent.mkdir(parents=True, exist_ok=True) + + # Write the certificate + cert_file.write_text(new_content) + if not is_quiet: + print(f"Certificate updated successfully in {CERT_FILE_PATH}") + print(f"Certificate: {cert_description}, valid until {valid_until}") + return True + except Exception as e: + if not is_quiet: + print(f"Error writing to {CERT_FILE_PATH}: {e}") + return False + +def update_ca_certificate(is_quiet=False): + """Update CA certificate for raw.githubusercontent.com""" + if not is_quiet: + print("Updating CA certificate for raw.githubusercontent.com...") + + cert_text, cert_description, valid_until = get_certificate() + return update_cert_file(cert_text, cert_description, valid_until, is_quiet=is_quiet) + +def log_to_stderr(message): + """Print a message to stderr instead of stdout""" + print(message, file=sys.stderr) + +def main(): + """ + Main function when run directly or by PlatformIO build flags + + When called by PlatformIO in the build_flags section (like !python cert_updater.py), + it needs to print a valid build flag to stdout without any other output. + """ + # Save the original print function + original_print = print + + # Override the print function in our modules to send everything to stderr + def safe_print(*args, **kwargs): + if 'file' not in kwargs: + kwargs['file'] = sys.stderr + original_print(*args, **kwargs) + + # Replace print in global scope + builtins = sys.modules['builtins'] + setattr(builtins, 'print', safe_print) + + try: + log_to_stderr("\nRunning cert_updater.py to update GitHub SSL certificate...") + + cert_file = Path(CERT_FILE_PATH) + + if cert_file.exists(): + log_to_stderr(f"Certificate file exists at {CERT_FILE_PATH}") + log_to_stderr(f"File size: {cert_file.stat().st_size} bytes") + else: + log_to_stderr(f"Certificate file does not exist at {CERT_FILE_PATH}") + log_to_stderr("Will create certificate file") + + # Update the certificate + result = update_ca_certificate(is_quiet=False) + + if cert_file.exists(): + log_to_stderr(f"Certificate file updated successfully at {CERT_FILE_PATH}") + log_to_stderr(f"File size: {cert_file.stat().st_size} bytes") + else: + log_to_stderr(f"WARNING: Certificate file could not be created at {CERT_FILE_PATH}") + + # Reset print back to original + setattr(builtins, 'print', original_print) + + # Print only the build flag to stdout - this will be picked up by PlatformIO + print("-DCERT_UPDATER_VERSION=1") + + return 0 + except Exception as e: + log_to_stderr(f"ERROR in cert_updater.py: {e}") + + # Reset print back to original + setattr(builtins, 'print', original_print) + + # Print only the build flag to stdout + print("-DCERT_UPDATER_ERROR=1") + return 1 + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/include/cert.h b/include/cert.h index a6d812e0..f31c0fa7 100644 --- a/include/cert.h +++ b/include/cert.h @@ -6,42 +6,33 @@ */ /* - * To update, search for ROOT CA Certificate used by raw.githubusercontent.com (Digicert) - * Sourced from: https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt - * Worth pointing out that this is likely better to source direct from the source: - * https://curl.se/docs/caextract.html - needs conversion to .crt to be text editor readable. + * Automatically updated CA certificate for raw.githubusercontent.com + * Last updated: 2025-03-25 19:48:51 */ #pragma once // certificate for https://raw.githubusercontent.com -// DigiCert Global Root G2, valid until Sat Mar 29 2031, size: 1720 bytes +// Sectigo Limited Sectigo RSA Domain Validation Secure Server CA, valid until Sat Mar 07 2026, size: 1512 bytes const char* rootCACertificate = "-----BEGIN CERTIFICATE-----\n" - "MIIEyDCCA7CgAwIBAgIQDPW9BitWAvR6uFAsI8zwZjANBgkqhkiG9w0BAQsFADBh\n" - "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" - "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH\n" - "MjAeFw0yMTAzMzAwMDAwMDBaFw0zMTAzMjkyMzU5NTlaMFkxCzAJBgNVBAYTAlVT\n" - "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxMzAxBgNVBAMTKkRpZ2lDZXJ0IEdsb2Jh\n" - "bCBHMiBUTFMgUlNBIFNIQTI1NiAyMDIwIENBMTCCASIwDQYJKoZIhvcNAQEBBQAD\n" - "ggEPADCCAQoCggEBAMz3EGJPprtjb+2QUlbFbSd7ehJWivH0+dbn4Y+9lavyYEEV\n" - "cNsSAPonCrVXOFt9slGTcZUOakGUWzUb+nv6u8W+JDD+Vu/E832X4xT1FE3LpxDy\n" - "FuqrIvAxIhFhaZAmunjZlx/jfWardUSVc8is/+9dCopZQ+GssjoP80j812s3wWPc\n" - "3kbW20X+fSP9kOhRBx5Ro1/tSUZUfyyIxfQTnJcVPAPooTncaQwywa8WV0yUR0J8\n" - "osicfebUTVSvQpmowQTCd5zWSOTOEeAqgJnwQ3DPP3Zr0UxJqyRewg2C/Uaoq2yT\n" - "zGJSQnWS+Jr6Xl6ysGHlHx+5fwmY6D36g39HaaECAwEAAaOCAYIwggF+MBIGA1Ud\n" - "EwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFHSFgMBmx9833s+9KTeqAx2+7c0XMB8G\n" - "A1UdIwQYMBaAFE4iVCAYlebjbuYP+vq5Eu0GF485MA4GA1UdDwEB/wQEAwIBhjAd\n" - "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdgYIKwYBBQUHAQEEajBoMCQG\n" - "CCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQAYIKwYBBQUHMAKG\n" - "NGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RH\n" - "Mi5jcnQwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQuY29t\n" - "L0RpZ2lDZXJ0R2xvYmFsUm9vdEcyLmNybDA9BgNVHSAENjA0MAsGCWCGSAGG/WwC\n" - "ATAHBgVngQwBATAIBgZngQwBAgEwCAYGZ4EMAQICMAgGBmeBDAECAzANBgkqhkiG\n" - "9w0BAQsFAAOCAQEAkPFwyyiXaZd8dP3A+iZ7U6utzWX9upwGnIrXWkOH7U1MVl+t\n" - "wcW1BSAuWdH/SvWgKtiwla3JLko716f2b4gp/DA/JIS7w7d7kwcsr4drdjPtAFVS\n" - "slme5LnQ89/nD/7d+MS5EHKBCQRfz5eeLjJ1js+aWNJXMX43AYGyZm0pGrFmCW3R\n" - "bpD0ufovARTFXFZkAdl9h6g4U5+LXUZtXMYnhIHUfoyMo5tS58aI7Dd8KvvwVVo4\n" - "chDYABPPTHPbqjc1qCmBaZx2vN4Ye5DUys/vZwP9BFohFrH/6j/f3IL16/RZkiMN\n" - "JCqVJUzKoZHm1Lesh3Sz8W2jmdv51b2EQJ8HmA==\n" + "MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS\n" + "R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg\n" + "TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw\n" + "MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl\n" + "c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV\n" + "BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n" + "ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG\n" + "C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs\n" + "i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW\n" + "Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH\n" + "Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK\n" + "Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f\n" + "BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl\n" + "cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz\n" + "LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm\n" + "7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz\n" + "Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z\n" + "8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C\n" + "12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==\n" "-----END CERTIFICATE-----\n"; \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 715a8e79..affe8ffd 100644 --- a/platformio.ini +++ b/platformio.ini @@ -21,19 +21,17 @@ board_build.filesystem = littlefs upload_speed = 921600 monitor_speed = 115200 monitor_filters = esp32_exception_decoder -build_flags = +build_flags = !python git_tag_macro.py !python build_date_macro.py + !python cert_updater.py -D CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 -D CONFIG_MDNS_STRICT_MODE=1 -D CORE_DEBUG_LEVEL=1 -D ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=3500 -std=gnu++17 lib_deps = - #use a PR version of the library to fix a bug. Remove this line when the PR is merged - #NimBLE-Arduino PR #878 - #https://github.com/h2zero/NimBLE-Arduino.git#refactor - https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.2.1.zip + https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.2.3.zip https://github.com/teemuatlut/TMCStepper/archive/refs/tags/v0.7.3.zip https://github.com/bblanchon/ArduinoJson/archive/refs/tags/v6.20.0.zip https://github.com/gin66/FastAccelStepper/archive/refs/tags/0.31.2.zip From 40e0459d51d82cb8d598f516d42fcf3d54b6687f Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 25 Mar 2025 20:04:07 -0500 Subject: [PATCH 144/451] Free update client memory after boot. --- src/HTTP_Server_Basic.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/HTTP_Server_Basic.cpp b/src/HTTP_Server_Basic.cpp index d3198048..0f8a09cc 100644 --- a/src/HTTP_Server_Basic.cpp +++ b/src/HTTP_Server_Basic.cpp @@ -31,7 +31,6 @@ IPAddress myIP; const byte DNS_PORT = 53; DNSServer dnsServer; HTTP_Server httpServer; -WiFiClientSecure client; WebServer server(80); void _staSetup() { @@ -646,8 +645,8 @@ void HTTP_Server::stop() { void HTTP_Server::FirmwareUpdate() { HTTPClient http; - // WiFiClientSecure client; - client.setCACert(rootCACertificate); + WiFiClientSecure localClient; + localClient.setCACert(rootCACertificate); SS2K_LOG(HTTP_SERVER_LOG_TAG, "Checking for newer firmware:"); http.begin(userConfig->getFirmwareUpdateURL() + String(FW_VERSIONFILE), rootCACertificate); // check version URL @@ -693,6 +692,7 @@ void HTTP_Server::FirmwareUpdate() { DeserializationError error = deserializeJson(doc, payload); if (error) { SS2K_LOG(HTTP_SERVER_LOG_TAG, "Failed to read file list"); + http.end(); // Make sure to end HTTP before returning return; } httpServer.internetConnection = true; @@ -700,6 +700,9 @@ void HTTP_Server::FirmwareUpdate() { SS2K_LOG(HTTP_SERVER_LOG_TAG, "error downloading %s %d", DATA_FILELIST, httpCode); httpServer.internetConnection = false; } + // End HTTP connection after file list download + http.end(); + JsonArray files = doc.as(); // iterate through file list and download files individually for (JsonVariant v : files) { @@ -717,6 +720,7 @@ void HTTP_Server::FirmwareUpdate() { File file = LittleFS.open(fileName, FILE_WRITE, true); if (!file) { SS2K_LOG(HTTP_SERVER_LOG_TAG, "Failed to create file, %s", fileName); + http.end(); // End HTTP before returning return; } file.print(payload); @@ -727,13 +731,15 @@ void HTTP_Server::FirmwareUpdate() { SS2K_LOG(HTTP_SERVER_LOG_TAG, "Error downloading %s %d", fileName, httpCode); httpServer.internetConnection = false; } + // End HTTP connection after each file download + http.end(); } //////// Update Firmware ///////// if (((availableVer > currentVer) || updateAnyway) && (userConfig->getAutoUpdate())) { SS2K_LOG(HTTP_SERVER_LOG_TAG, "New firmware detected!"); SS2K_LOG(HTTP_SERVER_LOG_TAG, "Upgrading from %s to %s", FIRMWARE_VERSION, payload.c_str()); - t_httpUpdate_return ret = httpUpdate.update(client, userConfig->getFirmwareUpdateURL() + String(FW_BINFILE)); + t_httpUpdate_return ret = httpUpdate.update(localClient, userConfig->getFirmwareUpdateURL() + String(FW_BINFILE)); switch (ret) { case HTTP_UPDATE_FAILED: SS2K_LOG(HTTP_SERVER_LOG_TAG, "HTTP_UPDATE_FAILED Error %d : %s", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str()); @@ -754,5 +760,6 @@ void HTTP_Server::FirmwareUpdate() { }else{ SS2K_LOG(HTTP_SERVER_LOG_TAG, "Could not connect to Github. httpCode: %d", httpCode); } + // localClient will be automatically destroyed when the function exits } From f07f3eec16e1459a72120a1ecb050a4e3121571f Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 25 Mar 2025 20:12:58 -0500 Subject: [PATCH 145/451] Updated vTaskDelay() to regular delay() for consistancy. --- src/BLE_Client.cpp | 4 ++-- src/HTTP_Server_Basic.cpp | 16 +++++++------- src/Main.cpp | 44 +++++++++++++++++++-------------------- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index 7191f2b9..bfc49fdd 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -141,7 +141,7 @@ void bleClientTask(void *pvParameters) { long int scanDelay = millis(); spinBLEClient.checkBLEReconnect(); for (;;) { - vTaskDelay(BLE_CLIENT_DELAY / portTICK_PERIOD_MS); // Delay between loops. + delay(BLE_CLIENT_DELAY); // Delay between loops. // disconnect all connected servers if we're updating via BLE if (ss2k->isUpdating) { @@ -701,7 +701,7 @@ void SpinBLEClient::postConnect() { // appliance. if (userConfig->getFTMSControlPointWrite()) { writeCharacteristic->writeValue(FitnessMachineControlPointProcedure::RequestControl, 1); - vTaskDelay(BLE_NOTIFY_DELAY / portTICK_PERIOD_MS); + delay(BLE_NOTIFY_DELAY); SS2K_LOG(BLE_CLIENT_LOG_TAG, "Activated FTMS Training."); } writeCharacteristic->writeValue(FitnessMachineControlPointProcedure::StartOrResume, 1); diff --git a/src/HTTP_Server_Basic.cpp b/src/HTTP_Server_Basic.cpp index 0f8a09cc..1bf38383 100644 --- a/src/HTTP_Server_Basic.cpp +++ b/src/HTTP_Server_Basic.cpp @@ -48,7 +48,7 @@ void _APSetup() { //WiFi.setHostname(userConfig->getDeviceName()); WiFi.softAPsetHostname(userConfig->getDeviceName()); WiFi.enableAP(true); - vTaskDelay(500/portTICK_RATE_MS); // Micro controller requires some time to reset the mode + delay(500); // Micro controller requires some time to reset the mode } // ********************************WIFI Setup************************* @@ -60,7 +60,7 @@ void startWifi() { SS2K_LOG(HTTP_SERVER_LOG_TAG, "Connecting to: %s", userConfig->getSsid()); _staSetup(); while (WiFi.status() != WL_CONNECTED) { - vTaskDelay(1000 / portTICK_RATE_MS); + delay(1000); SS2K_LOG(HTTP_SERVER_LOG_TAG, "Waiting for connection to be established..."); i++; if (i > WIFI_CONNECT_TIMEOUT) { @@ -69,7 +69,7 @@ void startWifi() { WiFi.disconnect(true, true); WiFi.setAutoReconnect(false); WiFi.mode(WIFI_MODE_NULL); - vTaskDelay(1000 / portTICK_RATE_MS); + delay(1000); break; } } @@ -94,7 +94,7 @@ void startWifi() { SS2K_LOG(HTTP_SERVER_LOG_TAG, "Using Default Password"); WiFi.softAP(userConfig->getDeviceName(), DEFAULT_PASSWORD); } - vTaskDelay(50/portTICK_RATE_MS); + delay(50); myIP = WiFi.softAPIP(); /* Setup the DNS server redirecting all the domains to the apIP */ dnsServer.setErrorReplyCode(DNSReplyCode::NoError); @@ -680,9 +680,9 @@ void HTTP_Server::FirmwareUpdate() { SS2K_LOG(HTTP_SERVER_LOG_TAG, "Updating FileSystem"); http.begin(DATA_UPDATEURL + String(DATA_FILELIST), rootCACertificate); // check version URL - vTaskDelay(100 / portTICK_PERIOD_MS); + delay(100); httpCode = http.GET(); // get data from version file - vTaskDelay(100 / portTICK_PERIOD_MS); + delay(100); StaticJsonDocument<500> doc; if (httpCode == HTTP_CODE_OK) { // if version received String payload; @@ -709,9 +709,9 @@ void HTTP_Server::FirmwareUpdate() { String fileName = "/" + v.as(); http.begin(DATA_UPDATEURL + fileName, rootCACertificate); // check version URL - vTaskDelay(100 / portTICK_PERIOD_MS); + delay(100); httpCode = http.GET(); - vTaskDelay(100 / portTICK_PERIOD_MS); + delay(100); if (httpCode == HTTP_CODE_OK) { String payload; payload = http.getString(); diff --git a/src/Main.cpp b/src/Main.cpp index 31c8ac1c..6bd5ee25 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -103,7 +103,7 @@ void setup() { if (!LittleFS.begin(false)) { SS2K_LOG(MAIN_LOG_TAG, "An Error has occurred while mounting LittleFS."); LittleFS.format(); // Format so that the settings can be saved. - vTaskDelay(100 / portTICK_PERIOD_MS); // Provide some time for the format to happen. + delay(100); // Provide some time for the format to happen. } // Load Config @@ -184,7 +184,7 @@ void SS2K::maintenanceLoop(void *pvParameters) { static bool isScanning = false; while (true) { - vTaskDelay(5 / portTICK_RATE_MS); + delay(5); // Run what used to be in the BLECommunications Task. BLECommunications(); @@ -240,11 +240,11 @@ void SS2K::maintenanceLoop(void *pvParameters) { // Handle flag set for rebooting if (ss2k->rebootFlag) { static bool _loopOnce = false; - vTaskDelay(1000 / portTICK_RATE_MS); + delay(1000); // Let the main task loop complete once before rebooting if (_loopOnce) { // Important to keep this delay high in order to allow coms to finish. - vTaskDelay(1000 / portTICK_RATE_MS); + delay(1000); ESP.restart(); } _loopOnce = true; @@ -390,9 +390,9 @@ void SS2K::FTMSModeShiftModifier() { void SS2K::restartWifi() { httpServer.stop(); - vTaskDelay(100 / portTICK_RATE_MS); + delay(100); stopWifi(); - vTaskDelay(100 / portTICK_RATE_MS); + delay(100); startWifi(); httpServer.start(); } @@ -482,7 +482,7 @@ void SS2K::moveStepper() { if (_stepperDir != userConfig->getStepperDir()) { // User changed the config direction of the stepper wires _stepperDir = userConfig->getStepperDir(); while (stepper->isRunning()) { // Wait until the motor stops running - vTaskDelay(100 / portTICK_PERIOD_MS); + delay(100); } stepper->setDirectionPin(currentBoard.dirPin, _stepperDir); } @@ -529,15 +529,15 @@ void SS2K::resetIfShiftersHeld() { SS2K_LOG(MAIN_LOG_TAG, "Resetting to defaults via shifter buttons."); for (int x = 0; x < 10; x++) { // blink fast to acknowledge digitalWrite(LED_PIN, HIGH); - vTaskDelay(200 / portTICK_PERIOD_MS); + delay(200); digitalWrite(LED_PIN, LOW); } for (int i = 0; i < 20; i++) { LittleFS.format(); userConfig->setDefaults(); - vTaskDelay(200 / portTICK_PERIOD_MS); + delay(200); userConfig->saveToLittleFS(); - vTaskDelay(200 / portTICK_PERIOD_MS); + delay(200); } ESP.restart(); } @@ -583,22 +583,22 @@ void SS2K::goHome(bool bothDirections) { SS2K_LOG(MAIN_LOG_TAG, "Updating driver..."); fitnessMachineService.spinDown(0x01); updateStepperPower(userConfig->getStepperPower() * .2); - vTaskDelay(50 / portTICK_PERIOD_MS); + delay(50); driver.irun(0x02); // low power - vTaskDelay(50 / portTICK_PERIOD_MS); + delay(50); driver.ihold(0x01); - vTaskDelay(50 / portTICK_PERIOD_MS); + delay(50); int threshold = 0; bool stalled = false; // Back off limit in case we are alread here. stepper->move(userConfig->getShiftStep(), true); this->updateStepperSpeed(1500); - vTaskDelay(500 / portTICK_PERIOD_MS); + delay(500); stepper->runBackward(); - vTaskDelay(250 / portTICK_PERIOD_MS); + delay(250); threshold = driver.SG_RESULT(); Serial.printf("%d ", driver.SG_RESULT()); - vTaskDelay(300 / portTICK_PERIOD_MS); + delay(300); fitnessMachineService.spinDown(0x04); while (!stalled) { if (abs(rtConfig->getShifterPosition() - ss2k->lastShifterPosition)) { // let the user abort with the shift button. @@ -609,10 +609,10 @@ void SS2K::goHome(bool bothDirections) { stalled = (driver.SG_RESULT() < threshold - userConfig->getHomingSensitivity()); } stepper->forceStop(); - vTaskDelay(100 / portTICK_PERIOD_MS); + delay(100); stepper->moveTo(stepper->getCurrentPosition() + userConfig->getShiftStep()); while (stepper->isRunning()) { - vTaskDelay(10 / portTICK_PERIOD_MS); + delay(10); } stepper->setCurrentPosition((int32_t)0); ss2k->setTargetPosition(0); @@ -623,12 +623,12 @@ void SS2K::goHome(bool bothDirections) { if (bothDirections) { // Back off limit in case we are alread here. this->updateStepperSpeed(1500); - vTaskDelay(500 / portTICK_PERIOD_MS); + delay(500); stepper->runForward(); - vTaskDelay(1000 / portTICK_PERIOD_MS); // wait until stable + delay(1000); // wait until stable threshold = driver.SG_RESULT(); // take reading Serial.printf("%d ", driver.SG_RESULT()); - vTaskDelay(250 / portTICK_PERIOD_MS); + delay(250); while (!stalled) { if (abs(rtConfig->getShifterPosition() - ss2k->lastShifterPosition)) { // let the user abort with the shift button. userConfig->setHMin(INT32_MIN); @@ -639,7 +639,7 @@ void SS2K::goHome(bool bothDirections) { } stepper->forceStop(); fitnessMachineService.spinDown(0x02); - vTaskDelay(500 / portTICK_PERIOD_MS); + delay(500); rtConfig->setMaxStep(stepper->getCurrentPosition() - 200); SS2K_LOG(MAIN_LOG_TAG, "Max Position found: %d.", rtConfig->getMaxStep()); this->updateStepperSpeed(); From 14077da1cf4fe76a065515ee7237255d194b8e61 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 26 Mar 2025 12:52:41 -0500 Subject: [PATCH 146/451] - Added CSC sensor selection in BLE Scanner html. --- CHANGELOG.md | 3 ++- data/bluetoothscanner.html | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b0c94a8..991d254c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 -Root CA certificates are now updated automatically during every build. ### Changed -- Multiple html and css improvements. +- Multiple html and css improvements. +- Added CSC sensor selection in BLE Scanner html. ### Hardware diff --git a/data/bluetoothscanner.html b/data/bluetoothscanner.html index 00d185ee..4b79e67e 100644 --- a/data/bluetoothscanner.html +++ b/data/bluetoothscanner.html @@ -113,7 +113,7 @@

Device Selection

let option = document.createElement('option'); option.text = device.name || device.address; - if (['0x1818', '0x1826', '6e400001-b5a3-f393-e0a9-e50e24dcca9e', '0bf669f0-45f2-11e7-9598-0800200c9a66'].includes(device.UUID)) { + if (['0x1818', '0x1826', '0x1816', '6e400001-b5a3-f393-e0a9-e50e24dcca9e', '0bf669f0-45f2-11e7-9598-0800200c9a66'].includes(device.UUID)) { PMDropdown.add(option.cloneNode(true)); } if (device.UUID === '0x180d') { From 63d968af8eafd887aa2828fcc4bfb06491c0ec18 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 26 Mar 2025 20:04:58 -0500 Subject: [PATCH 147/451] instead of waiting for 3 readings, wait 5 seconds before setting 0 for cadence or power. --- lib/SS2K/include/sensors/CscSensorData.h | 10 +++++----- lib/SS2K/include/sensors/CyclePowerData.h | 14 ++++++------- lib/SS2K/src/sensors/CscSensorData.cpp | 13 ++++++------ lib/SS2K/src/sensors/CyclePowerData.cpp | 24 +++++++++++++++-------- 4 files changed, 34 insertions(+), 27 deletions(-) diff --git a/lib/SS2K/include/sensors/CscSensorData.h b/lib/SS2K/include/sensors/CscSensorData.h index 20c72af1..61d81400 100644 --- a/lib/SS2K/include/sensors/CscSensorData.h +++ b/lib/SS2K/include/sensors/CscSensorData.h @@ -26,11 +26,11 @@ class CscSensorData : public SensorData { void decode(uint8_t *data, size_t length); private: - float cadence = nanf(""); - float speed = nanf(""); - uint32_t lastWheelEventTime = 0; - uint32_t lastCrankEventTime = 0; + float cadence = nanf(""); + float speed = nanf(""); + uint32_t lastWheelEventTime = 0; + uint32_t lastCrankEventTime = 0; uint32_t lastWheelRevolutions = 0; uint32_t lastCrankRevolutions = 0; - uint8_t missedReadingCount = 0; + unsigned long lastUpdateTime = 0; }; \ No newline at end of file diff --git a/lib/SS2K/include/sensors/CyclePowerData.h b/lib/SS2K/include/sensors/CyclePowerData.h index da3842ce..eaa6462e 100644 --- a/lib/SS2K/include/sensors/CyclePowerData.h +++ b/lib/SS2K/include/sensors/CyclePowerData.h @@ -26,11 +26,11 @@ class CyclePowerData : public SensorData { void decode(uint8_t *data, size_t length); private: - int power = INT_MIN; - float cadence = nanf(""); - uint16_t crankRev = 0; - uint16_t lastCrankRev = 0; - uint16_t lastCrankEventTime = 0; - uint16_t crankEventTime = 0; - uint8_t missedReadingCount = 0; + int power = INT_MIN; + float cadence = nanf(""); + uint16_t crankRev = 0; + uint16_t lastCrankRev = 0; + uint16_t lastCrankEventTime = 0; + uint16_t crankEventTime = 0; + unsigned long lastUpdateTime = 0; }; diff --git a/lib/SS2K/src/sensors/CscSensorData.cpp b/lib/SS2K/src/sensors/CscSensorData.cpp index aaa1363b..54f955a3 100644 --- a/lib/SS2K/src/sensors/CscSensorData.cpp +++ b/lib/SS2K/src/sensors/CscSensorData.cpp @@ -8,6 +8,7 @@ #include "Data.h" #include "endian.h" #include "sensors/CscSensorData.h" +#include "Arduino.h" bool CscSensorData::hasHeartRate() { return false; } @@ -89,15 +90,13 @@ void CscSensorData::decode(uint8_t *data, size_t length) { cadence = this->cadence; } this->cadence = cadence; - this->missedReadingCount = 0; - } else { - this->missedReadingCount++; - } - } else { // the crank rev probably didn't update - if (this->missedReadingCount > 2) { // Require three consecutive readings before setting 0 cadence + this->lastUpdateTime = millis(); + } + } else { + unsigned long currentTime = millis(); + if (currentTime - lastUpdateTime > 5000) { // Require five seconds before setting 0 cadence this->cadence = 0; } - this->missedReadingCount++; } } diff --git a/lib/SS2K/src/sensors/CyclePowerData.cpp b/lib/SS2K/src/sensors/CyclePowerData.cpp index 21db6017..29f93c7c 100644 --- a/lib/SS2K/src/sensors/CyclePowerData.cpp +++ b/lib/SS2K/src/sensors/CyclePowerData.cpp @@ -8,6 +8,7 @@ #include "Data.h" #include "endian.h" #include "sensors/CyclePowerData.h" +#include "Arduino.h" bool CyclePowerData::hasHeartRate() { return false; } @@ -35,7 +36,16 @@ void CyclePowerData::decode(uint8_t *data, size_t length) { // Instantaneous power is always present. Do that first. // first calculate which fields are present. Power is always 2 & 3, cadence // can move depending on the flags. - this->power = get_le16(&data[cPos]); + int newPower = get_le16(&data[cPos]); + // check newPower is greater than zero. If not, wait 5 seconds before setting zero + if (newPower > 0) { + this->power = newPower; + } else { + unsigned long currentTime = millis(); + if (currentTime - lastUpdateTime > 5000) { // Require five seconds before setting 0 power + this->power = 0; + } + } cPos += 2; if (bitRead(flags, 0)) { @@ -86,16 +96,14 @@ void CyclePowerData::decode(uint8_t *data, size_t length) { // Leave cadence unchanged cadence = this->cadence; } - this->cadence = cadence; - this->missedReadingCount = 0; - } else { - this->missedReadingCount++; + this->cadence = cadence; + this->lastUpdateTime = millis(); } - } else { // the crank rev probably didn't update - if (this->missedReadingCount > 2) { // Require three consecutive readings before setting 0 cadence + } else { + unsigned long currentTime = millis(); + if (currentTime - lastUpdateTime > 5000) { // Require five seconds before setting 0 cadence this->cadence = 0; } - this->missedReadingCount++; } } } From 3111d11e26d3f80d1824ddacaf90ebbaeefbf078 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 26 Mar 2025 20:24:56 -0500 Subject: [PATCH 148/451] adjusted BLE connection parameters --- src/BLE_Client.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index bfc49fdd..33e53a9b 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -259,6 +259,7 @@ bool SpinBLEClient::connectToServer() { pClient = NimBLEDevice::getClientByPeerAddress(myDevice->getAddress()); if (pClient) { pClient->setConnectTimeout(500); + pClient->setConnectionParams(24, 48, 0, 200); SS2K_LOG(BLE_CLIENT_LOG_TAG, "Reusing Client"); if (!pClient->connect(myDevice)) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Reconnect failed "); @@ -300,9 +301,9 @@ bool SpinBLEClient::connectToServer() { * connections. Timeout should be a multiple of the interval, minimum is 100ms. * Min interval: 12 * 1.25ms = 15, Max interval: 12 * 1.25ms = 15, 0 latency, 51 * 10ms = 510ms timeout */ - pClient->setConnectionParams(6, 12, 0, 500); + pClient->setConnectionParams(24, 48, 0, 200); /** Set how long we are willing to wait for the connection to complete (seconds), default is 30. */ - pClient->setConnectTimeout(5 * 1000); // 5 seconds + pClient->setConnectTimeout(5000); // 5 seconds if (!pClient->connect(myDevice, false)) { SS2K_LOG(BLE_CLIENT_LOG_TAG, " - Failed to connect client"); From f78452834f58e8df8e424991fb8063dd001401ed Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 26 Mar 2025 21:10:30 -0500 Subject: [PATCH 149/451] Power should update better on ptab4pwr now. --- src/ERG_Mode.cpp | 2 +- src/Power_Table.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 0eb026d6..734420a5 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -60,7 +60,7 @@ void ErgMode::runERG() { // userConfig->setPTab4Pwr(true); // rtConfig->setHomed(true); - if ((!spinBLEClient.connectedPM || userConfig->getPTab4Pwr()) && rtConfig->cad.getValue() && rtConfig->getHomed()) { + if (userConfig->getPTab4Pwr() && rtConfig->getHomed()) { // Lookup watts using the Power Table. pTabUsed4Pwr = true; if (powerTable->_hasBeenLoadedThisSession) { diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 0e50b7c4..e6e89fd6 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -1535,6 +1535,9 @@ bool PowerTable::_save() { } int32_t PowerTable::lookupWatts(int cad, int32_t targetPosition) { + if(cad<1) { + return 0; + } // Convert targetPosition from external format (xTABLE_DIVISOR) to internal format int16_t internalPosition = targetPosition / TABLE_DIVISOR; From d79690e700ef79a147fb123db72f90c66769f8a8 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 26 Mar 2025 21:25:06 -0500 Subject: [PATCH 150/451] build fix --- lib/SS2K/include/sensors/CyclePowerData.h | 15 ++++++++------- lib/SS2K/src/sensors/CscSensorData.cpp | 17 ++++++++++++----- lib/SS2K/src/sensors/CyclePowerData.cpp | 20 ++++++++++++++------ 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/lib/SS2K/include/sensors/CyclePowerData.h b/lib/SS2K/include/sensors/CyclePowerData.h index eaa6462e..83b04b70 100644 --- a/lib/SS2K/include/sensors/CyclePowerData.h +++ b/lib/SS2K/include/sensors/CyclePowerData.h @@ -26,11 +26,12 @@ class CyclePowerData : public SensorData { void decode(uint8_t *data, size_t length); private: - int power = INT_MIN; - float cadence = nanf(""); - uint16_t crankRev = 0; - uint16_t lastCrankRev = 0; - uint16_t lastCrankEventTime = 0; - uint16_t crankEventTime = 0; - unsigned long lastUpdateTime = 0; + int power = INT_MIN; + float cadence = nanf(""); + uint16_t crankRev = 0; + uint16_t lastCrankRev = 0; + uint16_t lastCrankEventTime = 0; + uint16_t crankEventTime = 0; + unsigned long lastCadUpdateTime = 0; + unsigned long lastPwrUpdateTime = 0; }; diff --git a/lib/SS2K/src/sensors/CscSensorData.cpp b/lib/SS2K/src/sensors/CscSensorData.cpp index 54f955a3..70335b61 100644 --- a/lib/SS2K/src/sensors/CscSensorData.cpp +++ b/lib/SS2K/src/sensors/CscSensorData.cpp @@ -5,10 +5,17 @@ * SPDX-License-Identifier: GPL-2.0-only */ +#include #include "Data.h" #include "endian.h" #include "sensors/CscSensorData.h" -#include "Arduino.h" + +// Replacement for Arduino's millis() using standard C++ +static unsigned long getTimeMillis() { + return std::chrono::duration_cast( + std::chrono::steady_clock::now().time_since_epoch() + ).count(); +} bool CscSensorData::hasHeartRate() { return false; } @@ -90,10 +97,10 @@ void CscSensorData::decode(uint8_t *data, size_t length) { cadence = this->cadence; } this->cadence = cadence; - this->lastUpdateTime = millis(); - } - } else { - unsigned long currentTime = millis(); + this->lastUpdateTime = getTimeMillis(); + } + } else { + unsigned long currentTime = getTimeMillis(); if (currentTime - lastUpdateTime > 5000) { // Require five seconds before setting 0 cadence this->cadence = 0; } diff --git a/lib/SS2K/src/sensors/CyclePowerData.cpp b/lib/SS2K/src/sensors/CyclePowerData.cpp index 29f93c7c..a85e1b56 100644 --- a/lib/SS2K/src/sensors/CyclePowerData.cpp +++ b/lib/SS2K/src/sensors/CyclePowerData.cpp @@ -5,10 +5,17 @@ * SPDX-License-Identifier: GPL-2.0-only */ +#include #include "Data.h" #include "endian.h" #include "sensors/CyclePowerData.h" -#include "Arduino.h" + +// Replacement for Arduino's millis() using standard C++ +static unsigned long getTimeMillis() { + return std::chrono::duration_cast( + std::chrono::steady_clock::now().time_since_epoch() + ).count(); +} bool CyclePowerData::hasHeartRate() { return false; } @@ -40,9 +47,10 @@ void CyclePowerData::decode(uint8_t *data, size_t length) { // check newPower is greater than zero. If not, wait 5 seconds before setting zero if (newPower > 0) { this->power = newPower; + this->lastPwrUpdateTime = getTimeMillis(); } else { - unsigned long currentTime = millis(); - if (currentTime - lastUpdateTime > 5000) { // Require five seconds before setting 0 power + unsigned long currentTime = getTimeMillis(); + if (currentTime - lastPwrUpdateTime > 5000) { // Require five seconds before setting 0 power this->power = 0; } } @@ -97,11 +105,11 @@ void CyclePowerData::decode(uint8_t *data, size_t length) { cadence = this->cadence; } this->cadence = cadence; - this->lastUpdateTime = millis(); + this->lastCadUpdateTime = getTimeMillis(); } } else { - unsigned long currentTime = millis(); - if (currentTime - lastUpdateTime > 5000) { // Require five seconds before setting 0 cadence + unsigned long currentTime = getTimeMillis(); + if (currentTime - lastCadUpdateTime > 5000) { // Require five seconds before setting 0 cadence this->cadence = 0; } } From 8b8ec61efdc1d5957e68b27fb53ca902c2e22dd1 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 26 Mar 2025 21:27:16 -0500 Subject: [PATCH 151/451] Modified ERG Sensitivity --- src/ERG_Mode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 734420a5..2058f726 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -227,7 +227,7 @@ void ErgMode::_setPointChangeState(int newCadence, Measurement& newWatts) { // PrevError void ErgMode::_inSetpointState(int newCadence, Measurement& newWatts) { // Setting Gains For PID Loop - float Kp = userConfig->getERGSensitivity() * 2; + float Kp = userConfig->getERGSensitivity(); float Ki = 0.1; float Kd = 0.1; From da5a4216c4f080a40c35c99ffa8e87399e896745 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Thu, 27 Mar 2025 10:02:20 -0500 Subject: [PATCH 152/451] shifter position resets to 0 after homing --- src/Main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Main.cpp b/src/Main.cpp index 6bd5ee25..791f76d5 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -657,6 +657,7 @@ void SS2K::goHome(bool bothDirections) { userConfig->saveToLittleFS(); rtConfig->setHomed(true); this->setupTMCStepperDriver(true); + rtConfig->setShifterPosition(0); ss2k->setTargetPosition(0); } From cdd467517386c1d31cda8fd82f7183647f67e1b8 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Thu, 27 Mar 2025 20:46:14 -0500 Subject: [PATCH 153/451] shorter time before registering zero --- include/settings.h | 4 ++-- lib/SS2K/src/sensors/CscSensorData.cpp | 4 ++-- lib/SS2K/src/sensors/CyclePowerData.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/settings.h b/include/settings.h index d292b0a6..9c9dffb0 100644 --- a/include/settings.h +++ b/include/settings.h @@ -208,7 +208,7 @@ const char* const DEFAULT_PASSWORD = "password"; #define LED_PIN 2 // Max tries that BLE client will perform on reconnect -#define MAX_RECONNECT_TRIES 3 +#define MAX_RECONNECT_TRIES 1 // loop speed for the SmartSpin2k BLE communications #define BLE_NOTIFY_DELAY 503 @@ -339,7 +339,7 @@ const char* const DEFAULT_PASSWORD = "password"; #define DEFAULT_HOMING_SENSITIVITY 50 // BLE automatic reconnect duration in milliseconds. Set this low to avoid interruption. -#define BLE_RECONNECT_SCAN_DURATION 5000 +#define BLE_RECONNECT_SCAN_DURATION 1000 // Task Stack Sizes #define MAIN_STACK 6500 diff --git a/lib/SS2K/src/sensors/CscSensorData.cpp b/lib/SS2K/src/sensors/CscSensorData.cpp index 70335b61..6e8f24b2 100644 --- a/lib/SS2K/src/sensors/CscSensorData.cpp +++ b/lib/SS2K/src/sensors/CscSensorData.cpp @@ -82,7 +82,7 @@ void CscSensorData::decode(uint8_t *data, size_t length) { // Handle timer wraparound (16-bit timer) uint16_t timeDiff = (crankEventTime >= lastCrankEventTime) ? (crankEventTime - lastCrankEventTime) : - (65535 - lastCrankEventTime + crankEventTime); + (UINT16_MAX - lastCrankEventTime + crankEventTime); if (timeDiff > 0) { // Time is in 1/1024th of a second @@ -101,7 +101,7 @@ void CscSensorData::decode(uint8_t *data, size_t length) { } } else { unsigned long currentTime = getTimeMillis(); - if (currentTime - lastUpdateTime > 5000) { // Require five seconds before setting 0 cadence + if (currentTime - lastUpdateTime > 2500) { // Require five seconds before setting 0 cadence this->cadence = 0; } } diff --git a/lib/SS2K/src/sensors/CyclePowerData.cpp b/lib/SS2K/src/sensors/CyclePowerData.cpp index a85e1b56..3d47723a 100644 --- a/lib/SS2K/src/sensors/CyclePowerData.cpp +++ b/lib/SS2K/src/sensors/CyclePowerData.cpp @@ -50,7 +50,7 @@ void CyclePowerData::decode(uint8_t *data, size_t length) { this->lastPwrUpdateTime = getTimeMillis(); } else { unsigned long currentTime = getTimeMillis(); - if (currentTime - lastPwrUpdateTime > 5000) { // Require five seconds before setting 0 power + if (currentTime - lastPwrUpdateTime > 2500) { // Require five seconds before setting 0 power this->power = 0; } } @@ -109,7 +109,7 @@ void CyclePowerData::decode(uint8_t *data, size_t length) { } } else { unsigned long currentTime = getTimeMillis(); - if (currentTime - lastCadUpdateTime > 5000) { // Require five seconds before setting 0 cadence + if (currentTime - lastCadUpdateTime > 2500) { // Require five seconds before setting 0 cadence this->cadence = 0; } } From d56b67ca3351d88f810c0e59339c9f9196f82e55 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Thu, 27 Mar 2025 21:02:45 -0500 Subject: [PATCH 154/451] removed depreciated checkDriverTemperature() --- include/Main.h | 1 - src/Main.cpp | 17 ----------------- 2 files changed, 18 deletions(-) diff --git a/include/Main.h b/include/Main.h index 1d8ce3b5..da7a7d4f 100644 --- a/include/Main.h +++ b/include/Main.h @@ -64,7 +64,6 @@ class SS2K { void updateStepperPower(int pwr = 0); void updateStealthChop(); void updateStepperSpeed(int speed = 0); - void checkDriverTemperature(); void FTMSModeShiftModifier(); static void rxSerial(void); void txSerial(); diff --git a/src/Main.cpp b/src/Main.cpp index 791f76d5..dba8eafc 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -704,23 +704,6 @@ void SS2K::updateStepperSpeed(int speed) { stepper->setSpeedInHz(speed); } -// Checks the driver temperature and throttles power if above threshold. -void SS2K::checkDriverTemperature() { - static bool overTemp = false; - if (static_cast(temperatureRead()) > THROTTLE_TEMP) { // Start throttling driver power at 72C on the ESP32 - uint8_t throttledPower = (THROTTLE_TEMP - static_cast(temperatureRead())) + currentBoard.pwrScaler; - driver.irun(throttledPower); - SS2K_LOG(MAIN_LOG_TAG, "Over temp! Driver is throttling down! ESP32 @ %f C", temperatureRead()); - overTemp = true; - } else if (static_cast(temperatureRead()) < THROTTLE_TEMP) { - if (overTemp) { - SS2K_LOG(MAIN_LOG_TAG, "Temperature is now under control. Driver current reset."); - driver.irun(currentBoard.pwrScaler); - } - overTemp = false; - } -} - void SS2K::txSerial() { // Serial.printf(" Before TX "); if (PELOTON_TX && (txCheck >= 1)) { static int alternate = 0; From 1557797771c50474caada0ef2849af8804f5cc9d Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Thu, 27 Mar 2025 21:06:03 -0500 Subject: [PATCH 155/451] removed depreciated SpinBLEAdvertisedDevice::print() --- include/BLE_Common.h | 1 - src/BLE_Client.cpp | 17 ----------------- 2 files changed, 18 deletions(-) diff --git a/include/BLE_Common.h b/include/BLE_Common.h index d3e0988a..2e05269d 100644 --- a/include/BLE_Common.h +++ b/include/BLE_Common.h @@ -176,7 +176,6 @@ class SpinBLEAdvertisedDevice { bool getPostConnected() { return isPostConnected; } void set(const NimBLEAdvertisedDevice* device, int id = BLE_HS_CONN_HANDLE_NONE, BLEUUID inServiceUUID = (uint16_t)0x0000, BLEUUID inCharUUID = (uint16_t)0x0000); void reset(bool resetAdvertisedDevice = true); - void print(); bool enqueueData(uint8_t data[NOTIFY_DATA_QUEUE_SIZE], size_t length, NimBLEUUID serviceUUID, NimBLEUUID charUUID); NotifyData dequeueData(); }; diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index 33e53a9b..acaf071a 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -760,23 +760,6 @@ NotifyData SpinBLEAdvertisedDevice::dequeueData() { return receivedNotifyData; } -// Was changed in notify-Buffer - - may not be needed ********************************************************************** -void SpinBLEAdvertisedDevice::print() { - char logBuf[250]; - char *logBufP = logBuf; - logBufP += sprintf(logBufP, "Address: (%s)", peerAddress.toString().c_str()); - logBufP += sprintf(logBufP, " Client ID: (%d)", connectedClientID); - logBufP += sprintf(logBufP, " SerUUID: (%s)", serviceUUID.toString().c_str()); - logBufP += sprintf(logBufP, " CharUUID: (%s)", charUUID.toString().c_str()); - logBufP += sprintf(logBufP, " HRM: (%s)", isHRM ? "true" : "false"); - logBufP += sprintf(logBufP, " PM: (%s)", isPM ? "true" : "false"); - logBufP += sprintf(logBufP, " CSC: (%s)", isCSC ? "true" : "false"); - logBufP += sprintf(logBufP, " CT: (%s)", isCT ? "true" : "false"); - logBufP += sprintf(logBufP, " doConnect: (%s)", doConnect ? "true" : "false"); - strcat(logBufP, "|"); - SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s", String(logBuf)); -} - void SpinBLEClient::connectBLE_HID(NimBLEClient *pClient) { NimBLERemoteService *pSvc = nullptr; NimBLERemoteCharacteristic *pChr = nullptr; From 8ad5742ea9df17ab2ccc1dfdf598ab441ab4fe98 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Thu, 27 Mar 2025 21:11:19 -0500 Subject: [PATCH 156/451] removed depreciated ErgMode::_writeLogHeader() --- include/BLE_Common.h | 1 - include/ERG_Mode.h | 1 - src/ERG_Mode.cpp | 4 ---- 3 files changed, 6 deletions(-) diff --git a/include/BLE_Common.h b/include/BLE_Common.h index 2e05269d..31f343d8 100644 --- a/include/BLE_Common.h +++ b/include/BLE_Common.h @@ -193,7 +193,6 @@ class SpinBLEClient { boolean doScan = false; bool dontBlockScan = true; int intentionalDisconnect = 0; - int noReadingIn = 0; long int cscCumulativeCrankRev = 0; double cscLastCrankEvtTime = 0.0; long int cscCumulativeWheelRev = 0; diff --git a/include/ERG_Mode.h b/include/ERG_Mode.h index 4244f802..6691fc20 100644 --- a/include/ERG_Mode.h +++ b/include/ERG_Mode.h @@ -20,7 +20,6 @@ class ErgMode { void runERG(); void computeErg(); void computeResistance(); - void _writeLogHeader(); void _writeLog(float currentIncline, float newIncline, int currentSetPoint, int newSetPoint, int currentWatts, int newWatts, int currentCadence, int newCadence); private: diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 2058f726..81e2eac0 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -324,10 +324,6 @@ bool ErgMode::_userIsSpinning(int cadence, float incline) { return true; } -void ErgMode::_writeLogHeader() { - SS2K_LOGW(ERG_MODE_LOG_CSV_TAG, "current incline;new incline;current setpoint;new setpoint;current watts;new watts;current cadence;new cadence;"); -} - void ErgMode::_writeLog(float currentIncline, float newIncline, int currentSetPoint, int newSetPoint, int currentWatts, int newWatts, int currentCadence, int newCadence) { SS2K_LOGW(ERG_MODE_LOG_CSV_TAG, "%d;%.2f;%.2f;%d;%d;%d;%d;%d", currentIncline, newIncline, currentSetPoint, newSetPoint, currentWatts, newWatts, currentCadence, newCadence); } From 0e03708ad19000d26c52f86bfbdba3f5309f700e Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Fri, 28 Mar 2025 11:48:16 -0500 Subject: [PATCH 157/451] MDNS is working --- include/BLE_SB20_Service.h | 4 +- include/DirConManager.h | 40 + .../SHIFTR-main/.github/workflows/build.py | 62 ++ .../SHIFTR-main/.github/workflows/build.yml | 206 ++++ reference/SHIFTR-main/.gitignore | 4 + reference/SHIFTR-main/LICENSE | 674 +++++++++++++ reference/SHIFTR-main/NOTICE.txt | 23 + reference/SHIFTR-main/README.md | 104 ++ reference/SHIFTR-main/VirtualShifting.md | 95 ++ .../SHIFTR-main/docs/Assigned_Numbers.pdf | Bin 0 -> 1253127 bytes ...ce_Profile_-_Fitness_Equipment_-_Rev_5.txt | 3 + ...ANT_Message_Protocol_and_Usage_Rev_5.1.txt | 3 + reference/SHIFTR-main/docs/FTMS_v1.0.pdf | Bin 0 -> 1351293 bytes .../docs/How-to FE-C over BLE v1_0_0.pdf | Bin 0 -> 747726 bytes .../docs/WT32-ETH01_datasheet_V1.4+-+en.pdf | Bin 0 -> 665833 bytes .../images/connected_to_tacx_neo_2t.jpg | Bin 0 -> 228032 bytes .../tacx_neo_2t_and_zwift_cog_and_device.jpg | Bin 0 -> 242674 bytes .../SHIFTR-main/images/wt32-eth01_case.jpg | Bin 0 -> 106037 bytes .../include/BTAdvertisedDeviceCallbacks.h | 10 + .../SHIFTR-main/include/BTClientCallbacks.h | 12 + .../SHIFTR-main/include/BTDeviceManager.h | 60 ++ .../SHIFTR-main/include/Characteristic.h | 35 + .../include/CharacteristicCallbacks.h | 14 + reference/SHIFTR-main/include/Config.h | 21 + reference/SHIFTR-main/include/DirConManager.h | 94 ++ reference/SHIFTR-main/include/DirConMessage.h | 48 + reference/SHIFTR-main/include/FTMS.h | 76 ++ reference/SHIFTR-main/include/Service.h | 37 + .../SHIFTR-main/include/ServiceManager.h | 29 + .../include/ServiceManagerCallbacks.h | 13 + .../SHIFTR-main/include/SettingsManager.h | 70 ++ reference/SHIFTR-main/include/UUIDs.h | 26 + reference/SHIFTR-main/include/Utils.h | 23 + reference/SHIFTR-main/include/Version.h | 16 + .../lib/Calculations/src/Calculations.cpp | 221 +++++ .../lib/Calculations/src/Calculations.h | 30 + .../SHIFTR-main/lib/Logger/src/Logger.cpp | 31 + reference/SHIFTR-main/lib/Logger/src/Logger.h | 25 + reference/SHIFTR-main/platformio.ini | 30 + reference/SHIFTR-main/src-web/devicesettings | 29 + reference/SHIFTR-main/src-web/favicon.ico | Bin 0 -> 17551 bytes reference/SHIFTR-main/src-web/index.html | 147 +++ reference/SHIFTR-main/src-web/settings.html | 165 +++ reference/SHIFTR-main/src-web/status | 14 + reference/SHIFTR-main/src-web/style.css | 462 +++++++++ .../src/BTAdvertisedDeviceCallbacks.cpp | 23 + .../SHIFTR-main/src/BTClientCallbacks.cpp | 17 + reference/SHIFTR-main/src/BTDeviceManager.cpp | 479 +++++++++ reference/SHIFTR-main/src/Characteristic.cpp | 69 ++ reference/SHIFTR-main/src/DirConManager.cpp | 938 ++++++++++++++++++ reference/SHIFTR-main/src/DirConMessage.cpp | 253 +++++ reference/SHIFTR-main/src/Service.cpp | 61 ++ reference/SHIFTR-main/src/ServiceManager.cpp | 71 ++ reference/SHIFTR-main/src/SettingsManager.cpp | 164 +++ reference/SHIFTR-main/src/Utils.cpp | 69 ++ reference/SHIFTR-main/src/main.cpp | 479 +++++++++ .../test/test_calculations/test_main.cpp | 72 ++ src/BLE_Cycling_Power_Service.cpp | 4 +- src/BLE_Cycling_Speed_Cadence.cpp | 5 +- src/BLE_Fitness_Machine_Service.cpp | 5 +- src/BLE_Heart_Service.cpp | 5 +- src/DirConManager.cpp | 105 ++ src/HTTP_Server_Basic.cpp | 11 + src/Main.cpp | 3 + 64 files changed, 5783 insertions(+), 6 deletions(-) create mode 100644 include/DirConManager.h create mode 100644 reference/SHIFTR-main/.github/workflows/build.py create mode 100644 reference/SHIFTR-main/.github/workflows/build.yml create mode 100644 reference/SHIFTR-main/.gitignore create mode 100644 reference/SHIFTR-main/LICENSE create mode 100644 reference/SHIFTR-main/NOTICE.txt create mode 100644 reference/SHIFTR-main/README.md create mode 100644 reference/SHIFTR-main/VirtualShifting.md create mode 100644 reference/SHIFTR-main/docs/Assigned_Numbers.pdf create mode 100644 reference/SHIFTR-main/docs/D000001231_-_ANT+_Device_Profile_-_Fitness_Equipment_-_Rev_5.txt create mode 100644 reference/SHIFTR-main/docs/D00000652_ANT_Message_Protocol_and_Usage_Rev_5.1.txt create mode 100644 reference/SHIFTR-main/docs/FTMS_v1.0.pdf create mode 100644 reference/SHIFTR-main/docs/How-to FE-C over BLE v1_0_0.pdf create mode 100644 reference/SHIFTR-main/docs/WT32-ETH01_datasheet_V1.4+-+en.pdf create mode 100644 reference/SHIFTR-main/images/connected_to_tacx_neo_2t.jpg create mode 100644 reference/SHIFTR-main/images/tacx_neo_2t_and_zwift_cog_and_device.jpg create mode 100644 reference/SHIFTR-main/images/wt32-eth01_case.jpg create mode 100644 reference/SHIFTR-main/include/BTAdvertisedDeviceCallbacks.h create mode 100644 reference/SHIFTR-main/include/BTClientCallbacks.h create mode 100644 reference/SHIFTR-main/include/BTDeviceManager.h create mode 100644 reference/SHIFTR-main/include/Characteristic.h create mode 100644 reference/SHIFTR-main/include/CharacteristicCallbacks.h create mode 100644 reference/SHIFTR-main/include/Config.h create mode 100644 reference/SHIFTR-main/include/DirConManager.h create mode 100644 reference/SHIFTR-main/include/DirConMessage.h create mode 100644 reference/SHIFTR-main/include/FTMS.h create mode 100644 reference/SHIFTR-main/include/Service.h create mode 100644 reference/SHIFTR-main/include/ServiceManager.h create mode 100644 reference/SHIFTR-main/include/ServiceManagerCallbacks.h create mode 100644 reference/SHIFTR-main/include/SettingsManager.h create mode 100644 reference/SHIFTR-main/include/UUIDs.h create mode 100644 reference/SHIFTR-main/include/Utils.h create mode 100644 reference/SHIFTR-main/include/Version.h create mode 100644 reference/SHIFTR-main/lib/Calculations/src/Calculations.cpp create mode 100644 reference/SHIFTR-main/lib/Calculations/src/Calculations.h create mode 100644 reference/SHIFTR-main/lib/Logger/src/Logger.cpp create mode 100644 reference/SHIFTR-main/lib/Logger/src/Logger.h create mode 100644 reference/SHIFTR-main/platformio.ini create mode 100644 reference/SHIFTR-main/src-web/devicesettings create mode 100644 reference/SHIFTR-main/src-web/favicon.ico create mode 100644 reference/SHIFTR-main/src-web/index.html create mode 100644 reference/SHIFTR-main/src-web/settings.html create mode 100644 reference/SHIFTR-main/src-web/status create mode 100644 reference/SHIFTR-main/src-web/style.css create mode 100644 reference/SHIFTR-main/src/BTAdvertisedDeviceCallbacks.cpp create mode 100644 reference/SHIFTR-main/src/BTClientCallbacks.cpp create mode 100644 reference/SHIFTR-main/src/BTDeviceManager.cpp create mode 100644 reference/SHIFTR-main/src/Characteristic.cpp create mode 100644 reference/SHIFTR-main/src/DirConManager.cpp create mode 100644 reference/SHIFTR-main/src/DirConMessage.cpp create mode 100644 reference/SHIFTR-main/src/Service.cpp create mode 100644 reference/SHIFTR-main/src/ServiceManager.cpp create mode 100644 reference/SHIFTR-main/src/SettingsManager.cpp create mode 100644 reference/SHIFTR-main/src/Utils.cpp create mode 100644 reference/SHIFTR-main/src/main.cpp create mode 100644 reference/SHIFTR-main/test/test_calculations/test_main.cpp create mode 100644 src/DirConManager.cpp diff --git a/include/BLE_SB20_Service.h b/include/BLE_SB20_Service.h index e29f5bde..21e8f036 100644 --- a/include/BLE_SB20_Service.h +++ b/include/BLE_SB20_Service.h @@ -11,8 +11,8 @@ #include "BLE_Common.h" // See https://github.com/JanDeVisser/stages-monitor/tree/master/sb20display -#define SB20_SERVICE_UUID "a026ee0b-0a7d-4ab3-97fa-f1500f9feb8b" -#define SB20_CHARACTERISTIC_UUID "a026e037-0a7d-4ab3-97fa-f1500f9feb8b" +#define SB20_SERVICE_UUID "0c46beaf-9c22-48ff-ae0e-c6eae1a2f4e5" +#define SB20_CHARACTERISTIC_UUID "0c46beb0-9c22-48ff-ae0e-c6eae1a2f4e5" struct SB20Data { uint8_t gear; // Calculated Gear (1-22) diff --git a/include/DirConManager.h b/include/DirConManager.h new file mode 100644 index 00000000..8fb3745f --- /dev/null +++ b/include/DirConManager.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 Anthony Doud & Joel Baranick + * All rights reserved + * + * SPDX-License-Identifier: GPL-2.0-only + */ + +#ifndef DIRCONMANAGER_H +#define DIRCONMANAGER_H + +#include "Main.h" +#include "BLE_Common.h" +#include +#include + +// DirCon protocol definitions +#define DIRCON_MDNS_SERVICE_NAME "_wahoo-fitness-tnp" +#define DIRCON_MDNS_SERVICE_PROTOCOL "tcp" +#define DIRCON_TCP_PORT 8080 +#define DIRCON_MAX_CLIENTS 3 + +class DirConManager { +public: + static bool start(); + static void stop(); + static void update(); + static void handleData(); + static String getStatusMessage(); + + // Add a BLE service UUID to DirCon MDNS service + static void addBleServiceUuid(const NimBLEUUID& serviceUuid); + +private: + static bool started; + static String statusMessage; + static WiFiClient dirConClients[DIRCON_MAX_CLIENTS]; + static void setupMDNS(); +}; + +#endif // DIRCONMANAGER_H \ No newline at end of file diff --git a/reference/SHIFTR-main/.github/workflows/build.py b/reference/SHIFTR-main/.github/workflows/build.py new file mode 100644 index 00000000..061710c8 --- /dev/null +++ b/reference/SHIFTR-main/.github/workflows/build.py @@ -0,0 +1,62 @@ +import subprocess +import os +import sys +import shutil +from datetime import datetime + +Import("env") + +# determine the latest releasev semver +latest_release_tag = subprocess.run(["git", "tag", "-l", "--sort=-committerdate"], stdout=subprocess.PIPE, text=True) +latest_release_tag = latest_release_tag.stdout.strip() +latest_release_tag = latest_release_tag.split("\n")[0] + +print ("\033[93;1;4mLatest Release Tag : " + latest_release_tag + "\033[0m") + +# determine last release version +latest_release_tag_parts = latest_release_tag.split("-") +latest_release_semver_incl_v = latest_release_tag_parts[0] +latest_release_semver = latest_release_semver_incl_v[1:] +latest_release_digits = latest_release_semver.split(".") +latest_release_main = latest_release_digits[0] +latest_release_minor = latest_release_digits[1] +latest_release_patch = latest_release_digits[2] + +# increase patch for local development build +latest_release_patch = str(int(latest_release_patch) + 1) +latest_release_semver = latest_release_main + "." + latest_release_minor + "." + latest_release_patch +latest_release_semver_incl_v = "v" + latest_release_semver + +print ("\033[93;1;4mLatest Release Main : " + latest_release_main + "\033[0m") +print ("\033[93;1;4mLatest Release Minor : " + latest_release_minor + "\033[0m") +print ("\033[93;1;4mLatest Release Patch : " + latest_release_patch + "\033[0m") + + +# determine current commit hash +current_commit_hash = subprocess.run(["git", "rev-parse", "--short", "HEAD"], stdout=subprocess.PIPE, text=True) +current_commit_hash = current_commit_hash.stdout.strip() +print ("\033[93;1;4mCurrent Commit Hash : " + current_commit_hash + "\033[0m") + +# determine the build timstamp +build_timestamp = datetime.now().strftime("%Y-%b-%d %H:%M:%S") +print ("\033[93;1;4mBuild Timestamp : " + build_timestamp + "\033[0m") + +# store the results in a source file, so our source code has access to it +include_file = open('include/Version.h', 'w') +include_file.write("// ##########################################################################\n") +include_file.write("// ### This file is generated by build and Continuous Integration scripts ###\n") +include_file.write("// ### .github/workflows/build.py for local development environment ###\n") +include_file.write("// ### .github/workflows/build.yml for CI environment ###\n") +include_file.write("// ### Changes will be overwritten on the next build! ###\n") +include_file.write("// ##########################################################################\n") +include_file.write("\n") +include_file.write("#ifndef VERSION_H\n") +include_file.write("#define VERSION_H\n") +include_file.write("#define VERSION \"" + latest_release_semver_incl_v + "\"\n") +include_file.write("#define VERSION_MAJOR " + latest_release_main + "\n") +include_file.write("#define VERSION_MINOR " + latest_release_minor + "\n") +include_file.write("#define VERSION_PATCH " + latest_release_patch + "\n") +include_file.write("#define VERSION_BUILD \"" + current_commit_hash + "\"\n") +include_file.write("#define VERSION_TIMESTAMP \"" + build_timestamp + "\"\n") +include_file.write("#endif\n") +include_file.close() diff --git a/reference/SHIFTR-main/.github/workflows/build.yml b/reference/SHIFTR-main/.github/workflows/build.yml new file mode 100644 index 00000000..0c4d9997 --- /dev/null +++ b/reference/SHIFTR-main/.github/workflows/build.yml @@ -0,0 +1,206 @@ +# Nice article: https://piolabs.com/blog/insights/cicd-testing-coverage-versioning.html +name: Build and Release +on: + workflow_dispatch: + push: + branches: [ main, develop ] + +jobs: + versioning: + name: Determine version, Build and Release + permissions: write-all + + runs-on: ubuntu-latest + outputs: + branchname: ${{ steps.versioninfo.outputs.branchname }} + commithash: ${{ steps.versioninfo.outputs.commithash }} + buildtimestamp: ${{ steps.versioninfo.outputs.buildtimestamp }} + lastmajordigit: ${{ steps.versioninfo.outputs.lastmajordigit }} + lastminordigit: ${{ steps.versioninfo.outputs.lastminordigit }} + lastpatchdigit: ${{ steps.versioninfo.outputs.lastpatchdigit }} + lastversion: ${{ steps.versioninfo.outputs.lastversion }} + nextmajordigit: ${{ steps.selectversion.outputs.nextmajordigit }} + nextminordigit: ${{ steps.selectversion.outputs.nextminordigit }} + nextpatchdigit: ${{ steps.selectversion.outputs.nextpatchdigit }} + buildversion: ${{ steps.selectversion.outputs.buildversion }} + buildversionfilename: ${{ steps.selectversion.outputs.buildversionfilename }} + + steps: + - name: Enable caching + uses: actions/cache@v3 + with: + path: | + ~/.cache/pip + ~/.platformio/.cache + key: ${{ runner.os }}-pio + + - name: Checkout Repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get version data + id: versioninfo + run: | + echo "extract branch name from github_ref '${{ github.ref }}'" + declare branchname=$(echo "${{ github.ref }}" | cut -d'/' -f 3-) + echo "clean branch name = $branchname" + echo "extract commit short hash : $(git rev-parse --short HEAD)" + declare commithash=$(git rev-parse --short HEAD) + echo "extract build timestamp" + declare buildtimestamp=$(date "+%Y-%b-%d-%H:%M:%S") + echo "buildtimestamp = $buildtimestamp" + declare fulltag=$(git describe --tag $(git rev-parse --verify refs/remotes/origin/main)) + echo "fulltag = [$fulltag]" + declare versiontag=$(echo $fulltag | cut -d'-' -f1) + echo "extract SemVer numbers from version tag [$versiontag]" + declare -i lastmajordigit=$(echo $versiontag | cut -c 2- | cut -d'.' -f1) + echo "lastmajordigit = $lastmajordigit" + declare -i lastminordigit=$(echo $versiontag | cut -c 1- | cut -d'.' -f2) + echo "lastminordigit = $lastminordigit" + declare -i lastpatchdigit=$(echo $versiontag | cut -c 1- | cut -d'.' -f3) + echo "lastpatchdigit = $lastpatchdigit" + declare lastversion="v$lastmajordigit.$lastminordigit.$lastpatchdigit" + echo "output variables to GitHub Actions" + echo "branchname=$branchname" >> $GITHUB_OUTPUT + echo "lastmajordigit=$lastmajordigit" >> $GITHUB_OUTPUT + echo "lastminordigit=$lastminordigit" >> $GITHUB_OUTPUT + echo "lastpatchdigit=$lastpatchdigit" >> $GITHUB_OUTPUT + echo "commithash=$commithash" >> $GITHUB_OUTPUT + echo "buildtimestamp=$buildtimestamp" >> $GITHUB_OUTPUT + echo "lastversion=$lastversion" >> $GITHUB_OUTPUT + + - name: Determine which version to build + id: selectversion + run: | + echo "Triggered from Branch : ${{ steps.versioninfo.outputs.branchname }}" + echo "Commit hash : ${{ steps.versioninfo.outputs.commithash }}" + echo "Last version : ${{ steps.versioninfo.outputs.lastversion }}" + echo " Major : ${{ steps.versioninfo.outputs.lastmajordigit }}" + echo " Minor : ${{ steps.versioninfo.outputs.lastminordigit }}" + echo " Patch : ${{ steps.versioninfo.outputs.lastpatchdigit }}" + if [ "${{ steps.versioninfo.outputs.branchname }}" == "main" ]; then + echo "Triggered from merge on main branch with commit title : ${{ github.event.head_commit.message }}" + if [[ "${{ github.event.head_commit.message }}" == *"major"* ]]; then + echo "Incrementing Major versionDigit" + declare -i nextmajordigit=${{ steps.versioninfo.outputs.lastmajordigit }}+1 + declare -i nextminordigit=0 + declare -i nextpatchdigit=0 + declare buildversion="v$nextmajordigit.$nextminordigit.$nextpatchdigit" + declare buildversionfilename=$(echo "SHIFTR-${buildversion}") + + elif [[ "${{ github.event.head_commit.message }}" == *"minor"* ]]; then + echo "Incrementing Minor versionDigit" + declare -i nextmajordigit=${{ steps.versioninfo.outputs.lastmajordigit }} + declare -i nextminordigit=${{ steps.versioninfo.outputs.lastminordigit }}+1 + declare -i nextpatchdigit=0 + declare buildversion="v$nextmajordigit.$nextminordigit.$nextpatchdigit" + declare buildversionfilename=$(echo "SHIFTR-${buildversion}") + else + echo "Incrementing Patch versionDigit" + declare -i nextmajordigit=${{ steps.versioninfo.outputs.lastmajordigit }} + declare -i nextminordigit=${{ steps.versioninfo.outputs.lastminordigit }} + declare -i nextpatchdigit=${{ steps.versioninfo.outputs.lastpatchdigit }}+1 + declare buildversion="v$nextmajordigit.$nextminordigit.$nextpatchdigit" + declare buildversionfilename=$(echo "SHIFTR-${buildversion}") + fi + else + echo "Not on main branch -> development version" + declare -i nextmajordigit=${{ steps.versioninfo.outputs.lastmajordigit }} + declare -i nextminordigit=${{ steps.versioninfo.outputs.lastminordigit }} + declare -i nextpatchdigit=${{ steps.versioninfo.outputs.lastpatchdigit }} + declare buildversion="v$nextmajordigit.$nextminordigit.$nextpatchdigit-${{ steps.versioninfo.outputs.commithash }}" + declare buildversionfilename=$(echo "SHIFTR-${buildversion}") + fi + echo "Building Version : $buildversion" + echo " Major : $nextmajordigit" + echo " Minor : $nextminordigit" + echo " Patch : $nextpatchdigit" + echo "Filename : $buildversionfilename" + echo "output variables to GitHub Actions" + echo "nextmajordigit=$nextmajordigit" >> $GITHUB_OUTPUT + echo "nextminordigit=$nextminordigit" >> $GITHUB_OUTPUT + echo "nextpatchdigit=$nextpatchdigit" >> $GITHUB_OUTPUT + echo "buildversion=$buildversion" >> $GITHUB_OUTPUT + echo "buildversionfilename=$buildversionfilename" >> $GITHUB_OUTPUT + + - name: Show Build info + id: showbuildinfo + run: | + echo "Build Version : ${{ steps.selectversion.outputs.buildversion }}" + echo " Major : ${{ steps.selectversion.outputs.nextmajordigit }}" + echo " Minor : ${{ steps.selectversion.outputs.nextminordigit }}" + echo " Patch : ${{ steps.selectversion.outputs.nextpatchdigit }}" + echo "Build Filename : ${{ steps.selectversion.outputs.buildversionfilename }}.bin" + echo "Build Timestamp : ${{ steps.versioninfo.outputs.buildtimestamp }}" + + - name: Save Build info + uses: "DamianReeves/write-file-action@master" + with: + path: include/Version.h + write-mode: overwrite + contents: | + // ########################################################################## + // ### This file is generated by build and Continuous Integration scripts ### + // ### .github/workflows/build.py for local development environment ### + // ### .github/workflows/build.yml for CI environment ### + // ### Changes will be overwritten on the next build! ### + // ########################################################################## + + #ifndef VERSION_H + #define VERSION_H + #define VERSION "${{ steps.selectversion.outputs.buildversion }}" + #define VERSION_MAJOR ${{ steps.selectversion.outputs.nextmajordigit }} + #define VERSION_MINOR ${{ steps.selectversion.outputs.nextminordigit }} + #define VERSION_PATCH ${{ steps.selectversion.outputs.nextpatchdigit }} + #define VERSION_BUILD "${{ steps.versioninfo.outputs.commithash }}" + #define VERSION_TIMESTAMP "${{ steps.versioninfo.outputs.buildtimestamp }}" + #endif + + - name: Verify Build info + run: | + cat include/Version.h + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install PlatformIO Core + run: pip install --upgrade platformio + + - name: Build + run: | + pio run -e wt32-eth01 + + - name: Attach Binary to Workflow run + id: attachbinarytoworkflowrun + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.selectversion.outputs.buildversionfilename }}.bin + path: .pio/build/wt32-eth01/firmware.bin + if-no-files-found: error + + - name: Release when on main branch + id: createrelease + uses: actions/create-release@v1 + if: ${{ steps.versioninfo.outputs.branchname == 'main'}} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ steps.selectversion.outputs.buildversion }} + release_name: Release ${{ steps.selectversion.outputs.buildversion }} + draft: false + prerelease: false + + - name: Attach Binary to Release + id: attachbinarytorelease + uses: actions/upload-release-asset@v1 + if: ${{ steps.versioninfo.outputs.branchname == 'main'}} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.createrelease.outputs.upload_url }} + asset_path: .pio/build/wt32-eth01/firmware.bin + asset_name: ${{ steps.selectversion.outputs.buildversionfilename }}.bin + asset_content_type: application/octet-stream \ No newline at end of file diff --git a/reference/SHIFTR-main/.gitignore b/reference/SHIFTR-main/.gitignore new file mode 100644 index 00000000..c417b1f1 --- /dev/null +++ b/reference/SHIFTR-main/.gitignore @@ -0,0 +1,4 @@ +.pio +.vscode +.DS_Store +ota.ini diff --git a/reference/SHIFTR-main/LICENSE b/reference/SHIFTR-main/LICENSE new file mode 100644 index 00000000..f288702d --- /dev/null +++ b/reference/SHIFTR-main/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/reference/SHIFTR-main/NOTICE.txt b/reference/SHIFTR-main/NOTICE.txt new file mode 100644 index 00000000..200a79a9 --- /dev/null +++ b/reference/SHIFTR-main/NOTICE.txt @@ -0,0 +1,23 @@ +SHIFTR +Copyright 2024 SHIFTR contributors + +This product includes software from the IotWebConf project (MIT License) +https://github.com/prampec/IotWebConf + +This product includes software from the NimBLE-Arduino project (Apache 2.0) +https://github.com/h2zero/NimBLE-Arduino + +This product includes software from the arduino-timer project (BSD, 3-clause) +https://github.com/contrem/arduino-timer + +This product includes software from the AsyncTCP project (LGPL-3.0 License) +https://github.com/me-no-dev/AsyncTCP + +This product includes software from the uleb128 project (MIT License) +https://github.com/bolderflight/uleb128 + +This product includes code from the shelly-homekit project (Apache 2.0) +https://github.com/mongoose-os-apps/shelly-homekit + +This product includes code from the qdomyos-zwift project (GPL-3.0 License) +https://github.com/cagnulein/qdomyos-zwift \ No newline at end of file diff --git a/reference/SHIFTR-main/README.md b/reference/SHIFTR-main/README.md new file mode 100644 index 00000000..923634ad --- /dev/null +++ b/reference/SHIFTR-main/README.md @@ -0,0 +1,104 @@ +[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) +[![CI](https://github.com/JuergenLeber/SHIFTR/actions/workflows/build.yml/badge.svg)](https://github.com/JuergenLeber/SHIFTR/actions/workflows/build.yml) +# SHIFTR +A BLE to Direct Connect bridge for bike trainers using a WT32-ETH01 module based on ESP32. Increases connection stability and additionally adding Zwift "virtual shifting" functionality to any device supporting FE-C over BLE. Also adding FTMS emulation via DirCon for non-FE-C compatible software like MyWhoosh. + +Currently tested with Garmin/Tacx NEO 2T and Vortex but should also work on other trainers supporting FE-C over BLE. + +Tested bike trainer software so far: +- ☑ Zwift (Pass-through + virtual shifting mode) +- ☑ MyWhoosh (Pass-through mode only / TACX Neo 2T and Vortex only with FTMS emulation enabled) + +Disclaimer: Even if everything is working fine this project is still work in progress. Feel free to provide feedback if you encounter any issues. + +## Overview +Bike trainers heavily evolved over the last few years. Tacx (acquired by Garmin some years ago) is one of the market leaders producing bike trainers of a very high quality with special features like e.g. "Road Feeling" to simulate different road surfaces. +Other vendors like Zwift came up with cool new features like "virtual shifting" using the "Zwift Cog" and a controller device (Zwift Click/Play) to have a non-mechanical shifting solution which is setting the gears via software that adjusts the resistance in the trainer. +Wahoo came up with a technology called "Direct Connect" that allows the trainer devices to be connected via Ethernet (or even WiFi) instead of bluetooth to have a more stable connection. + +While other vendors like e.g. Elite or JetBlack are very fast in implementing things like virtual shifting to their newer models Garmin is very slow and unresponsive when it comes to such feature requests. Probably also because they have their own ecosystem that competes with Zwift. + +Using Zwift for many years and owning a "Tacx Vortex" and a "Tacx Neo 2T" bike trainer I have been jealous of features like virtual shifting and the possibility to connect the trainer device via ethernet. So the idea for this project, SHIFTR, was born by having a device between Zwift and the Tacx supporting all this cool new functionality. + +After many days and nights of searching the internet for a specification of the protocols I was only able to find small parts for "Direct Connect" that have already been reverse engineered by Roberto Viola in his [QDomyos-Zwift](https://github.com/cagnulein/qdomyos-zwift) project. The code helped me a lot to understand the protocol. +Unfortunately there was absolutely no information about the "virtual shifting" to be found. So a very long session of decompiling Zwift apps and sniffing BLE traffic between Zwift and capable trainers (which fortunately a friend had one of) started. It took some weeks but I was able to reverse engineer the used protocols. + +As I wanted to have a convenient solution that doesn't require a special program or app to be started to have that functionality I decided to implement everything on an ESP32 microcontroller that already features WiFi and Bluetooth onboard and also optionally ethernet. The perfect module for that was the [WT32-ETH01](https://en.wireless-tag.com/product-item-2.html) module that comes with everything I needed. The device will be placed very close to the trainer in a 3D printed case that also has a place for a step down converter to be able to use the existing power supply from the trainer. + +Now I have a great setup with a Garmin/Tacx NEO 2T with a Zwift Cog installed and communicating to Zwift via ethernet while still having the "Road Feeling" feature: +![The whole setup](images/tacx_neo_2t_and_zwift_cog_and_device.jpg) + +This setup even works great with Zwift running on an Apple TV. Apple TV only supports two simultaneous bluetooth connections and those can now be used for the Zwift Play controllers while the trainer itself is being connected through ethernet. + +## How it works +The SHIFTR is working in two modes, "Pass-through" and "Pass-through + virtual shifting": +### Pass-through mode +In this mode the SHIFTR just takes all services from the BLE trainer devices and provides them 1:1 via Direct Connect. It supports SIM and ERG mode as if the device would be connected via bluetooth. +### Pass-through + virtual shifting mode +This mode provides the pass through features as mentioned before and additionally offers a special Zwift service via Direct Connect that allows it to behave like a Zwift certified device offering virtual shifting, too. All necessary information like incline, bicycle and user weight, etc. are transmitted by Zwift and used for calculations. SIM and ERG mode are supported but of course virtual shifting only works in SIM mode. + +Details about the virtual shifting function and calculations can be found [here](./VirtualShifting.md). + +***Note***: Virtual shifting will be disabled if neither Zwift Play controllers nor a Zwift Click are connected which results in the standard SIM mode with a track resistance of 0%. Then you'd have to shift with your bike but with a Zwift Cog installed this doesn't make sense of course. If the controllers disconnect during a training then the fallback will be this normal SIM mode but as soon as the controller(s) are re-connected the virtual shifting will be enabled again. + +### Pass-through + FTMS emulation +This mode provides all services from the BLE trainer and additionally offers a FTMS emulation that internally sends the commands to the BLE FE-C trainer. This makes software like MyWhoosh also working. Doesn't (at least not yet) work with virtual shifting as this is a Zwift-only feature at the moment. + +## Needed hardware +- WT32-ETH01 ESP32 board (e.g. from [Amazon](https://www.amazon.de/WT32-ETH01-Embedded-Schnittstelle-Bluetooth-Entwicklungsplatine/dp/B0CW3DDWZ4)) +- Step-Down converter 5-80V (the Tacx Neo supplies 48V) to 5V (e.g. from [Amazon](https://www.amazon.de/dp/B0CMC7Y3DJ)) +- Y-Splitter for the Tacx power cable (e.g. from [Amazon](https://www.amazon.de/dp/B09FHHN9T5)) +- Power connector for the case (e.g. from [Amazon](https://www.amazon.de/gp/product/B09PD6J4BN)) +- 3D printed case that fits the WT32-ETH01. Luckily I was able to find a perfect match that also fits the step-down converter: [WT32-ETH01 Enclosure](https://www.thingiverse.com/thing:5621092) +- Two countersunk screws M2x7 to hold the lid on the case + + +## Hardware installation +- ***IMPORTANT***: Don't solder the pin headers that came with the WT32-ETH01. With the longer pins on the bottom side the module won't fit the case anymore. +- ***IMPORTANT #2***: Connect the step-down converter first to a power supply (e.g. the original one with 48V) and a multimeter and use a screwdriver to adjust the output voltage to 5V before connecting it to the WT32-ETH01 module! +- Use a standard USB<->TTL converter (e.g. with FTDI232 or similar). Make sure that it can provide **3,3V and not 5V** and connect as follows (see also pinout above): + | Converter | -> | ETH01-EVO | + |-|-|-| + | RX | -> | TXD | + | TX | -> | RXD | + | 3V3 | -> | 3V3 | + | GND | -> | GND | + + It's best to use some breadboard jumper wires that can just be connected without soldering. Use a rubber band to hold them in contact. + + To start the WT32-ETH01 in boot mode it is necessary to connect "IO0" with GND and then to reset the board, shortly connect "EN" to GND for a quarter of a second. + +## Software installation +- Open the project in [PlatformIO](https://platformio.org) and let it install the dependencies +- Connect the programmer and upload via the task wt32-eth01 -> Upload and Monitor +- Connect an ethernet cable and make sure a DHCP server exists in your network +- After a few seconds you should be able to see the IP address and the hostname (like e.g. "SHIFTR-123456.local") in the monitor log +- If you don't use the Ethernet interface you can also use the WiFi functionality. For that the device opens an AP with the device name (e.g. "SHIFTR-123456") and the password is the same but of course can be changed later. Please note that WiFi is provided by an external library called [IoTWebConf](https://github.com/prampec/IotWebConf) and is more or less untested +- After that you can configure the device and its network settings in the web interface on e.g. http://SHIFTR-123456.local +- The status page is accessible without credentials, the settings and firmware update pages need the username "admin" and the password is the configured AP password or just the device name (e.g. "SHIFTR-123456") as default. Note that both are case sensitive! +- Further updates can be made over ethernet or WiFi so you can disconnect the programming adapter now + +## Finalization +- Finally you can solder some wires to the power connector to the step down module and from there to the WT32-ETH01. Then mount everything in the 3D printed case: + + ![Mounted adapter](images/wt32-eth01_case.jpg) + +- Use the Y-Power-Splitter to connect the Tacx trainer and the device: + + ![Connected to Tacx](images/connected_to_tacx_neo_2t.jpg) + +- Power the Trainer and go to the web interface +- Go to "Settings", select the trainer device and "Save" +- Make sure the "Virtual shifting" option is enabled if you want to use it. Virtual shifting only works in Zwift when a Zwift Click or Zwift Play controllers are connected. Otherwise it will fall back to the normal ERG and SIM modes +- In Zwift you need to connect to the "SHIFTR 123456" device instead of your old device now. Have fun! + +## Thank you! +You've made it to the end, hopefully you'll have fun rebuilding the whole thing. Please tell me if you like it and if it works as expected. +In case of any questions feel free to contact me! + +## Disclaimer +Please always check the documentation of the hardware you bought as there are sometimes small changes in pin assignments, voltage and so on. I don't take any liability for damages or injuries. Build this project at your own risk. The linked products and pages are for reference only. I don't get any money from the manufacturers or the (re)sellers. + + + + diff --git a/reference/SHIFTR-main/VirtualShifting.md b/reference/SHIFTR-main/VirtualShifting.md new file mode 100644 index 00000000..42b704d7 --- /dev/null +++ b/reference/SHIFTR-main/VirtualShifting.md @@ -0,0 +1,95 @@ +# Virtual shifting +This section describes how the virtual shifting inside SHIFTR works as it isn't natively supported by the trainers (e.g. TACX Neo 2T). + +***PARTLY OUTDATED***: As there have been many changes in the recent version this description isn't completely correct anymore and needs to be updated. + +## How it works +The virtual gears are defined inside Zwift and don't need a special handling in SHIFTR. Zwift just sends the corresponding gear ratio (chainring:sprocket) between 0.75 and 5.49 on every shift. + +Currently these are: 0.75 0.87 0.99 1.11 1.23 1.38 1.53 1.68 1.86 2.04 2.22 2.40 2.61 2.82 3.03 3.24 3.49 3.74 3.99 4.24 4.54 4.84 5.14 5.49 + +As the Zwift Cog has 14 teeth and a standard chainring 34 teeth the default ratio in SHIFTR is defined at 2.4286 which roughly matches Zwift Gear 12. This ratio is the base for all further gear calculations. Of course the chainring and sprocket teeth can be set in the device configuration and these values will then be used for the default ratio. + +Based on this ratio and the selected ratio from Zwift (e.g. 1.23 ~ "Gear 5") the ratio that will later be applied to the trainer's force will be calculated: + +$R_{relative} = R_{selected} / R_{standard}$ + +Example: + +$R_{relative} = 1.23 / 2.4286 = 0.51$ (rounded) + +To set the correct resistance of the trainer, the gravitational, the rolling and the drag force are calculated using formulas. There are currently three methods of applying the virtual gears implemented: "***Basic Resistance***", "***Target Power***" and "***Track Resistance***". The feeling may vary from trainer to trainer but whatever mode is being used the reported watts and cadence are never modified and so the measured power in Zwift will always be as correct as before. + +The different modes can be set in the device configuration - the default is "Basic Resistance". + +Getting back to the calculations: The combined weight of you (the cyclist) and your bike is $W$ ($kg$). The gravitational force constant $g$ is 9.8067 ($m/s^2$). There is a dimensionless parameter, called the "Coefficient of Rolling Resistance", or $C_{rr}$, that captures the bumpiness of the road and the quality of your tires. There are some defaults specified in the FE-C docs: + +| Terrain | Coefficient of Rolling Resistance | + |-|-:| + | Wooden Track | 0.001 | + | Smooth Concrete | 0.002 | + | Asphalt Road | 0.004 | + | Rough Road | 0.008 | + +This parameter is set by Zwift in normal SIM mode as `0x53`(= 83 dec) and equals (as the unit is $5·10^{-5}$) a value of 0.00415 which is kind of an "Asphalt Road" and also the default mentioned in the FE-C docs. The steepness of a hill will be provided by Zwift in terms of percentage grade $G$. + +Regarding the aerodynamic drag the head/tailwind $V_{hw} (m/s)$ isn't taken into account from Zwift and is assumed 0. But the faster your groundspeed $V_{gs} (m/s)$ is, the more force the air pushes against you. Your airspeed $V_{as} (m/s)$ is the speed that the wind strikes your face, and it is the sum of your groundspeed $V_{gs}$ and the headwind speed $V_{hw}$. As well, you and your bike present a certain frontal area $A (m^2)$ to the air. The larger this frontal area, the more air you have to displace, and the larger the force the air pushes against you. The air density $Rho (kg/m^3)$ is also important. The more dense the air, the more force it exerts on you. Then there is another dimensionless parameter, called the "Drag Coefficient", or $C_{d}$, that captures other effects, like the slipperiness of your clothing and the degree to which air flows laminarly rather than turbulently around you and your bike. Having all the values we can calculate as follows: + +### Calculate total geared force + +$F_{gravity} = g · \sin(\arctan(\frac{G}{100})) · W$ + +$F_{rolling} = g · W · C_{rr}$ + +As we are calculating with no head/tailwind, our $V_{as}$ equals our $V_{gs}$ as we assume $V_{hw} = 0$ and the calculation would be: + +$V_{as} = V_{gs} + V_{hw}$ + +$F_{drag} = 0.5 · C_d · A · Rho · V_{as}^2$ + +The FE-C documentation uses a more simple approach by using a bundled coefficient $C_{wr} (kg/m)$ as the "Wind Resistance Coefficient" there: + +$C_{wr} = A · C_d · Rho$ + +| Bicycle and Rider | Frontal Area ($m^2$) | Drag Coefficient | + |-|-:|-:| + | All-terrain (Mountain) Bike | 0.57 | 1.20 | + | Upright Commuting Bike | 0.55 | 1.15 | + | Road Bike, Touring Position | 0.40 | 1.0 | + | Racing Bike, Rider Crouched, Tight Clothing | 0.36 | 0.88 | + +As a unit this coefficient uses 0.01 kg/m and the default value of the trainer is `0x33` (=51 dec) which equals 0.51 kg/m while using the standard density of air, 1.275kg/m3 (15°C at sea level) and the "Road Bike" parameters for frontal area and drag coefficient as the default. + +$F_{drag} = 0.5 · C_{wr} · V_{as}^2$ + +The total force is the sum of these three forces: + +$F_{total} = F_{gravity} + F_{rolling} + F_{drag}$ + +In case of $F_{total} >= 0$ the relative gear ratio mentioned above will be applied by multiplication: + +$F_{totalGeared} = F_{total} · R_{relative}$ + +Otherwise in case of $F_{total} < 0$ the reciprocal of the relative gear ratio will be applied by multiplication: + +$F_{totalGeared} = F_{total} · \frac{1}{R_{relative}}$ + +In the "Basic resistance" mode the resulting force will then be used to set the trainer's resistance. Depending on the model there is a maximum force the trainer can apply. For a Tacx Vortex this is 50N and for a Tacx Neo 2T this is 200N. On every connection the maximum force is read out of the trainer. The basic resistance can only be set in 0.5% (0-200) and not in N as expected. So before applying the resistance it will be mapped to the correct 0.5% value. + +In the "Track Resistance" mode we can only set a grade/slope on the trainer. The resulting "geared" force is being used to calculate backwards to get a correct percentage of the desired grade/slope with the gear ratio calculated in. This is done by first calculating the force as above but then subtracting the rolling and drag force to only have the gravity force with its gearing factor left. From there we are calculating the grade, that would need to be set to achieve the force we calculated before: + +$F_{gravity} = F_{totalGeared} - F_{rolling} - F_{drag}$ + +$G = \tan(\arcsin(F_{gravity} / W / g)) · 100$ + +This new grade value is then sent to the trainer in the track resistance mode and so will also support the powered decline feature to provide a better feeling especially when riding downhill. + +The "Target Power" mode uses a different approach. Here we want to set an expected watts value depending on the current track and speed. To calculate the speed we assume a default wheel diameter $d$ of 0.7m and take the current cadence $c$ from the trainer that is being multiplied with the wanted gear ratio. The product is then being multiplied with the calculated perimeter of the wheel: + +$V_{gs} = (c · R_{selected}) · (d · \pi)$ + +This speed is then taken to calculate the geared total force [as described above](#calculate-total-geared-force) which is then being used to calculate the needed power $P$: + +$P = F_{totalGeared} · V_{gs}$ + +This value is then being sent to the trainer in the target power mode as in ERG mode but of course is updated on every parameter change. diff --git a/reference/SHIFTR-main/docs/Assigned_Numbers.pdf b/reference/SHIFTR-main/docs/Assigned_Numbers.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fce19284502000e67a4b6d370230c4dacea6c293 GIT binary patch literal 1253127 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

2)Ep+tDUwvrzAXeYWAB1ETEk=DW^$u&6K0~i= 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

n$|rPmr?;SYISX5Q?mP@kC1kQC;@ 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

qG3DM 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%0D!`|8 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 uNuPM_2$3bmIvDAroaH!`=Ve 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 ZWki^+a?=>eAi&EV&>?4$eyI+~zCmLhikmi$Ju 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 }^HHH7EY`&TT1- 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

MQ!jP8@?R1Za(?0)7npAnsyuV`dnmpz;nw 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

)>hRn&va>;^OEBFj%Om4_`MVl+cIv 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

oJgw&|e>m=`yEJm`txFlZZ5$@c%FJDdPoR7ef>f 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

gpw;TGsk&GX87ySEO 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

U2?P` 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�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

^xs!}$t1 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

XgYd82dFF2nEwQhCC_=a)q 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

6AP?p+K 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 UoE~^zUS1vqq8Ag>F@8+{UqSK@nE(I) literal 0 HcmV?d00001 diff --git a/reference/SHIFTR-main/docs/D000001231_-_ANT+_Device_Profile_-_Fitness_Equipment_-_Rev_5.txt b/reference/SHIFTR-main/docs/D000001231_-_ANT+_Device_Profile_-_Fitness_Equipment_-_Rev_5.txt new file mode 100644 index 00000000..82e0420d --- /dev/null +++ b/reference/SHIFTR-main/docs/D000001231_-_ANT+_Device_Profile_-_Fitness_Equipment_-_Rev_5.txt @@ -0,0 +1,3 @@ +This file is only available after registration on https://www.thisisant.com + +Link: https://www.thisisant.com/resources/fitness-equipment-device/ diff --git a/reference/SHIFTR-main/docs/D00000652_ANT_Message_Protocol_and_Usage_Rev_5.1.txt b/reference/SHIFTR-main/docs/D00000652_ANT_Message_Protocol_and_Usage_Rev_5.1.txt new file mode 100644 index 00000000..3f494dfb --- /dev/null +++ b/reference/SHIFTR-main/docs/D00000652_ANT_Message_Protocol_and_Usage_Rev_5.1.txt @@ -0,0 +1,3 @@ +This file is only available after registration on https://www.thisisant.com + +Link: https://www.thisisant.com/resources/ant-message-protocol-and-usage/ diff --git a/reference/SHIFTR-main/docs/FTMS_v1.0.pdf b/reference/SHIFTR-main/docs/FTMS_v1.0.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2f352f9199fd5460037a5e460596f995eb02822d GIT binary patch literal 1351293 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

\n"; + + // Add Chart.js library + htmlFile << "\n"; + + // Add canvas for the chart with increased height + htmlFile << "
\n"; + htmlFile << " \n"; + htmlFile << "
\n"; + + // Add Y-axis range control HTML *before* the script that uses it + htmlFile << "
\n"; + htmlFile << " \n"; + htmlFile << " \n"; + htmlFile << "
\n"; + + // Start script for chart and slider logic + htmlFile << "\n"; + + // Add Y-axis range control + htmlFile << "
\n"; + htmlFile << " \n"; + htmlFile << " \n"; + htmlFile << "
\n"; + // HTML footer htmlFile << "\n\n"; diff --git a/test/test_table_fill.cpp b/test/test_table_fill.cpp index 5cd7f8b9..ab9c21ad 100644 --- a/test/test_table_fill.cpp +++ b/test/test_table_fill.cpp @@ -23,7 +23,7 @@ void TestTableFill::test_fill_incomplete_table(void) { PTData ptData; // Load the incomplete power table data - const std::string inputFilePath = "test/data/final_5_25_25.ptab"; + const std::string inputFilePath = "test/data/10x5-26-25.ptab"; loadCSVToPTData(inputFilePath, ptData); logFile << "Loaded incomplete power table from: " << inputFilePath << "\n"; From f7f9c05cb90bd71ad1ae6ff3d5a6c1387accec4c Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 27 May 2025 09:45:10 -0500 Subject: [PATCH 231/451] start at middle and alternate out to fill table. --- src/PowerTable_Helpers.cpp | 125 ++++++++++++++++++++++++++++--------- test/data/10x5-26-25.ptab | 18 +++--- 2 files changed, 104 insertions(+), 39 deletions(-) diff --git a/src/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp index 766d9f4e..eaabbb4e 100644 --- a/src/PowerTable_Helpers.cpp +++ b/src/PowerTable_Helpers.cpp @@ -399,25 +399,44 @@ void PTHelpers::extrapFillTableDirection(bool horizontal, PTData& ptData, bool f std::vector x, y; int rangeStart, rangeEnd; + // Determine the range for inner loop based on firstHalf or secondHalf + // This logic for 'rangeStart' and 'rangeEnd' applies to the 'innerIndex' loop if (firstHalf) { rangeStart = 0; - rangeEnd = (innerSize / 2) + (innerSize / 2 - innerSize / 3); + // Ensure overlap: process a bit more than half, e.g., 2/3 or 3/4 + // The amount of overlap might need tuning. Let's try 2/3 for now. + rangeEnd = (innerSize * 2) / 3; + if (rangeEnd > innerSize) rangeEnd = innerSize; // cap at innerSize } else { - rangeStart = (innerSize / 2) - (innerSize / 2 - innerSize / 3); + // Start from a point that ensures overlap with the first half + rangeStart = innerSize / 3; rangeEnd = innerSize; } - for (int outerIndex = 0; outerIndex < outerSize; ++outerIndex) { + + int mid_outer = outerSize / 2; + int max_k_outer = 0; + if (outerSize > 0) { + max_k_outer = std::max(mid_outer, (outerSize - 1) - mid_outer); + } + + auto processOuterIndex = + [&](int currentOuterIndex) { unique_xy.clear(); emptyIndices.clear(); x.clear(); y.clear(); ptIndex index; - // Collect data points + // Collect data points for the currentOuterIndex across the specified inner range for (int innerIndex = rangeStart; innerIndex < rangeEnd; ++innerIndex) { - index.cadIndex = horizontal ? outerIndex : innerIndex; - index.wattIndex = horizontal ? innerIndex : outerIndex; + index.cadIndex = horizontal ? currentOuterIndex : innerIndex; + index.wattIndex = horizontal ? innerIndex : currentOuterIndex; + + // Boundary checks for safety, though currentOuterIndex should be valid by loop logic + if (index.cadIndex < 0 || index.cadIndex >= POWERTABLE_CAD_SIZE || index.wattIndex < 0 || index.wattIndex >= POWERTABLE_WATT_SIZE) { + continue; + } if (ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition != INT16_MIN) { unique_xy.emplace_back(innerIndex, static_cast(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition)); @@ -426,7 +445,7 @@ void PTHelpers::extrapFillTableDirection(bool horizontal, PTData& ptData, bool f } } - if (unique_xy.size() < 2) continue; // Skip if not enough data + if (unique_xy.size() < 2) return; // Skip if not enough data std::sort(unique_xy.begin(), unique_xy.end()); @@ -436,10 +455,26 @@ void PTHelpers::extrapFillTableDirection(bool horizontal, PTData& ptData, bool f } CubicSpline spline; + // The decision to use natural spline might be based on the characteristics of x, y + // For now, let's assume shouldUseNaturalSpline is available and correctly implemented bool useNaturalSpline = spline.shouldUseNaturalSpline(std::make_pair(x, y), x.size()); // Fill empty table entries using the determined spline type - extrapolateEmptyIndices(outerIndex, emptyIndices, std::make_pair(x, y), x.size(), horizontal, useNaturalSpline, ptData); + extrapolateEmptyIndices(currentOuterIndex, emptyIndices, std::make_pair(x, y), x.size(), horizontal, useNaturalSpline, ptData); + }; + + for (int k = 0; k <= max_k_outer; ++k) { + int outer_upper = mid_outer + k; + if (outer_upper < outerSize) { + processOuterIndex(outer_upper); + } + + if (k > 0) { + int outer_lower = mid_outer - k; + if (outer_lower >= 0) { + processOuterIndex(outer_lower); + } + } } } @@ -484,30 +519,60 @@ void PTHelpers::splineFill(PTData& ptData, bool firstHalf) { extrapFillTableDirection(true, ptData, false); // Fill remaining empty entries in horizontal direction } +/** + * @brief Fills empty entries in the power table using linear interpolation. + * + * This function iterates through the table rows, starting from the middle row and expanding outward, + * and fills empty cells (where targetPosition == INT16_MIN) by estimating resistance using the lookup method. + * Only fills a cell if all its neighbors pass validation. + * + * @param ptData Reference to the PTData object containing the power table. + */ void PTHelpers::linearFill(PTData& ptData) { - for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - if (ptData.tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { - // lookup resistance for this position using watts and cadence - int watts = j * POWERTABLE_WATT_INCREMENT; - int cad = i * POWERTABLE_CAD_INCREMENT + MINIMUM_TABLE_CAD; - int resistance = lookup(watts, cad, ptData); - if (resistance == RETURN_ERROR) { - SS2K_LOG(PTDATA_LOG_TAG, "Failed to lookup resistance for watts: %d, cadence: %d", watts, cad); - continue; // Skip if lookup failed - } else { - resistance = resistance / TABLE_DIVISOR; + int mid = POWERTABLE_CAD_SIZE / 2; + int max_k = (POWERTABLE_CAD_SIZE - 1) - mid; + + // Define a lambda for processing a single cell + auto processCell = [this, &ptData](int currentRowIndex, int currentColIndex) { + if (ptData.tableRow[currentRowIndex].tableEntry[currentColIndex].targetPosition == INT16_MIN) { + int watts = currentColIndex * POWERTABLE_WATT_INCREMENT; + int cad = currentRowIndex * POWERTABLE_CAD_INCREMENT + MINIMUM_TABLE_CAD; + int resistance = this->lookup(watts, cad, ptData); + if (resistance == RETURN_ERROR) { + SS2K_LOG(PTDATA_LOG_TAG, "Failed to lookup resistance for watts: %d, cadence: %d", watts, cad); + return; // Skip this cell processing + } else { + resistance = resistance / TABLE_DIVISOR; + } + ptIndex current_pt_idx; + current_pt_idx.wattIndex = currentColIndex; + current_pt_idx.cadIndex = currentRowIndex; + TestResults results = this->testNeighbors(current_pt_idx, resistance, ptData); + if (results.allNeighborsPassed == 1) { + ptData.tableRow[currentRowIndex].tableEntry[currentColIndex].targetPosition = resistance; + //SS2K_LOG(PTDATA_LOG_TAG, "Filled position (%d, %d) with resistance: %d", currentRowIndex, currentColIndex, resistance); + } else { // log the failure to in insert the value + // Serial.printf("Failed to fill position (%d, %d) with resistance: %d\n", currentRowIndex, currentColIndex, resistance); + } + } + }; + + for (int k = 0; k <= max_k; ++k) { + // Process row from mid upwards: mid, mid+1, mid+2, ... + int i_upper = mid + k; + if (i_upper < POWERTABLE_CAD_SIZE) { // Ensure i_upper is a valid row index + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + processCell(i_upper, j); + } + } + + // Process row from mid downwards: mid-1, mid-2, ..., only if k > 0 to avoid re-processing 'mid' + if (k > 0) { + int i_lower = mid - k; + if (i_lower >= 0) { // Ensure i_lower is a valid row index + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + processCell(i_lower, j); } - ptIndex index; - index.wattIndex = j; - index.cadIndex = i; - TestResults results = testNeighbors(index, resistance, ptData); - if (results.allNeighborsPassed == 1) { - ptData.tableRow[i].tableEntry[j].targetPosition = resistance; - //SS2K_LOG(PTDATA_LOG_TAG, "Filled position (%d, %d) with resistance: %d", i, j, resistance); - } else { // log the failure to in insert the value - // Serial.printf("Failed to fill position (%d, %d) with resistance: %d\n", i, j, resistance); - } // log failed neighbor resistance values } } } diff --git a/test/data/10x5-26-25.ptab b/test/data/10x5-26-25.ptab index a92ff794..40648005 100644 --- a/test/data/10x5-26-25.ptab +++ b/test/data/10x5-26-25.ptab @@ -1,11 +1,11 @@ Cadence/Power,0W,30W,60W,90W,120W,150W,180W,210W,240W,270W,300W,330W,360W,390W,420W,450W,480W,510W,540W,570W,600W,630W,660W,690W,720W,750W,780W,810W,840W,870W,900W,930W,960W,990W,1020W,1050W,1080W,1110W -60RPM,,,,,,,,,,,1755,1938,2121,2304,2487,2670,2853,3036,3219,3402,3585,3768,3951,4134,4317,4500,4683,4866,5049,5232 -65RPM,1625,1648,,,,,,,1665,1716,,1845,1903,1926,1950,1973,2069,2097,2102,2106,2108,2112,2135,2158,2181,2204,2227,2250,2273,2296 -70RPM,1198,1225,,,1241,1334,1361,1388,1518,1665,1670,1673,1678,1702,1707,1711,1712,1713,,1714,,,,,,,,,1958,1985 -75RPM,268,,,1090,,,1350,,1448,,1625,,,,,,,,,1641,,,,,,2075,2147,2219,, -80RPM,135,,854,,1120,1184,1316,1373,1421,1443,1538,1604,1642,,,,,,,,1994,2018,2030,2036,2038,2039,2040,2113,, -85RPM,,794,841,888,,,1250,1327,1382,,1497,1512,1521,1535,1564,1571,1576,1577,,1638,,1971,2004,2010,2015,2016,2017,2018,, -90RPM,,,,,1134,1170,1178,1300,1324,1380,1418,1451,,,,1527,1562,,1809,,1836,1844,1846,1847,1848,1884,1920,1956,, -95RPM,,,,,1127,1151,1148,1227,1317,1367,1394,1408,1474,1489,1500,1504,1506,1510,1513,1514,1515,1539,1563,1587,1611,1635,1659,1683,1707,1731 -100RPM,,,,,1105,,1125,1191,1276,1334,1370,1406,1421,1428,1431,1433,1433,1434,1435,1436,1458,1480,1502,1524,1546,1568,1590,1612,1634,1656 +60RPM,,,,,,,,,,,1755,1938,,,,,,,,,,,,,,,,,, +65RPM,,,,,,,,,,,1665,1716,,1845,1903,1926,1950,1973,2069,2097,2102,2106,,,,,,, +70RPM,1198,,,,1241,1334,1361,1388,1518,1665,1670,1673,1678,1702,1707,1711,,,,, +75RPM,268,,,,,,1350,,1448,,1625,,,,,,,,,1641,,,,,,2075,2147,2219,, +80RPM,135,,854,,1120,1184,1316,1373,1421,1443,1538,1604,1642,,,,,,,,1994,2018,,,,, +85RPM,,794,841,888,,,1250,1327,1382,,1497,1512,1521,1535,1564,1571,1576,1577,,1638,,,,,, +90RPM,,,,,1134,1170,1178,1300,1324,1380,1418,1451,,,,1527,1562,,1809,,1836,1844,1846,1847,,,,, +95RPM,,,,,1127,1151,1148,1227,1317,1367,1394,1408,1474,1489,1500,1504,1506,1510,1513,1514,1515,,,,, +100RPM,,,,,1105,,1125,1191,1276,1334,1370,1406,1421,1428,1431,1433,1433,1434,1435,1436,1458,1480,,,,, 105RPM,,,,,1085,1109,1122,1156,1260,1315,1341,1387,1400,1408,1411,1413,1416,1417,1418,,,,,,,,,,, From bcd2368a38ce169c3a456e46f0040ca81f4f7efa Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 27 May 2025 09:47:22 -0500 Subject: [PATCH 232/451] fixed Y-Axis Slider --- test/data_helpers.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/data_helpers.cpp b/test/data_helpers.cpp index 3508d7dc..ac013153 100644 --- a/test/data_helpers.cpp +++ b/test/data_helpers.cpp @@ -274,12 +274,6 @@ static void createPowerTableHeatmap(const std::string& inputFilePath, const std: htmlFile << " yAxisRange.addEventListener('input', updateYAxisRange);\n"; htmlFile << "\n"; - // Add Y-axis range control - htmlFile << "
\n"; - htmlFile << " \n"; - htmlFile << " \n"; - htmlFile << "
\n"; - // HTML footer htmlFile << "\n\n"; From a71ccb4883a3523683d3544df1072c3a39af1f51 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 27 May 2025 11:47:00 -0500 Subject: [PATCH 233/451] fixed BLE with Zwift (BLE values were not being set, only Notified) --- src/BLE_Cycling_Power_Service.cpp | 28 ++++++++++++---------------- src/BLE_Cycling_Speed_Cadence.cpp | 15 +++++++++------ src/BLE_Fitness_Machine_Service.cpp | 8 +++++--- src/BLE_Heart_Service.cpp | 9 ++++++--- src/BLE_SB20_Service.cpp | 9 ++++++--- src/BLE_Wattbike_Service.cpp | 15 ++++++++------- 6 files changed, 46 insertions(+), 38 deletions(-) diff --git a/src/BLE_Cycling_Power_Service.cpp b/src/BLE_Cycling_Power_Service.cpp index a80bf177..1dfcae35 100644 --- a/src/BLE_Cycling_Power_Service.cpp +++ b/src/BLE_Cycling_Power_Service.cpp @@ -8,17 +8,16 @@ #include "DirConManager.h" #include -BLE_Cycling_Power_Service::BLE_Cycling_Power_Service() : pPowerMonitor(nullptr), cyclingPowerFeatureCharacteristic(nullptr), sensorLocationCharacteristic(nullptr){} +BLE_Cycling_Power_Service::BLE_Cycling_Power_Service() : pPowerMonitor(nullptr), cyclingPowerFeatureCharacteristic(nullptr), sensorLocationCharacteristic(nullptr) {} void BLE_Cycling_Power_Service::setupService(NimBLEServer *pServer, MyCharacteristicCallbacks *chrCallbacks) { // Power Meter service setup pPowerMonitor = spinBLEServer.pServer->createService(CYCLINGPOWERSERVICE_UUID); cyclingPowerMeasurementCharacteristic = pPowerMonitor->createCharacteristic(CYCLINGPOWERMEASUREMENT_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); cyclingPowerFeatureCharacteristic = pPowerMonitor->createCharacteristic(CYCLINGPOWERFEATURE_UUID, NIMBLE_PROPERTY::READ); sensorLocationCharacteristic = pPowerMonitor->createCharacteristic(SENSORLOCATION_UUID, NIMBLE_PROPERTY::READ); - byte cpsLocation[1] = {0b0101}; // sensor location 5 == left crank + byte cpsLocation[1] = {0b0101}; // sensor location 5 == left crank - CyclingPowerFeatureFlags::Types cpFeatureFlags = CyclingPowerFeatureFlags::WheelRevolutionDataSupported | - CyclingPowerFeatureFlags::CrankRevolutionDataSupported; + CyclingPowerFeatureFlags::Types cpFeatureFlags = CyclingPowerFeatureFlags::WheelRevolutionDataSupported | CyclingPowerFeatureFlags::CrankRevolutionDataSupported; cpFeature[0] = static_cast(cpFeatureFlags & 0xFF); cpFeature[1] = static_cast((cpFeatureFlags >> 8) & 0xFF); @@ -29,14 +28,13 @@ void BLE_Cycling_Power_Service::setupService(NimBLEServer *pServer, MyCharacteri sensorLocationCharacteristic->setValue(cpsLocation, sizeof(cpsLocation)); cyclingPowerMeasurementCharacteristic->setCallbacks(chrCallbacks); pPowerMonitor->start(); - //spinBLEServer.pServer->getAdvertising()->addServiceUUID(pPowerMonitor->getUUID()); - + // spinBLEServer.pServer->getAdvertising()->addServiceUUID(pPowerMonitor->getUUID()); + // Add service UUID to DirCon MDNS DirConManager::addBleServiceUuid(pPowerMonitor->getUUID()); } void BLE_Cycling_Power_Service::update() { - int power = rtConfig->watts.getValue(); float cadence = rtConfig->cad.getValue(); @@ -58,20 +56,18 @@ void BLE_Cycling_Power_Service::update() { auto byteArray = cpm.toByteArray(); - cyclingPowerMeasurementCharacteristic->notify(&byteArray[0], byteArray.size()); - + // Notify the cycling power measurement characteristic + // Need to set the value before notifying so that read works correctly. + cyclingPowerMeasurementCharacteristic->setValue(&byteArray[0], byteArray.size()); + cyclingPowerMeasurementCharacteristic->notify(); + // Also notify DirCon TCP clients - DirConManager::notifyCharacteristic( - NimBLEUUID(CYCLINGPOWERSERVICE_UUID), - cyclingPowerMeasurementCharacteristic->getUUID(), - &byteArray[0], - byteArray.size() - ); + DirConManager::notifyCharacteristic(NimBLEUUID(CYCLINGPOWERSERVICE_UUID), cyclingPowerMeasurementCharacteristic->getUUID(), &byteArray[0], byteArray.size()); const int kLogBufCapacity = 150; char logBuf[kLogBufCapacity]; const size_t byteArrayLength = byteArray.size(); logCharacteristic(logBuf, kLogBufCapacity, &byteArray[0], byteArrayLength, CYCLINGPOWERSERVICE_UUID, cyclingPowerMeasurementCharacteristic->getUUID(), - "CPS(CPM)[ CD(%.2f) PW(%d) ]", cadence > 0 ? fmodf(cadence, 1000.0) : 0, power % 10000); + "CPS(CPM)[ CD(%.2f) PW(%d) ]", cadence > 0 ? fmodf(cadence, 1000.0) : 0, power % 10000); } diff --git a/src/BLE_Cycling_Speed_Cadence.cpp b/src/BLE_Cycling_Speed_Cadence.cpp index 7b304ea8..90e40369 100644 --- a/src/BLE_Cycling_Speed_Cadence.cpp +++ b/src/BLE_Cycling_Speed_Cadence.cpp @@ -14,9 +14,9 @@ void BLE_Cycling_Speed_Cadence::setupService(NimBLEServer *pServer, MyCharacteri pCyclingSpeedCadenceService = pServer->createService(CSCSERVICE_UUID); cscMeasurement = pCyclingSpeedCadenceService->createCharacteristic(CSCMEASUREMENT_UUID, NIMBLE_PROPERTY::NOTIFY); cscFeature = pCyclingSpeedCadenceService->createCharacteristic(CSCFEATURE_UUID, NIMBLE_PROPERTY::READ); - - CyclingSpeedCadenceFeatureFlags::Types cscFeatureFlags = CyclingSpeedCadenceFeatureFlags::WheelRevolutionDataSupported | - CyclingSpeedCadenceFeatureFlags::CrankRevolutionDataSupported; + + CyclingSpeedCadenceFeatureFlags::Types cscFeatureFlags = + CyclingSpeedCadenceFeatureFlags::WheelRevolutionDataSupported | CyclingSpeedCadenceFeatureFlags::CrankRevolutionDataSupported; cscFeatureBytes[0] = static_cast(cscFeatureFlags & 0xFF); cscFeatureBytes[1] = static_cast((cscFeatureFlags >> 8) & 0xFF); @@ -24,8 +24,8 @@ void BLE_Cycling_Speed_Cadence::setupService(NimBLEServer *pServer, MyCharacteri cscFeature->setValue(cscFeatureBytes, sizeof(cscFeatureBytes)); cscMeasurement->setCallbacks(chrCallbacks); pCyclingSpeedCadenceService->start(); - //spinBLEServer.pServer->getAdvertising()->addServiceUUID(pCyclingSpeedCadenceService->getUUID()); - + // spinBLEServer.pServer->getAdvertising()->addServiceUUID(pCyclingSpeedCadenceService->getUUID()); + // Add service UUID to DirCon MDNS DirConManager::addBleServiceUuid(pCyclingSpeedCadenceService->getUUID()); } @@ -52,7 +52,10 @@ void BLE_Cycling_Speed_Cadence::update() { auto byteArray = csc.toByteArray(); - cscMeasurement->notify(&byteArray[0], byteArray.size()); + // Notify the cycling power measurement characteristic + // Need to set the value before notifying so that read works correctly. + cscMeasurement->setValue(&byteArray[0], byteArray.size()); + cscMeasurement->notify(); const int kLogBufCapacity = 150; char logBuf[kLogBufCapacity]; diff --git a/src/BLE_Fitness_Machine_Service.cpp b/src/BLE_Fitness_Machine_Service.cpp index 8dd1f001..9ff33cd7 100644 --- a/src/BLE_Fitness_Machine_Service.cpp +++ b/src/BLE_Fitness_Machine_Service.cpp @@ -108,8 +108,10 @@ void BLE_Fitness_Machine_Service::update() { ftmsIndoorBikeData.push_back(static_cast(rtConfig->hr.getValue())); } - fitnessMachineIndoorBikeData->notify(ftmsIndoorBikeData.data(), ftmsIndoorBikeData.size()); - + // Notify the cycling power measurement characteristic + // Need to set the value before notifying so that read works correctly. + fitnessMachineIndoorBikeData->setValue(ftmsIndoorBikeData.data(), ftmsIndoorBikeData.size()); + fitnessMachineIndoorBikeData->notify(); // Also notify DirCon TCP clients about Indoor Bike Data DirConManager::notifyCharacteristic(NimBLEUUID(FITNESSMACHINESERVICE_UUID), fitnessMachineIndoorBikeData->getUUID(), ftmsIndoorBikeData.data(), ftmsIndoorBikeData.size()); @@ -286,7 +288,7 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { ftmsStatus = {FitnessMachineStatus::StartedOrResumedByUser}; ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x00; } - //not checking for subscription because a write request would have triggererd this + // not checking for subscription because a write request would have triggererd this fitnessMachineControlPoint->indicate(returnValue.data(), returnValue.size()); fitnessMachineTrainingStatus->notify(ftmsTrainingStatus.data(), ftmsTrainingStatus.size()); fitnessMachineStatusCharacteristic->notify(ftmsStatus.data(), ftmsStatus.size()); diff --git a/src/BLE_Heart_Service.cpp b/src/BLE_Heart_Service.cpp index 75da4271..6e7a20c5 100644 --- a/src/BLE_Heart_Service.cpp +++ b/src/BLE_Heart_Service.cpp @@ -18,7 +18,7 @@ void BLE_Heart_Service::setupService(NimBLEServer *pServer, MyCharacteristicCall heartRateMeasurementCharacteristic->setValue(heartRateMeasurement, 2); heartRateMeasurementCharacteristic->setCallbacks(chrCallbacks); pHeartService->start(); - + // Add service UUID to DirCon MDNS DirConManager::addBleServiceUuid(pHeartService->getUUID()); } @@ -48,9 +48,12 @@ void BLE_Heart_Service::update() { MyCharacteristicCallbacks* chrCallbacks; setupService(spinBLEServer.pServer, chrCallbacks); }*/ - + byte heartRateMeasurement[2] = {0x00, (byte)rtConfig->hr.getValue()}; - heartRateMeasurementCharacteristic->notify(heartRateMeasurement, 2); + // Notify the cycling power measurement characteristic + // Need to set the value before notifying so that read works correctly. + heartRateMeasurementCharacteristic->setValue(heartRateMeasurement, 2); + heartRateMeasurementCharacteristic->notify(); DirConManager::notifyCharacteristic(NimBLEUUID(HEARTSERVICE_UUID), heartRateMeasurementCharacteristic->getUUID(), heartRateMeasurement, 2); const int kLogBufCapacity = 125; // Data(10), Sep(data/2), Arrow(3), CharId(37), Sep(3), CharId(37), Sep(3), Name(8), Prefix(2), HR(7), Suffix(2), Nul(1), rounded up diff --git a/src/BLE_SB20_Service.cpp b/src/BLE_SB20_Service.cpp index fb15f1d8..c738e26c 100644 --- a/src/BLE_SB20_Service.cpp +++ b/src/BLE_SB20_Service.cpp @@ -19,7 +19,7 @@ void BLE_SB20_Service::begin() { pService = BLEDevice::createServer()->createService(SB20_SERVICE_UUID); pCharacteristic = pService->createCharacteristic(SB20_CHARACTERISTIC_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); pService->start(); - SS2K_LOG(SS2K_LOG_TAG,"SB20 Service started\n"); + SS2K_LOG(SS2K_LOG_TAG, "SB20 Service started\n"); } void BLE_SB20_Service::setData(SB20Data data) { currentData = data; } @@ -38,6 +38,9 @@ void BLE_SB20_Service::notify() { currentData.power = rtConfig->watts.getValue(); currentData.heartrate = rtConfig->hr.getValue(); - pCharacteristic->notify((uint8_t *)¤tData, sizeof(currentData)); - SS2K_LOG(SS2K_LOG_TAG,"SB20 data sent: Gear=%d, Cadence=%d, Power=%d, HR=%d\n", currentData.gear, currentData.cadence, currentData.power, currentData.heartrate); + // Notify the cycling power measurement characteristic + // Need to set the value before notifying so that read works correctly. + pCharacteristic->setValue((uint8_t *)¤tData, sizeof(currentData)); + pCharacteristic->notify(); + SS2K_LOG(SS2K_LOG_TAG, "SB20 data sent: Gear=%d, Cadence=%d, Power=%d, HR=%d\n", currentData.gear, currentData.cadence, currentData.power, currentData.heartrate); } \ No newline at end of file diff --git a/src/BLE_Wattbike_Service.cpp b/src/BLE_Wattbike_Service.cpp index 2eb671bd..46adfdcf 100644 --- a/src/BLE_Wattbike_Service.cpp +++ b/src/BLE_Wattbike_Service.cpp @@ -28,10 +28,10 @@ void BLE_Wattbike_Service::setupService(NimBLEServer *pServer) { } void BLE_Wattbike_Service::parseNemit() { - static int lastGear = -1; // Track last gear position - static unsigned long lastNotifyTime = 0; // Track last notification time + static int lastGear = -1; // Track last gear position + static unsigned long lastNotifyTime = 0; // Track last notification time const unsigned long NOTIFY_INTERVAL = 30000; // 30 seconds in milliseconds - + // Get current shifter position int currentGear = rtConfig->getShifterPosition(); if (currentGear < 1) { // Ensure gear is at least 1 @@ -39,13 +39,13 @@ void BLE_Wattbike_Service::parseNemit() { } unsigned long currentTime = millis(); - + // Only call update if gear changed or 30 seconds elapsed if (currentGear != lastGear || (currentTime - lastNotifyTime) >= NOTIFY_INTERVAL) { update(); // Call existing update function to handle notification - + // Update tracking variables - lastGear = currentGear; + lastGear = currentGear; lastNotifyTime = currentTime; } } @@ -67,7 +67,8 @@ void BLE_Wattbike_Service::update() { gearData[2] = 0xB6; // Fixed value gearData[3] = (byte)currentGear; // Gear value - // Update the characteristic + // Notify the cycling power measurement characteristic + // Need to set the value before notifying so that read works correctly. wattbikeReadCharacteristic->setValue(gearData, sizeof(gearData)); wattbikeReadCharacteristic->notify(); DirConManager::notifyCharacteristic(NimBLEUUID(WATTBIKE_SERVICE_UUID), wattbikeReadCharacteristic->getUUID(), gearData, sizeof(gearData)); From b68cbfd320580e011a12a984c9b115fb447165ea Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 28 May 2025 20:18:06 -0500 Subject: [PATCH 234/451] switched to notifications --- src/BLE_Fitness_Machine_Service.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/BLE_Fitness_Machine_Service.cpp b/src/BLE_Fitness_Machine_Service.cpp index 9ff33cd7..b66f3e0a 100644 --- a/src/BLE_Fitness_Machine_Service.cpp +++ b/src/BLE_Fitness_Machine_Service.cpp @@ -37,7 +37,7 @@ void BLE_Fitness_Machine_Service::setupService(NimBLEServer *pServer, MyCharacte // Fitness Machine service setup pFitnessMachineService = spinBLEServer.pServer->createService(FITNESSMACHINESERVICE_UUID); fitnessMachineFeature = pFitnessMachineService->createCharacteristic(FITNESSMACHINEFEATURE_UUID, NIMBLE_PROPERTY::READ); - fitnessMachineControlPoint = pFitnessMachineService->createCharacteristic(FITNESSMACHINECONTROLPOINT_UUID, NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::INDICATE); + fitnessMachineControlPoint = pFitnessMachineService->createCharacteristic(FITNESSMACHINECONTROLPOINT_UUID, NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::INDICATE | NIMBLE_PROPERTY::NOTIFY); fitnessMachineStatusCharacteristic = pFitnessMachineService->createCharacteristic(FITNESSMACHINESTATUS_UUID, NIMBLE_PROPERTY::NOTIFY); fitnessMachineIndoorBikeData = pFitnessMachineService->createCharacteristic(FITNESSMACHINEINDOORBIKEDATA_UUID, NIMBLE_PROPERTY::NOTIFY); fitnessMachineResistanceLevelRange = pFitnessMachineService->createCharacteristic(FITNESSMACHINERESISTANCELEVELRANGE_UUID, NIMBLE_PROPERTY::READ); @@ -280,7 +280,7 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> Unsupported FTMS Request"); } } - SS2K_LOG(FMTS_SERVER_LOG_TAG, "%s", logBuf); + SS2K_LOG(FMTS_SERVER_LOG_TAG, "%s. Responding: %x%x%x", logBuf, returnValue[0], returnValue[1], returnValue[2]); } else { SS2K_LOG(FMTS_SERVER_LOG_TAG, "App wrote nothing "); SS2K_LOG(FMTS_SERVER_LOG_TAG, "assuming it's a Control request"); @@ -289,9 +289,12 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Other; // 0x00; } // not checking for subscription because a write request would have triggererd this - fitnessMachineControlPoint->indicate(returnValue.data(), returnValue.size()); - fitnessMachineTrainingStatus->notify(ftmsTrainingStatus.data(), ftmsTrainingStatus.size()); - fitnessMachineStatusCharacteristic->notify(ftmsStatus.data(), ftmsStatus.size()); + fitnessMachineControlPoint->setValue(returnValue.data(), returnValue.size()); + fitnessMachineControlPoint->notify(); + fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus.data(), ftmsTrainingStatus.size()); + fitnessMachineTrainingStatus->notify(); + fitnessMachineStatusCharacteristic->setValue(ftmsStatus.data(), ftmsStatus.size()); + fitnessMachineStatusCharacteristic->notify(); // Also notify DirCon TCP clients DirConManager::notifyCharacteristic(NimBLEUUID(FITNESSMACHINESERVICE_UUID), fitnessMachineControlPoint->getUUID(), returnValue.data(), returnValue.size()); From 54368d6b09fe2400aa6b74106120d8c8c3e612c1 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 28 May 2025 20:55:56 -0500 Subject: [PATCH 235/451] reduced comments --- src/PowerTable_Helpers.cpp | 2 +- src/Power_Table.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp index eaabbb4e..bebd861f 100644 --- a/src/PowerTable_Helpers.cpp +++ b/src/PowerTable_Helpers.cpp @@ -539,7 +539,7 @@ void PTHelpers::linearFill(PTData& ptData) { int cad = currentRowIndex * POWERTABLE_CAD_INCREMENT + MINIMUM_TABLE_CAD; int resistance = this->lookup(watts, cad, ptData); if (resistance == RETURN_ERROR) { - SS2K_LOG(PTDATA_LOG_TAG, "Failed to lookup resistance for watts: %d, cadence: %d", watts, cad); + //SS2K_LOG(PTDATA_LOG_TAG, "Failed to lookup resistance for watts: %d, cadence: %d", watts, cad); return; // Skip this cell processing } else { resistance = resistance / TABLE_DIVISOR; diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 2ed7496d..f8020cbd 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -282,7 +282,7 @@ void PowerTable::fillTable() { if (this->getNumEntries() > 4) { // set flag to stop execution after we can't add any more entries. if (esp_get_free_heap_size() < FREE_HEAP_FOR_COMPLEX_MATH) { - SS2K_LOG(POWERTABLE_LOG_TAG, "%d Heap too low for step %d.", esp_get_free_heap_size(), step); + // SS2K_LOG(POWERTABLE_LOG_TAG, "%d Heap too low for step %d.", esp_get_free_heap_size(), step); return; } entries = getNumEntries(); From 6c710f564727bf2f289be8f7b1a0c6859de9cfd9 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Thu, 29 May 2025 08:15:06 -0500 Subject: [PATCH 236/451] changed max connections back to 7 --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 3cc4d7c1..1c740de5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -31,7 +31,7 @@ build_flags = ;-D CONFIG_NEWLIB_NANO_FORMAT=y ;-D CONFIG_LWIP_IRAM_OPTIMIZATION=y ;-D CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM=y - -D CONFIG_BT_NIMBLE_MAX_CONNECTIONS=6 + -D CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 ;Disable NimBLE TinyCrypt ;-D CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y -D CONFIG_BT_NIMBLE_WHITELIST_SIZE=1 From d45fb89bb9dd5561f0504eefc01db6c9bf6797a2 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Thu, 29 May 2025 08:35:23 -0500 Subject: [PATCH 237/451] updated connected client count --- include/BLE_Common.h | 2 +- src/BLE_Common.cpp | 4 ++-- src/BLE_Server.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/BLE_Common.h b/include/BLE_Common.h index c66d1bb1..e5686804 100644 --- a/include/BLE_Common.h +++ b/include/BLE_Common.h @@ -89,6 +89,7 @@ class SpinBLEServer { void notifyShift(); double calculateSpeed(); void update(); + int connectedClientCount(); // Queue to store writes to any of the callbacks to the server std::queue writeCache; }; @@ -108,7 +109,6 @@ void startBLEServer(); void logCharacteristic(char* buffer, const size_t bufferCapacity, const byte* data, const size_t dataLength, const NimBLEUUID serviceUUID, const NimBLEUUID charUUID, const char* format, ...); void calculateInstPwrFromHR(); -int connectedClientCount(); // BLE FIRMWARE UPDATER void BLEFirmwareSetup(); diff --git a/src/BLE_Common.cpp b/src/BLE_Common.cpp index 229b17c0..d36977ee 100644 --- a/src/BLE_Common.cpp +++ b/src/BLE_Common.cpp @@ -105,7 +105,7 @@ void BLECommunications() { #endif if (BLEDevice::getAdvertising()) { - if (!(BLEDevice::getAdvertising()->isAdvertising()) && (BLEDevice::getServer()->getConnectedCount() < CONFIG_BT_NIMBLE_MAX_CONNECTIONS - NUM_BLE_DEVICES)) { + if ((!BLEDevice::getAdvertising()->isAdvertising()) && (spinBLEServer.connectedClientCount() < CONFIG_BT_NIMBLE_MAX_CONNECTIONS - NUM_BLE_DEVICES)) { SS2K_LOG(BLE_COMMON_LOG_TAG, "Starting Advertising From Communication Loop"); BLEDevice::startAdvertising(); } @@ -113,7 +113,7 @@ void BLECommunications() { } // blink if no client connected - if (connectedClientCount() == 0) { + if (spinBLEServer.connectedClientCount() == 0) { if ((millis() / 500) % 2 == 0) { digitalWrite(LED_PIN, LOW); } else { diff --git a/src/BLE_Server.cpp b/src/BLE_Server.cpp index f4a7cd54..0d952289 100644 --- a/src/BLE_Server.cpp +++ b/src/BLE_Server.cpp @@ -200,7 +200,7 @@ void MyCharacteristicCallbacks::onSubscribe(NimBLECharacteristic* pCharacteristi } // Return number of clients connected to our server. -int connectedClientCount() { +int SpinBLEServer::connectedClientCount() { if (BLEDevice::getServer()) { return BLEDevice::getServer()->getConnectedCount(); } else { From bfb11ff0aceffdf7c7926b0a61dc6a4f552acf10 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Thu, 29 May 2025 08:37:23 -0500 Subject: [PATCH 238/451] decreased mtBLEDevices to 3 --- include/settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/settings.h b/include/settings.h index 640dc2e7..fc9272c6 100644 --- a/include/settings.h +++ b/include/settings.h @@ -214,7 +214,7 @@ const char* const DEFAULT_PASSWORD = "password"; #define BLE_CLIENT_DELAY 101 // Number of devices that can be connected to the Client (myBLEDevices size) -#define NUM_BLE_DEVICES 4 +#define NUM_BLE_DEVICES 3 // loop speed for the Webserver #define WEBSERVER_DELAY 7 From d9285fd345587dbca77d1b569cba6c2f9fbf8329 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sat, 31 May 2025 15:01:51 -0500 Subject: [PATCH 239/451] lower memory usage --- platformio.ini | 10 +++++++--- src/BLE_Common.cpp | 9 +++++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/platformio.ini b/platformio.ini index 1c740de5..3741d6f2 100644 --- a/platformio.ini +++ b/platformio.ini @@ -32,12 +32,16 @@ build_flags = ;-D CONFIG_LWIP_IRAM_OPTIMIZATION=y ;-D CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM=y -D CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 - ;Disable NimBLE TinyCrypt - ;-D CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y - -D CONFIG_BT_NIMBLE_WHITELIST_SIZE=1 + -D CONFIG_BT_NIMBLE_WHITELIST_SIZE=0 -D CONFIG_MDNS_STRICT_MODE=1 -D CORE_DEBUG_LEVEL=1 -D ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=3500 + ;-D CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=8000 + -D CONFIG_BT_NIMBLE_MAX_CCCDS=0 + -D CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=1 + -D CONFIG_NIMBLE_STACK_USE_MEM_POOLS=1 + -D CONFIG_BT_NIMBLE_MAX_BONDS=1 + -std=gnu++17 lib_deps = https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.3.0.zip diff --git a/src/BLE_Common.cpp b/src/BLE_Common.cpp index d36977ee..c15e6f08 100644 --- a/src/BLE_Common.cpp +++ b/src/BLE_Common.cpp @@ -105,8 +105,13 @@ void BLECommunications() { #endif if (BLEDevice::getAdvertising()) { - if ((!BLEDevice::getAdvertising()->isAdvertising()) && (spinBLEServer.connectedClientCount() < CONFIG_BT_NIMBLE_MAX_CONNECTIONS - NUM_BLE_DEVICES)) { - SS2K_LOG(BLE_COMMON_LOG_TAG, "Starting Advertising From Communication Loop"); + if ((!BLEDevice::getAdvertising()->isAdvertising()) && (spinBLEServer.connectedClientCount() < (CONFIG_BT_NIMBLE_MAX_CONNECTIONS - NUM_BLE_DEVICES))) { + SS2K_LOG(BLE_COMMON_LOG_TAG, "Starting Advertising From Communication Loop. Connected Clients: %d", spinBLEServer.connectedClientCount()); + auto clients = BLEDevice::getConnectedClients(); + //loop through clients and log their addresses + for (const auto& client : clients) { + SS2K_LOG(BLE_COMMON_LOG_TAG, "Connected Client: %s", client->getPeerAddress().toString().c_str()); + } BLEDevice::startAdvertising(); } } From fdcb94993617db8e48b17a7c98fedc6bc98b456f Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 18 Jun 2025 12:38:58 -0500 Subject: [PATCH 240/451] limited to one dircon connection. removed unused variables. --- .vscode/settings.json | 4 +- include/DirConManager.h | 2 +- include/PowerTable_Helpers.h | 3 +- include/settings.h | 3 - src/BLE_Client.cpp | 6 +- src/BLE_Custom_Characteristic.cpp | 1 - src/BLE_Server.cpp | 12 ++- src/DirConManager.cpp | 2 +- src/ERG_Mode.cpp | 1 - src/HTTP_Server_Basic.cpp | 5 -- src/Main.cpp | 1 - src/PowerTable_Helpers.cpp | 130 +++++++++++++++++------------- src/Power_Table.cpp | 17 ++-- src/SS2KLog.cpp | 6 -- 14 files changed, 97 insertions(+), 96 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 7c53a4d3..287233fe 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -93,7 +93,9 @@ "locale": "cpp", "print": "cpp", "queue": "cpp", - "stack": "cpp" + "stack": "cpp", + "regex": "cpp", + "future": "cpp" }, "cSpell.words": [ "Appender", diff --git a/include/DirConManager.h b/include/DirConManager.h index 37b17828..a701a2c3 100644 --- a/include/DirConManager.h +++ b/include/DirConManager.h @@ -18,7 +18,7 @@ #define DIRCON_MDNS_SERVICE_NAME "_wahoo-fitness-tnp" #define DIRCON_MDNS_SERVICE_PROTOCOL "tcp" #define DIRCON_TCP_PORT 8081 -#define DIRCON_MAX_CLIENTS 3 +#define DIRCON_MAX_CLIENTS 1 #define DIRCON_RECEIVE_BUFFER_SIZE 256 #define DIRCON_SEND_BUFFER_SIZE 256 #define DIRCON_MAX_CHARACTERISTICS 10 // maximum number of characteristics to track for subscriptions diff --git a/include/PowerTable_Helpers.h b/include/PowerTable_Helpers.h index 3ddc71ad..f229477a 100644 --- a/include/PowerTable_Helpers.h +++ b/include/PowerTable_Helpers.h @@ -121,9 +121,8 @@ class PTHelpers { int32_t lookup(int watts, int cad, PTData& ptData); void extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, std::pair, std::vector> xy, size_t n, bool horizontal, bool naturalSpline, PTData& ptData); - void extrapFillTableDirection(bool horizontal, PTData& ptData, bool firtHalf = true); + void splineFill(PTData& ptData, bool firtHalf = true,bool horizontal = true); float linearExtrapolate(std::pair, std::vector> xy, size_t n, float j); - void splineFill(PTData& ptData, bool firstHalf = true); void linearFill(PTData& ptData); int32_t lookupWatts(int cad, int32_t targetPosition, PTData& ptData); int32_t extrapolateCadenceWatts(int cad, float targetPosition, PTData& ptData); diff --git a/include/settings.h b/include/settings.h index fc9272c6..5eab577e 100644 --- a/include/settings.h +++ b/include/settings.h @@ -320,9 +320,6 @@ const char* const DEFAULT_PASSWORD = "password"; // If not receiving Peloton Messages, how long to wait before next TX attempt is #define TX_CHECK_INTERVAL 20 -// If ble devices are both setup, how often to attempt a reconnect. -#define BLE_RECONNECT_INTERVAL 1 - // Interval for polling ble battery updates #define BATTERY_UPDATE_INTERVAL_MILLIS 300000 diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index f9dd57b6..8506d251 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -200,7 +200,6 @@ bool SpinBLEClient::connectToServer() { NimBLEUUID serviceUUID; NimBLEUUID charUUID; - int successful = 0; const NimBLEAdvertisedDevice *myDevice = nullptr; int device_number = -1; @@ -420,7 +419,6 @@ void ScanCallbacks::onResult(const NimBLEAdvertisedDevice *advertisedDevice) { const char *const STRING_MATCHED_ANY = " String Matched Any"; const char *const THIS = "This "; const char *const NAME = "Name "; - const char *const ADDRESS = "Address "; const char *const REMOTE = "Remote"; const char *const HRM = "HRM"; const char *const PM = "PM"; @@ -748,14 +746,14 @@ NotifyData SpinBLEAdvertisedDevice::dequeueData() { void SpinBLEClient::connectBLE_HID(NimBLEClient *pClient) { NimBLERemoteService *pSvc = nullptr; - NimBLERemoteCharacteristic *pChr = nullptr; pSvc = pClient->getService(HID_SERVICE_UUID); if (pSvc) { /** make sure it's not null */ // This returns the HID report descriptor like this // HID_REPORT_MAP 0x2a4b Value: 5,1,9,2,A1,1,9,1,A1,0,5,9,19,1,29,5,15,0,25,1,75,1, // Copy and paste the value digits to http://eleccelerator.com/usbdescreqparser/ // to see the decoded report descriptor. - /*pChr = pSvc->getCharacteristic(HID_REPORT_MAP_UUID); + /*NimBLERemoteCharacteristic *pChr = nullptr; + pChr = pSvc->getCharacteristic(HID_REPORT_MAP_UUID); if (pChr) { /** make sure it's not null */ /* Serial.print("HID_REPORT_MAP "); if (pChr->canRead()) { diff --git a/src/BLE_Custom_Characteristic.cpp b/src/BLE_Custom_Characteristic.cpp index ce10d1df..7e08940f 100644 --- a/src/BLE_Custom_Characteristic.cpp +++ b/src/BLE_Custom_Characteristic.cpp @@ -140,7 +140,6 @@ void BLE_ss2kCustomCharacteristic::process(std::string rxValue) { } NimBLECharacteristic *pCharacteristic = NimBLEDevice::getServer()->getServiceByUUID(SMARTSPIN2K_SERVICE_UUID)->getCharacteristic(SMARTSPIN2K_CHARACTERISTIC_UUID); uint8_t *pData = reinterpret_cast(&rxValue[0]); - int length = rxValue.length(); #ifdef CUSTOM_CHAR_DEBUG #define LOG_BUF_APPEND(...) logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, __VA_ARGS__) diff --git a/src/BLE_Server.cpp b/src/BLE_Server.cpp index 0d952289..1f9a87e1 100644 --- a/src/BLE_Server.cpp +++ b/src/BLE_Server.cpp @@ -106,9 +106,9 @@ void SpinBLEServer::updateWheelAndCrankRev() { } // Calculate wheel revolutions per minute - float wheelRpm = (wheelSpeedMps / wheelSize) * 60; - double wheelRevPeriod = (60 * 1024) / wheelRpm; + float wheelRpm = (wheelSpeedMps / wheelSize) * 60; if (wheelRpm > 0) { + double wheelRevPeriod = (60 * 1024) / wheelRpm; spinBLEClient.cscCumulativeWheelRev++; // Increment cumulative wheel revolutions spinBLEClient.cscLastWheelEvtTime += wheelRevPeriod; // Convert RPM to time, ensuring no division by zero } @@ -167,7 +167,11 @@ void MyCharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, N } void MyCharacteristicCallbacks::onStatus(NimBLECharacteristic* pCharacteristic, int code) { - // loop through and accumulate the data into a C++ string +// loop through and accumulate the data into a C++ string +// only used for extensive logging. +#ifndef DEBUG_BLE_TX_RX + return; +#endif std::string characteristicValue = pCharacteristic->getValue(); std::string logValue; for (size_t i = 0; i < characteristicValue.length(); ++i) { @@ -176,7 +180,7 @@ void MyCharacteristicCallbacks::onStatus(NimBLECharacteristic* pCharacteristic, logValue += buf; } - // SS2K_LOG(BLE_SERVER_LOG_TAG, "%s -> %s", pCharacteristic->getUUID().toString().c_str(), logValue.c_str()); + SS2K_LOG(BLE_SERVER_LOG_TAG, "%s -> %s", pCharacteristic->getUUID().toString().c_str(), logValue.c_str()); } void MyCharacteristicCallbacks::onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) { diff --git a/src/DirConManager.cpp b/src/DirConManager.cpp index 1b77cf36..3f675679 100644 --- a/src/DirConManager.cpp +++ b/src/DirConManager.cpp @@ -536,12 +536,12 @@ void DirConManager::broadcastNotification(const NimBLEUUID& characteristicUuid, } // Send to all connected clients - bool sentDebug = false; for (int i = 0; i < DIRCON_MAX_CLIENTS; i++) { if (!dirConClients[i].connected() || !hasSubscription(i, characteristicUuid)) { continue; } #ifdef DEBUG_DIRCON_MESSAGES + bool sentDebug = false; // Print the outgoing raw message bytes to serial if (!sentDebug) DirConMessage::printVectorBytesToSerial(*encodedMessage, false); sentDebug = true; diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index e0f32036..4b7672de 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -117,7 +117,6 @@ void ErgMode::runERG() { // compute position for resistance control mode void ErgMode::computeResistance() { - static int stepChangePerResistance = userConfig->getShiftStep(); static Measurement oldResistance; if (rtConfig->resistance.getTimestamp() == oldResistance.getTimestamp()) { diff --git a/src/HTTP_Server_Basic.cpp b/src/HTTP_Server_Basic.cpp index 905d5c75..3fa22855 100644 --- a/src/HTTP_Server_Basic.cpp +++ b/src/HTTP_Server_Basic.cpp @@ -65,7 +65,6 @@ void startWifi() { SS2K_LOG(HTTP_SERVER_LOG_TAG, "Waiting for connection to be established..."); i++; if (i > WIFI_CONNECT_TIMEOUT) { - i = 0; SS2K_LOG(HTTP_SERVER_LOG_TAG, "Couldn't Connect. Switching to AP mode"); WiFi.disconnect(true, true); WiFi.setAutoReconnect(false); @@ -565,7 +564,6 @@ void HTTP_Server::settingsProcessor() { if (!server.arg("bleHRDropdown").isEmpty()) { wasBTUpdate = true; if (server.arg("bleHRDropdown")) { - bool reset = false; tString = server.arg("bleHRDropdown"); if (tString != userConfig->getConnectedHeartMonitor()) { spinBLEClient.reconnectAllDevices(); @@ -578,7 +576,6 @@ void HTTP_Server::settingsProcessor() { if (!server.arg("bleRemoteDropdown").isEmpty()) { wasBTUpdate = true; if (server.arg("bleRemoteDropdown")) { - bool reset = false; tString = server.arg("bleRemoteDropdown"); if (tString != userConfig->getConnectedRemote()) { spinBLEClient.reconnectAllDevices(); @@ -673,7 +670,6 @@ void HTTP_Server::FirmwareUpdate() { delay(100); JsonDocument doc; if (httpCode == HTTP_CODE_OK) { // if version received - String payload; payload = http.getString(); // save received version payload.trim(); // Deserialize the JSON document @@ -701,7 +697,6 @@ void HTTP_Server::FirmwareUpdate() { httpCode = http.GET(); delay(100); if (httpCode == HTTP_CODE_OK) { - String payload; payload = http.getString(); payload.trim(); LittleFS.remove(fileName); diff --git a/src/Main.cpp b/src/Main.cpp index 3b41040d..47d2db11 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -198,7 +198,6 @@ void loop() { // Delete this task so we can make one that's more memory efficie void SS2K::maintenanceLoop(void *pvParameters) { static unsigned long intervalTimer2 = millis(); static unsigned long rebootTimer = millis(); - static bool isScanning = false; while (true) { delay(5); diff --git a/src/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp index bebd861f..9469c63e 100644 --- a/src/PowerTable_Helpers.cpp +++ b/src/PowerTable_Helpers.cpp @@ -205,7 +205,6 @@ int32_t PTHelpers::lookup(int watts, int cad, PTData& ptData) { const int MIN_WATT_VAL = 0; // Assuming watts index start from 0 const int MAX_WATT_VAL = (POWERTABLE_WATT_SIZE - 1) * POWERTABLE_WATT_INCREMENT; int32_t resistance = RETURN_ERROR; - int ptDataSize = dataPoints(ptData); std::pair, std::vector> dataPoints; bool isCadOutOfTable = cad < MIN_CAD_VAL || cad > MAX_CAD_VAL; @@ -214,17 +213,14 @@ int32_t PTHelpers::lookup(int watts, int cad, PTData& ptData) { // ---- A. Handle Out-of-Table simple Extrapolation ---- if (isCadOutOfTable && !isWattOutOfTable) { - // A.1. Attempt Cadence Extrapolation if cadence is out of bounds - if (isCadOutOfTable) { - int targetWattIndex = index.wattIndex; - // Clamp targetWattIndex to be within table bounds for selecting the column - if (targetWattIndex < 0) targetWattIndex = 0; - dataPoints = getColumn(targetWattIndex, ptData); - if (dataPoints.first.size() >= 2) { - float extrapolatedVal = linearExtrapolate(dataPoints, dataPoints.first.size(), static_cast(cad)); - if (extrapolatedVal != INT16_MIN && !std::isnan(extrapolatedVal) && !std::isinf(extrapolatedVal)) { - resistance = static_cast(round(extrapolatedVal)) * TABLE_DIVISOR; - } + int targetWattIndex = index.wattIndex; + // Clamp targetWattIndex to be within table bounds for selecting the column + if (targetWattIndex < 0) targetWattIndex = 0; + dataPoints = getColumn(targetWattIndex, ptData); + if (dataPoints.first.size() >= 2) { + float extrapolatedVal = linearExtrapolate(dataPoints, dataPoints.first.size(), static_cast(cad)); + if (extrapolatedVal != INT16_MIN && !std::isnan(extrapolatedVal) && !std::isinf(extrapolatedVal)) { + resistance = static_cast(round(extrapolatedVal)) * TABLE_DIVISOR; } } } @@ -301,17 +297,33 @@ int32_t PTHelpers::lookup(int watts, int cad, PTData& ptData) { if (count > 0) { resistance = static_cast(round(sum / count)) * TABLE_DIVISOR; - //SS2K_LOG(PTDATA_LOG_TAG, "Lookup result: watts=%d, cad=%d, resistance=%d", watts, cad, resistance); - // LOG R1, R2, R3 values for debugging - //SS2K_LOG(PTDATA_LOG_TAG, "R1: %f, R2: %f, R3: %f", R1, R2, R3); + // SS2K_LOG(PTDATA_LOG_TAG, "Lookup result: watts=%d, cad=%d, resistance=%d", watts, cad, resistance); + // LOG R1, R2, R3 values for debugging + // SS2K_LOG(PTDATA_LOG_TAG, "R1: %f, R2: %f, R3: %f", R1, R2, R3); } return resistance; // All lookup methods failed } +/** + * @brief Extrapolates and fills empty indices in a power table row or column using cubic spline interpolation and neighbor blending. + * + * This function takes a set of empty indices within a row or column of a power table and attempts to extrapolate their values + * based on existing (x, y) data points using cubic spline interpolation. The extrapolated value is then blended with nearby + * valid neighbors to ensure smoothness and avoid abrupt transitions. The function also ensures that the extrapolated values + * remain within a reasonable range, slightly extended beyond the min/max of the known values. Neighbor blending uses a + * distance-based decay to weight closer neighbors more heavily. + * + * @param outerIndex The index of the row or column being processed, depending on the orientation. + * @param emptyIndices The indices within the row or column that are empty and need to be extrapolated. + * @param xy A pair of vectors representing the known (x, y) data points for interpolation. + * @param n The number of valid (x, y) data points. + * @param horizontal If true, extrapolation is performed horizontally (across columns); otherwise, vertically (across rows). + * @param naturalSpline If true, use a natural cubic spline for interpolation (currently unused in this function). + * @param ptData Reference to the power table data structure to be updated with extrapolated values. + */ void PTHelpers::extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, std::pair, std::vector> xy, size_t n, bool horizontal, bool naturalSpline, PTData& ptData) { - int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; ptIndex index; if (n >= 3) { bool validForSpline = true; @@ -343,29 +355,29 @@ void PTHelpers::extrapolateEmptyIndices(int outerIndex, const std::vector& if (testNeighbors(index, tempValue, ptData).allNeighborsPassed) { // Blend with nearby valid neighbors to ensure smoothness float blendedValue = tempValue; - float totalWeight = 1.0f; // Start with original value - + float totalWeight = 1.0f; // Start with original value + // Check horizontal and vertical neighbors within 2 steps - const int blendRadius = 2; + const int blendRadius = 2; const float distanceDecay = 0.7f; // Weight decreases with distance - + for (int di = -blendRadius; di <= blendRadius; di++) { for (int dj = -blendRadius; dj <= blendRadius; dj++) { // Skip self if (di == 0 && dj == 0) continue; - + int ni = index.cadIndex + (horizontal ? 0 : di); int nj = index.wattIndex + (horizontal ? di : 0); - + // Check if neighbor is valid if (ni >= 0 && ni < POWERTABLE_CAD_SIZE && nj >= 0 && nj < POWERTABLE_WATT_SIZE) { int16_t neighborVal = ptData.tableRow[ni].tableEntry[nj].targetPosition; - + if (neighborVal != INT16_MIN) { // Calculate distance-based weight float distance = std::fabs(di) + std::fabs(dj); // Manhattan distance - float weight = std::pow(distanceDecay, distance); - + float weight = std::pow(distanceDecay, distance); + // Add to weighted average blendedValue += neighborVal * weight; totalWeight += weight; @@ -373,24 +385,36 @@ void PTHelpers::extrapolateEmptyIndices(int outerIndex, const std::vector& } } } - + // Compute final blended value if we found neighbors if (totalWeight > 1.0f) { // More weight to original spline value (70%) for trend preservation float originalWeight = 0.7f; float neighborWeight = 1.0f - originalWeight; - - blendedValue = (originalWeight * tempValue + - neighborWeight * (blendedValue - tempValue) / (totalWeight - 1.0f)); + + blendedValue = (originalWeight * tempValue + neighborWeight * (blendedValue - tempValue) / (totalWeight - 1.0f)); } - + ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition = static_cast(round(blendedValue)); } } } } -void PTHelpers::extrapFillTableDirection(bool horizontal, PTData& ptData, bool firstHalf) { +/** + * @brief Fills missing entries in the power table using cubic spline interpolation. + * + * This function processes either the first or second half of the table rows or columns, + * depending on the `firstHalf` parameter, and interpolates missing values (marked by INT16_MIN) + * using cubic splines. The interpolation is performed either horizontally (across watt indices) + * or vertically (across cadence indices) as determined by the `horizontal` parameter. + * The function ensures overlap between the two halves to provide smooth transitions. + * + * @param ptData Reference to the power table data structure to be filled. + * @param firstHalf (optional) If true, processes the first half (with overlap); otherwise, processes the second half. Default is true. + * @param horizontal (optional) If true, fills across watt indices (rows); if false, fills across cadence indices (columns). Default is true. + */ +void PTHelpers::splineFill(PTData& ptData, bool firstHalf /*= true*/, bool horizontal /*= true*/) { int outerSize = horizontal ? POWERTABLE_CAD_SIZE : POWERTABLE_WATT_SIZE; int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; @@ -405,23 +429,21 @@ void PTHelpers::extrapFillTableDirection(bool horizontal, PTData& ptData, bool f rangeStart = 0; // Ensure overlap: process a bit more than half, e.g., 2/3 or 3/4 // The amount of overlap might need tuning. Let's try 2/3 for now. - rangeEnd = (innerSize * 2) / 3; - if (rangeEnd > innerSize) rangeEnd = innerSize; // cap at innerSize + rangeEnd = (innerSize * 2) / 3; + if (rangeEnd > innerSize) rangeEnd = innerSize; // cap at innerSize } else { // Start from a point that ensures overlap with the first half rangeStart = innerSize / 3; rangeEnd = innerSize; } - - int mid_outer = outerSize / 2; + int mid_outer = outerSize / 2; int max_k_outer = 0; if (outerSize > 0) { - max_k_outer = std::max(mid_outer, (outerSize - 1) - mid_outer); + max_k_outer = std::max(mid_outer, (outerSize - 1) - mid_outer); } - auto processOuterIndex = - [&](int currentOuterIndex) { + auto processOuterIndex = [&](int currentOuterIndex) { unique_xy.clear(); emptyIndices.clear(); x.clear(); @@ -435,7 +457,7 @@ void PTHelpers::extrapFillTableDirection(bool horizontal, PTData& ptData, bool f // Boundary checks for safety, though currentOuterIndex should be valid by loop logic if (index.cadIndex < 0 || index.cadIndex >= POWERTABLE_CAD_SIZE || index.wattIndex < 0 || index.wattIndex >= POWERTABLE_WATT_SIZE) { - continue; + continue; } if (ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition != INT16_MIN) { @@ -503,9 +525,9 @@ float PTHelpers::linearExtrapolate(std::pair, std::vector, std::vectorlookup(watts, cad, ptData); if (resistance == RETURN_ERROR) { - //SS2K_LOG(PTDATA_LOG_TAG, "Failed to lookup resistance for watts: %d, cadence: %d", watts, cad); - return; // Skip this cell processing + // SS2K_LOG(PTDATA_LOG_TAG, "Failed to lookup resistance for watts: %d, cadence: %d", watts, cad); + return; // Skip this cell processing } else { resistance = resistance / TABLE_DIVISOR; } ptIndex current_pt_idx; - current_pt_idx.wattIndex = currentColIndex; - current_pt_idx.cadIndex = currentRowIndex; - TestResults results = this->testNeighbors(current_pt_idx, resistance, ptData); + current_pt_idx.wattIndex = currentColIndex; + current_pt_idx.cadIndex = currentRowIndex; + TestResults results = this->testNeighbors(current_pt_idx, resistance, ptData); if (results.allNeighborsPassed == 1) { ptData.tableRow[currentRowIndex].tableEntry[currentColIndex].targetPosition = resistance; - //SS2K_LOG(PTDATA_LOG_TAG, "Filled position (%d, %d) with resistance: %d", currentRowIndex, currentColIndex, resistance); + // SS2K_LOG(PTDATA_LOG_TAG, "Filled position (%d, %d) with resistance: %d", currentRowIndex, currentColIndex, resistance); } else { // log the failure to in insert the value // Serial.printf("Failed to fill position (%d, %d) with resistance: %d\n", currentRowIndex, currentColIndex, resistance); } @@ -560,7 +577,7 @@ void PTHelpers::linearFill(PTData& ptData) { for (int k = 0; k <= max_k; ++k) { // Process row from mid upwards: mid, mid+1, mid+2, ... int i_upper = mid + k; - if (i_upper < POWERTABLE_CAD_SIZE) { // Ensure i_upper is a valid row index + if (i_upper < POWERTABLE_CAD_SIZE) { // Ensure i_upper is a valid row index for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { processCell(i_upper, j); } @@ -569,7 +586,7 @@ void PTHelpers::linearFill(PTData& ptData) { // Process row from mid downwards: mid-1, mid-2, ..., only if k > 0 to avoid re-processing 'mid' if (k > 0) { int i_lower = mid - k; - if (i_lower >= 0) { // Ensure i_lower is a valid row index + if (i_lower >= 0) { // Ensure i_lower is a valid row index for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { processCell(i_lower, j); } @@ -623,7 +640,6 @@ int PTHelpers::extrapolateWattsFromCadence(int cad, int32_t targetPosition, PTDa } ptIndex index = calculateIndex(0, cad); // Ensure the index is calculated for the given cadence bool inCadenceRange = index.cadIndex >= 0 && index.cadIndex < POWERTABLE_CAD_SIZE; - bool inWattRange = index.wattIndex >= 0 && index.wattIndex < POWERTABLE_WATT_SIZE; std::pair, std::vector> xyUsed4Offset; std::pair, std::vector> xy; // Get the row data for the given cadence @@ -644,11 +660,9 @@ int PTHelpers::extrapolateWattsFromCadence(int cad, int32_t targetPosition, PTDa // SS2K_LOG(PTDATA_LOG_TAG, "LookupWatts: index.cadIndex == %d, xy %f, xyused4Offset %f, cadDelta %d", index.cadIndex, xy.second[0], xyUsed4Offset.second[0], cadDelta); } for (int i = 0; i < xy.second.size(); i++) { - bool found = false; for (int j = 0; j < xyUsed4Offset.second.size(); j++) { if (xy.first[i] == xyUsed4Offset.first[j]) { offset = (((xyUsed4Offset.second[j] - xy.second[i]) * cadDelta) + offset) / 2; - bool found = true; } } } diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index f8020cbd..628f6e6e 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -151,7 +151,6 @@ int PowerTable::getNumEntries() { void PowerTable::clean() { SS2K_LOG(POWERTABLE_LOG_TAG, "Clean Power Table"); - int ret = 0; for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { if (this->ptData.tableRow[i].tableEntry[j].readings < 1) { @@ -166,7 +165,6 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { float watts = 0; float cad = 0; float targetPosition = 0; - int avgPosition = 0; // First, take the power buffer and average all of the samples together. int validEntries = 0; @@ -233,6 +231,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } this->enterData(index, (int)targetPosition); + fillTableFlag = true; // set flag to fill table BLE_ss2kCustomCharacteristic::notify(0x27, index.cadIndex); } @@ -263,7 +262,6 @@ void PowerTable::enterData(ptIndex index, int pos) { } } this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings++; - fillTableFlag = true; // set flag to fill table } void PowerTable::fillTable() { @@ -272,6 +270,7 @@ void PowerTable::fillTable() { static int8_t step = 0; static int prevEntries = 0; + //Abort if the fillTableFlag is not set. if (!fillTableFlag) { entries = 0; newEntries = 0; @@ -279,6 +278,7 @@ void PowerTable::fillTable() { step = 0; return; } + if (this->getNumEntries() > 4) { // set flag to stop execution after we can't add any more entries. if (esp_get_free_heap_size() < FREE_HEAP_FOR_COMPLEX_MATH) { @@ -289,11 +289,11 @@ void PowerTable::fillTable() { if (step == 0) { SS2K_LOG(POWERTABLE_LOG_TAG, "Fill start with %d entries", entries); prevEntries = entries; - ptHelpers.splineFill(ptData); + ptHelpers.splineFill(ptData, true); } else if (step == 1) { - ptHelpers.linearFill(ptData); + ptHelpers.splineFill(ptData, false); } else if (step == 2) { - // NOT IMPLEMENTED YET + ptHelpers.linearFill(ptData); } newEntries = getNumEntries(); SS2K_LOG(POWERTABLE_LOG_TAG, "Fill step %d added %d new entries", step, newEntries - prevEntries); @@ -302,7 +302,8 @@ void PowerTable::fillTable() { } else if (step == 2) { SS2K_LOG(POWERTABLE_LOG_TAG, "No more entries can be added, stopping fill."); fillTableFlag = false; - step = -1; + step = 0; + return; } step = (step + 1) % 3; } @@ -387,7 +388,7 @@ float PowerTable::calculatePosition(float watts, float cad, float targetPos, ptI float positions[] = {float(wattPosition + POWERTABLE_WATT_INCREMENT), float(wattPosition - POWERTABLE_WATT_INCREMENT), float(cadPosition + POWERTABLE_CAD_INCREMENT), float(cadPosition - POWERTABLE_CAD_INCREMENT)}; bool passedTests[] = {testResults.rightNeighbor.passedTest, testResults.leftNeighbor.passedTest, testResults.bottomNeighbor.passedTest, testResults.topNeighbor.passedTest}; - bool isValid[] = {testResults.rightNeighbor.found, testResults.leftNeighbor.found, testResults.bottomNeighbor.found, testResults.topNeighbor.found}; + bool isValid[] = {testResults.rightNeighbor.found, testResults.leftNeighbor.found, testResults.bottomNeighbor.found, testResults.topNeighbor.found}; float totalValue = 0.0f; int count = 0; diff --git a/src/SS2KLog.cpp b/src/SS2KLog.cpp index 7d1901bd..397098e4 100644 --- a/src/SS2KLog.cpp +++ b/src/SS2KLog.cpp @@ -75,12 +75,6 @@ void LogHandler::writev(esp_log_level_t level, const char *module, const char *f Serial.println(buffer); } - size_t bytesSent = xMessageBufferSend(_messageBufferHandle, buffer, written, 0); - - //if (bytesSent < written) { - // ESP_LOGE(LOG_HANDLER_TAG, "Can not send log message. Not enough free space left in buffer."); - //} - xSemaphoreGive(_logBufferMutex); } From af21a7a3f79eb96439b5832741036afa5facf2f9 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Thu, 19 Jun 2025 11:42:59 -0500 Subject: [PATCH 241/451] re-enabled logging --- platformio.ini | 8 ++++++-- src/SS2KLog.cpp | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 3741d6f2..e6fa1a2d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -39,9 +39,9 @@ build_flags = ;-D CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=8000 -D CONFIG_BT_NIMBLE_MAX_CCCDS=0 -D CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=1 - -D CONFIG_NIMBLE_STACK_USE_MEM_POOLS=1 + ;-D CONFIG_NIMBLE_STACK_USE_MEM_POOLS=1 -D CONFIG_BT_NIMBLE_MAX_BONDS=1 - + -D CONFIG_BT_NIMBLE_BLOCK_COUNT=40 -std=gnu++17 lib_deps = https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.3.0.zip @@ -79,6 +79,10 @@ lib_deps = lib/ArduinoCompat lib/SS2K build_flags = + -Wunused + -Wunused-function + -Wunused-variable + -Wunreachable-code -std=c++11 -D PLATFORMIO_ENV_NATIVE lib_ldf_mode = chain+ diff --git a/src/SS2KLog.cpp b/src/SS2KLog.cpp index 397098e4..cbe1e647 100644 --- a/src/SS2KLog.cpp +++ b/src/SS2KLog.cpp @@ -75,6 +75,7 @@ void LogHandler::writev(esp_log_level_t level, const char *module, const char *f Serial.println(buffer); } + xMessageBufferSend(_messageBufferHandle, buffer, written, 0); xSemaphoreGive(_logBufferMutex); } From 52ade50ea442c54a411f4aa0bfbad7f0ff6167d0 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sat, 21 Jun 2025 09:27:37 -0600 Subject: [PATCH 242/451] Should have fixed max connections issue --- platformio.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platformio.ini b/platformio.ini index e6fa1a2d..879e1916 100644 --- a/platformio.ini +++ b/platformio.ini @@ -41,17 +41,17 @@ build_flags = -D CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=1 ;-D CONFIG_NIMBLE_STACK_USE_MEM_POOLS=1 -D CONFIG_BT_NIMBLE_MAX_BONDS=1 - -D CONFIG_BT_NIMBLE_BLOCK_COUNT=40 + ;-D CONFIG_BT_NIMBLE_BLOCK_COUNT=20 -std=gnu++17 lib_deps = - https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.3.0.zip + ;https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.3.0.zip https://github.com/teemuatlut/TMCStepper/archive/refs/tags/v0.7.3.zip https://github.com/bblanchon/ArduinoJson/archive/refs/tags/v7.3.1.zip ;https://github.com/gin66/FastAccelStepper/archive/refs/tags/0.31.2.zip https://github.com/doudar/FastAccelStepper/ https://github.com/gilmaimon/ArduinoWebsockets/archive/refs/tags/0.5.4.zip ;https://github.com/Links2004/arduinoWebSockets - ;https://github.com/doudar/NimBLE-Arduino/ + https://github.com/doudar/NimBLE-Arduino/ [env:release] extends = esp32doit From 340b18d4cd8ace802ab9e655fbe00ac65f4e4a4f Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sat, 21 Jun 2025 19:33:10 -0700 Subject: [PATCH 243/451] spline fill methods check for time --- include/PowerTable_Helpers.h | 7 ++++--- src/PowerTable_Helpers.cpp | 24 +++++++++++++++++++----- src/Power_Table.cpp | 11 ++++++----- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/include/PowerTable_Helpers.h b/include/PowerTable_Helpers.h index f229477a..f740bcce 100644 --- a/include/PowerTable_Helpers.h +++ b/include/PowerTable_Helpers.h @@ -14,6 +14,7 @@ #define RETURN_ERROR INT32_MIN #define FREE_HEAP_FOR_COMPLEX_MATH 30000 +#define COMPUTATION_TIMEOUT_MS 50 class PowerEntry { public: @@ -119,11 +120,11 @@ class PTHelpers { public: TestResults testNeighbors(ptIndex index, int value, PTData& ptData); int32_t lookup(int watts, int cad, PTData& ptData); - void extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, std::pair, std::vector> xy, size_t n, bool horizontal, + bool extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, std::pair, std::vector> xy, size_t n, bool horizontal, bool naturalSpline, PTData& ptData); - void splineFill(PTData& ptData, bool firtHalf = true,bool horizontal = true); + bool splineFill(PTData& ptData, bool firtHalf = true,bool horizontal = true); float linearExtrapolate(std::pair, std::vector> xy, size_t n, float j); - void linearFill(PTData& ptData); + bool linearFill(PTData& ptData); int32_t lookupWatts(int cad, int32_t targetPosition, PTData& ptData); int32_t extrapolateCadenceWatts(int cad, float targetPosition, PTData& ptData); int extrapolateWattsFromCadence(int cad, int32_t targetPosition, PTData& ptData); diff --git a/src/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp index 9469c63e..c15868e9 100644 --- a/src/PowerTable_Helpers.cpp +++ b/src/PowerTable_Helpers.cpp @@ -307,6 +307,7 @@ int32_t PTHelpers::lookup(int watts, int cad, PTData& ptData) { /** * @brief Extrapolates and fills empty indices in a power table row or column using cubic spline interpolation and neighbor blending. + * returns false if the operation takes too long. * * This function takes a set of empty indices within a row or column of a power table and attempts to extrapolate their values * based on existing (x, y) data points using cubic spline interpolation. The extrapolated value is then blended with nearby @@ -322,8 +323,10 @@ int32_t PTHelpers::lookup(int watts, int cad, PTData& ptData) { * @param naturalSpline If true, use a natural cubic spline for interpolation (currently unused in this function). * @param ptData Reference to the power table data structure to be updated with extrapolated values. */ -void PTHelpers::extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, std::pair, std::vector> xy, size_t n, bool horizontal, +bool PTHelpers::extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, std::pair, std::vector> xy, size_t n, bool horizontal, bool naturalSpline, PTData& ptData) { + + unsigned long timeout = millis() + COMPUTATION_TIMEOUT_MS; // Set timeout for computation ptIndex index; if (n >= 3) { bool validForSpline = true; @@ -335,7 +338,7 @@ void PTHelpers::extrapolateEmptyIndices(int outerIndex, const std::vector& } if (!validForSpline) { SS2K_LOG(PTDATA_LOG_TAG, "Duplicate or non-increasing x-values detected!"); - return; + return true; } CubicSpline spline; @@ -396,9 +399,14 @@ void PTHelpers::extrapolateEmptyIndices(int outerIndex, const std::vector& } ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition = static_cast(round(blendedValue)); + if( millis() > timeout) { + SS2K_LOG(PTDATA_LOG_TAG, "Spline fill operation timed out!"); + return false; // Exit if computation takes too long + } } } } + return true; } /** @@ -414,7 +422,8 @@ void PTHelpers::extrapolateEmptyIndices(int outerIndex, const std::vector& * @param firstHalf (optional) If true, processes the first half (with overlap); otherwise, processes the second half. Default is true. * @param horizontal (optional) If true, fills across watt indices (rows); if false, fills across cadence indices (columns). Default is true. */ -void PTHelpers::splineFill(PTData& ptData, bool firstHalf /*= true*/, bool horizontal /*= true*/) { +bool PTHelpers::splineFill(PTData& ptData, bool firstHalf /*= true*/, bool horizontal /*= true*/) { + bool completedWithoutTimeout = true;; int outerSize = horizontal ? POWERTABLE_CAD_SIZE : POWERTABLE_WATT_SIZE; int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; @@ -482,10 +491,13 @@ void PTHelpers::splineFill(PTData& ptData, bool firstHalf /*= true*/, bool horiz bool useNaturalSpline = spline.shouldUseNaturalSpline(std::make_pair(x, y), x.size()); // Fill empty table entries using the determined spline type - extrapolateEmptyIndices(currentOuterIndex, emptyIndices, std::make_pair(x, y), x.size(), horizontal, useNaturalSpline, ptData); + completedWithoutTimeout = extrapolateEmptyIndices(currentOuterIndex, emptyIndices, std::make_pair(x, y), x.size(), horizontal, useNaturalSpline, ptData); }; for (int k = 0; k <= max_k_outer; ++k) { + if(!completedWithoutTimeout) { + return false; // Exit if computation takes too long + } int outer_upper = mid_outer + k; if (outer_upper < outerSize) { processOuterIndex(outer_upper); @@ -498,6 +510,7 @@ void PTHelpers::splineFill(PTData& ptData, bool firstHalf /*= true*/, bool horiz } } } + return completedWithoutTimeout; // Return true if all operations completed without timeout } /** @@ -545,7 +558,7 @@ float PTHelpers::linearExtrapolate(std::pair, std::vector Date: Sun, 22 Jun 2025 14:14:43 -0700 Subject: [PATCH 244/451] updated gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e26072d6..c699adda 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ build/CMakeCache.txt .env C/Users/ build/CMakeFiles/cmake.check_cache +/managed_components From 0e44a553a085999dc052e705ac2c9298a5e94106 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sun, 22 Jun 2025 15:09:24 -0700 Subject: [PATCH 245/451] initial test build --- .gitignore | 2 +- .vscode/settings.json | 2 + CMakeLists.txt | 7 + dependencies.lock | 90 ++ min_spiffs.csv | 6 + platformio.ini | 46 +- sdkconfig | 2103 ++++++++++++++++++++++++++++++++++ sdkconfig.defaults | 6 + sdkconfig.old | 2103 ++++++++++++++++++++++++++++++++++ sdkconfig.release | 2548 +++++++++++++++++++++++++++++++++++++++++ sdkconfig.release.old | 2197 +++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 6 + src/Main.cpp | 4 +- src/SS2KLog.cpp | 10 +- 14 files changed, 9107 insertions(+), 23 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 dependencies.lock create mode 100644 min_spiffs.csv create mode 100644 sdkconfig create mode 100644 sdkconfig.defaults create mode 100644 sdkconfig.old create mode 100644 sdkconfig.release create mode 100644 sdkconfig.release.old create mode 100644 src/CMakeLists.txt diff --git a/.gitignore b/.gitignore index c699adda..7795ffea 100644 --- a/.gitignore +++ b/.gitignore @@ -18,5 +18,5 @@ build/CMakeCache.txt .aider* .env C/Users/ -build/CMakeFiles/cmake.check_cache +/build /managed_components diff --git a/.vscode/settings.json b/.vscode/settings.json index 287233fe..2888d84a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -119,4 +119,6 @@ "VERSIONFILE", "WEBSERVER" ], + "idf.pythonInstallPath": "/opt/homebrew/bin/python3", + "idf.flashType": "UART", } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..9a5f975e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.16.0) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(SmartSpin2k) +include_directories( + ${PROJECT_SOURCE_DIR}/include + ${PROJECT_SOURCE_DIR}/src +) \ No newline at end of file diff --git a/dependencies.lock b/dependencies.lock new file mode 100644 index 00000000..3aef0ca5 --- /dev/null +++ b/dependencies.lock @@ -0,0 +1,90 @@ +dependencies: + chmorgan/esp-libhelix-mp3: + component_hash: cbb76089dc2c5749f7b470e2e70aedc44c9da519e04eb9a67d4c7ec275229e53 + dependencies: + - name: idf + registry_url: https://components.espressif.com + require: private + version: '>=4.1.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.0.3 + espressif/cbor: + component_hash: 440f4ee4504841cc9b4f3a8ef755776a612ac9dace355514c68b999868f990ff + dependencies: + - name: idf + registry_url: https://components.espressif.com + require: private + version: '>=4.3' + source: + registry_url: https://components.espressif.com/ + type: service + version: 0.6.0~1 + espressif/esp-zboss-lib: + component_hash: 2a2256a8d20e5ade59a8e084760c84faa87dc9332523afcb6e245a744420839a + dependencies: + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.6.3 + espressif/esp-zigbee-lib: + component_hash: 73112d38839c7460bd713f9e3a5b2baeab351ee01a4b9091c7df8b50ce524947 + dependencies: + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.6.3 + espressif/mdns: + component_hash: 3ec0af5f6bce310512e90f482388d21cc7c0e99668172d2f895356165fc6f7c5 + dependencies: + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.8.2 + espressif/network_provisioning: + component_hash: ef2e10182fd1861e68b821491916327c25416ca7ae70e5a6e43313dbc71fe993 + dependencies: + - name: idf + registry_url: https://components.espressif.com + require: private + version: '>=5.1' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.0.2 + idf: + source: + type: idf + version: 5.4.1 + joltwallet/littlefs: + component_hash: fe3d04a59a4c370408b0e0b69d9096c06371b9ee12ad8e06b9d52ac63ab1570c + dependencies: + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.20.0 +direct_dependencies: +- chmorgan/esp-libhelix-mp3 +- espressif/cbor +- espressif/esp-zboss-lib +- espressif/esp-zigbee-lib +- espressif/mdns +- espressif/network_provisioning +- idf +- joltwallet/littlefs +manifest_hash: cdea08c215af25ecb07f34a572afe529ccee1d11a022752ebfb3b54cbc0cb5f8 +target: esp32 +version: 2.0.0 diff --git a/min_spiffs.csv b/min_spiffs.csv new file mode 100644 index 00000000..311b5403 --- /dev/null +++ b/min_spiffs.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x1E0000, +app1, app, ota_1, 0x1F0000,0x1E0000, +spiffs, data, spiffs, 0x3D0000,0x30000, \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 879e1916..cf55353b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,15 +13,37 @@ default_envs = release [esp32doit] lib_ldf_mode = chain lib_compat_mode = strict -;platform = https://github.com/pioarduino/platform-espressif32/releases/download/54.03.20/platform-espressif32.zip -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/54.03.20/platform-espressif32.zip +;platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10/platform-espressif32.zip +;platform = espressif32 +;platform_packages = +; framework-espidf @ https://github.com/espressif/esp-idf/releases/download/v5.3.2/esp-idf-v5.3.2.zip board = esp32doit-devkit-v1 -framework = arduino +framework = arduino, espidf board_build.partitions = min_spiffs.csv board_build.filesystem = littlefs upload_speed = 921600 monitor_speed = 115200 monitor_filters = esp32_exception_decoder +board_build.embed_txtfiles = + ;managed_components/espressif__esp_insights/server_certs/https_server.crt + ;managed_components/espressif__esp_rainmaker/server_certs/rmaker_mqtt_server.crt + ;managed_components/espressif__esp_rainmaker/server_certs/rmaker_claim_service_server.crt + ;managed_components/espressif__esp_rainmaker/server_certs/rmaker_ota_server.crt +custom_component_remove = + espressif/esp_hosted + espressif/esp_wifi_remote + espressif/esp-dsp + espressif/esp32-camera + espressif/libsodium + espressif/esp-modbus + espressif/qrcode + espressif/esp_insights + espressif/esp_diag_data_store + espressif/esp_diagnostics + espressif/esp_rainmaker + espressif/zigbee + espressif/rmaker_common build_flags = !python git_tag_macro.py !python build_date_macro.py @@ -31,27 +53,27 @@ build_flags = ;-D CONFIG_NEWLIB_NANO_FORMAT=y ;-D CONFIG_LWIP_IRAM_OPTIMIZATION=y ;-D CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM=y - -D CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 - -D CONFIG_BT_NIMBLE_WHITELIST_SIZE=0 - -D CONFIG_MDNS_STRICT_MODE=1 - -D CORE_DEBUG_LEVEL=1 + ;-D CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 + ;-D CONFIG_BT_NIMBLE_WHITELIST_SIZE=0 + ;-D CONFIG_MDNS_STRICT_MODE=1 + ;-D CORE_DEBUG_LEVEL=1 -D ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=3500 ;-D CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=8000 - -D CONFIG_BT_NIMBLE_MAX_CCCDS=0 - -D CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=1 + ;-D CONFIG_BT_NIMBLE_MAX_CCCDS=0 + ;-D CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=1 ;-D CONFIG_NIMBLE_STACK_USE_MEM_POOLS=1 - -D CONFIG_BT_NIMBLE_MAX_BONDS=1 + ;-D CONFIG_BT_NIMBLE_MAX_BONDS=1 ;-D CONFIG_BT_NIMBLE_BLOCK_COUNT=20 -std=gnu++17 lib_deps = - ;https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/2.3.0.zip + https://github.com/h2zero/esp-nimble-cpp/ https://github.com/teemuatlut/TMCStepper/archive/refs/tags/v0.7.3.zip https://github.com/bblanchon/ArduinoJson/archive/refs/tags/v7.3.1.zip ;https://github.com/gin66/FastAccelStepper/archive/refs/tags/0.31.2.zip https://github.com/doudar/FastAccelStepper/ https://github.com/gilmaimon/ArduinoWebsockets/archive/refs/tags/0.5.4.zip ;https://github.com/Links2004/arduinoWebSockets - https://github.com/doudar/NimBLE-Arduino/ + ;https://github.com/doudar/NimBLE-Arduino/ [env:release] extends = esp32doit diff --git a/sdkconfig b/sdkconfig new file mode 100644 index 00000000..1287da4d --- /dev/null +++ b/sdkconfig @@ -0,0 +1,2103 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) 5.4.1 Project Configuration +# +CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined" +CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined" +CONFIG_SOC_DPORT_WORKAROUND="Not determined" +CONFIG_SOC_CAPS_ECO_VER_MAX=301 +CONFIG_SOC_ADC_SUPPORTED=y +CONFIG_SOC_DAC_SUPPORTED=y +CONFIG_SOC_UART_SUPPORTED=y +CONFIG_SOC_MCPWM_SUPPORTED=y +CONFIG_SOC_GPTIMER_SUPPORTED=y +CONFIG_SOC_SDMMC_HOST_SUPPORTED=y +CONFIG_SOC_BT_SUPPORTED=y +CONFIG_SOC_PCNT_SUPPORTED=y +CONFIG_SOC_PHY_SUPPORTED=y +CONFIG_SOC_WIFI_SUPPORTED=y +CONFIG_SOC_SDIO_SLAVE_SUPPORTED=y +CONFIG_SOC_TWAI_SUPPORTED=y +CONFIG_SOC_EFUSE_SUPPORTED=y +CONFIG_SOC_EMAC_SUPPORTED=y +CONFIG_SOC_ULP_SUPPORTED=y +CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y +CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y +CONFIG_SOC_RTC_MEM_SUPPORTED=y +CONFIG_SOC_I2S_SUPPORTED=y +CONFIG_SOC_RMT_SUPPORTED=y +CONFIG_SOC_SDM_SUPPORTED=y +CONFIG_SOC_GPSPI_SUPPORTED=y +CONFIG_SOC_LEDC_SUPPORTED=y +CONFIG_SOC_I2C_SUPPORTED=y +CONFIG_SOC_SUPPORT_COEXISTENCE=y +CONFIG_SOC_AES_SUPPORTED=y +CONFIG_SOC_MPI_SUPPORTED=y +CONFIG_SOC_SHA_SUPPORTED=y +CONFIG_SOC_FLASH_ENC_SUPPORTED=y +CONFIG_SOC_SECURE_BOOT_SUPPORTED=y +CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y +CONFIG_SOC_BOD_SUPPORTED=y +CONFIG_SOC_ULP_FSM_SUPPORTED=y +CONFIG_SOC_CLK_TREE_SUPPORTED=y +CONFIG_SOC_MPU_SUPPORTED=y +CONFIG_SOC_WDT_SUPPORTED=y +CONFIG_SOC_SPI_FLASH_SUPPORTED=y +CONFIG_SOC_RNG_SUPPORTED=y +CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y +CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y +CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y +CONFIG_SOC_PM_SUPPORTED=y +CONFIG_SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL=5 +CONFIG_SOC_XTAL_SUPPORT_26M=y +CONFIG_SOC_XTAL_SUPPORT_40M=y +CONFIG_SOC_XTAL_SUPPORT_AUTO_DETECT=y +CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DMA_SUPPORTED=y +CONFIG_SOC_ADC_PERIPH_NUM=2 +CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 +CONFIG_SOC_ADC_ATTEN_NUM=4 +CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 +CONFIG_SOC_ADC_PATT_LEN_MAX=16 +CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 +CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=4 +CONFIG_SOC_ADC_DIGI_MONITOR_NUM=0 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=2 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=20 +CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_SHARED_POWER=y +CONFIG_SOC_SHARED_IDCACHE_SUPPORTED=y +CONFIG_SOC_IDCACHE_PER_CORE=y +CONFIG_SOC_CPU_CORES_NUM=2 +CONFIG_SOC_CPU_INTR_NUM=32 +CONFIG_SOC_CPU_HAS_FPU=y +CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y +CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 +CONFIG_SOC_DAC_CHAN_NUM=2 +CONFIG_SOC_DAC_RESOLUTION=8 +CONFIG_SOC_DAC_DMA_16BIT_ALIGN=y +CONFIG_SOC_GPIO_PORT=1 +CONFIG_SOC_GPIO_PIN_COUNT=40 +CONFIG_SOC_GPIO_VALID_GPIO_MASK=0xFFFFFFFFFF +CONFIG_SOC_GPIO_IN_RANGE_MAX=39 +CONFIG_SOC_GPIO_OUT_RANGE_MAX=33 +CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0xEF0FEA +CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y +CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3 +CONFIG_SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP=y +CONFIG_SOC_I2C_NUM=2 +CONFIG_SOC_HP_I2C_NUM=2 +CONFIG_SOC_I2C_FIFO_LEN=32 +CONFIG_SOC_I2C_CMD_REG_NUM=16 +CONFIG_SOC_I2C_SUPPORT_SLAVE=y +CONFIG_SOC_I2C_SUPPORT_APB=y +CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR=y +CONFIG_SOC_I2C_STOP_INDEPENDENT=y +CONFIG_SOC_I2S_NUM=2 +CONFIG_SOC_I2S_HW_VERSION_1=y +CONFIG_SOC_I2S_SUPPORTS_APLL=y +CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y +CONFIG_SOC_I2S_SUPPORTS_PDM=y +CONFIG_SOC_I2S_SUPPORTS_PDM_TX=y +CONFIG_SOC_I2S_PDM_MAX_TX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_PDM_RX=y +CONFIG_SOC_I2S_PDM_MAX_RX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_ADC_DAC=y +CONFIG_SOC_I2S_SUPPORTS_ADC=y +CONFIG_SOC_I2S_SUPPORTS_DAC=y +CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y +CONFIG_SOC_I2S_MAX_DATA_WIDTH=24 +CONFIG_SOC_I2S_TRANS_SIZE_ALIGN_WORD=y +CONFIG_SOC_I2S_LCD_I80_VARIANT=y +CONFIG_SOC_LCD_I80_SUPPORTED=y +CONFIG_SOC_LCD_I80_BUSES=2 +CONFIG_SOC_LCD_I80_BUS_WIDTH=24 +CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y +CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y +CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y +CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y +CONFIG_SOC_LEDC_TIMER_NUM=4 +CONFIG_SOC_LEDC_CHANNEL_NUM=8 +CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=20 +CONFIG_SOC_MCPWM_GROUPS=2 +CONFIG_SOC_MCPWM_TIMERS_PER_GROUP=3 +CONFIG_SOC_MCPWM_OPERATORS_PER_GROUP=3 +CONFIG_SOC_MCPWM_COMPARATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GENERATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_TRIGGERS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GPIO_FAULTS_PER_GROUP=3 +CONFIG_SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP=y +CONFIG_SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER=3 +CONFIG_SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP=3 +CONFIG_SOC_MMU_PERIPH_NUM=2 +CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=3 +CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 +CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 +CONFIG_SOC_PCNT_GROUPS=1 +CONFIG_SOC_PCNT_UNITS_PER_GROUP=8 +CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 +CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 +CONFIG_SOC_RMT_GROUPS=1 +CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_CHANNELS_PER_GROUP=8 +CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 +CONFIG_SOC_RMT_SUPPORT_REF_TICK=y +CONFIG_SOC_RMT_SUPPORT_APB=y +CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y +CONFIG_SOC_RTCIO_PIN_COUNT=18 +CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y +CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y +CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_SDM_GROUPS=1 +CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 +CONFIG_SOC_SDM_CLK_SUPPORT_APB=y +CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y +CONFIG_SOC_SPI_AS_CS_SUPPORTED=y +CONFIG_SOC_SPI_PERIPH_NUM=3 +CONFIG_SOC_SPI_DMA_CHAN_NUM=2 +CONFIG_SOC_SPI_MAX_CS_NUM=3 +CONFIG_SOC_SPI_SUPPORT_CLK_APB=y +CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=64 +CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 +CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y +CONFIG_SOC_TIMER_GROUPS=2 +CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 +CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 +CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y +CONFIG_SOC_LP_TIMER_BIT_WIDTH_LO=32 +CONFIG_SOC_LP_TIMER_BIT_WIDTH_HI=16 +CONFIG_SOC_TOUCH_SENSOR_VERSION=1 +CONFIG_SOC_TOUCH_SENSOR_NUM=10 +CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1 +CONFIG_SOC_TWAI_CONTROLLER_NUM=1 +CONFIG_SOC_TWAI_BRP_MIN=2 +CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y +CONFIG_SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT=y +CONFIG_SOC_UART_NUM=3 +CONFIG_SOC_UART_HP_NUM=3 +CONFIG_SOC_UART_SUPPORT_APB_CLK=y +CONFIG_SOC_UART_SUPPORT_REF_TICK=y +CONFIG_SOC_UART_FIFO_LEN=128 +CONFIG_SOC_UART_BITRATE_MAX=5000000 +CONFIG_SOC_SPIRAM_SUPPORTED=y +CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y +CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG=y +CONFIG_SOC_SHA_ENDIANNESS_BE=y +CONFIG_SOC_SHA_SUPPORT_SHA1=y +CONFIG_SOC_SHA_SUPPORT_SHA256=y +CONFIG_SOC_SHA_SUPPORT_SHA384=y +CONFIG_SOC_SHA_SUPPORT_SHA512=y +CONFIG_SOC_MPI_MEM_BLOCKS_NUM=4 +CONFIG_SOC_MPI_OPERATIONS_NUM=y +CONFIG_SOC_RSA_MAX_BIT_LEN=4096 +CONFIG_SOC_AES_SUPPORT_AES_128=y +CONFIG_SOC_AES_SUPPORT_AES_192=y +CONFIG_SOC_AES_SUPPORT_AES_256=y +CONFIG_SOC_SECURE_BOOT_V1=y +CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=y +CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=32 +CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 +CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y +CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y +CONFIG_SOC_PM_SUPPORT_MODEM_PD=y +CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y +CONFIG_SOC_PM_MODEM_PD_BY_SW=y +CONFIG_SOC_CLK_APLL_SUPPORTED=y +CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y +CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y +CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y +CONFIG_SOC_SDMMC_USE_IOMUX=y +CONFIG_SOC_SDMMC_NUM_SLOTS=2 +CONFIG_SOC_WIFI_WAPI_SUPPORT=y +CONFIG_SOC_WIFI_CSI_SUPPORT=y +CONFIG_SOC_WIFI_MESH_SUPPORT=y +CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y +CONFIG_SOC_WIFI_NAN_SUPPORT=y +CONFIG_SOC_BLE_SUPPORTED=y +CONFIG_SOC_BLE_MESH_SUPPORTED=y +CONFIG_SOC_BT_CLASSIC_SUPPORTED=y +CONFIG_SOC_BLUFI_SUPPORTED=y +CONFIG_SOC_BT_H2C_ENC_KEY_CTRL_ENH_VSC_SUPPORTED=y +CONFIG_SOC_ULP_HAS_ADC=y +CONFIG_SOC_PHY_COMBO_MODULE=y +CONFIG_SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK=y +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TOOLCHAIN="gcc" +CONFIG_IDF_TOOLCHAIN_GCC=y +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET_ARCH="xtensa" +CONFIG_IDF_TARGET="esp32" +CONFIG_IDF_INIT_VERSION="5.4.1" +CONFIG_IDF_TARGET_ESP32=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# CONFIG_APP_REPRODUCIBLE_BUILD is not set +# CONFIG_APP_NO_BLOBS is not set +# CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# end of Build type + +# +# Bootloader config +# + +# +# Bootloader manager +# +CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y +CONFIG_BOOTLOADER_PROJECT_VER=1 +# end of Bootloader manager + +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set + +# +# Log +# +# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=3 + +# +# Format +# +# CONFIG_BOOTLOADER_LOG_COLORS is not set +CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y +# end of Format +# end of Log + +# +# Serial Flash Configurations +# +# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +# end of Serial Flash Configurations + +# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_V1_SUPPORTED=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +# end of Security features + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 +# end of Application manager + +CONFIG_ESP_ROM_HAS_CRC_LE=y +CONFIG_ESP_ROM_HAS_CRC_BE=y +CONFIG_ESP_ROM_HAS_MZ_CRC32=y +CONFIG_ESP_ROM_HAS_JPEG_DECODE=y +CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y +CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y +CONFIG_ESP_ROM_HAS_NEWLIB=y +CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y +CONFIG_ESP_ROM_HAS_NEWLIB_32BIT_TIME=y +CONFIG_ESP_ROM_HAS_SW_FLOAT=y +CONFIG_ESP_ROM_USB_OTG_NUM=-1 +CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1 +CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y +CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y + +# +# Serial flasher config +# +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHMODE="dio" +# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="40m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set +# CONFIG_PARTITION_TABLE_CUSTOM is not set +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Compiler options +# +CONFIG_COMPILER_OPTIMIZATION_DEBUG=y +# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set +# CONFIG_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y +CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set +CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y +# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +CONFIG_COMPILER_RT_LIB_GCCLIB=y +CONFIG_COMPILER_RT_LIB_NAME="gcc" +CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y +# CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set +# CONFIG_COMPILER_STATIC_ANALYZER is not set +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_JTAG is not set +CONFIG_APPTRACE_DEST_NONE=y +# CONFIG_APPTRACE_DEST_UART1 is not set +# CONFIG_APPTRACE_DEST_UART2 is not set +CONFIG_APPTRACE_DEST_UART_NONE=y +CONFIG_APPTRACE_UART_TASK_PRIO=1 +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# Bluetooth +# +# CONFIG_BT_ENABLED is not set +CONFIG_BT_ALARM_MAX_NUM=50 +# end of Bluetooth + +# +# Console Library +# +# CONFIG_CONSOLE_SORTED_HELP is not set +# end of Console Library + +# +# Driver Configurations +# + +# +# TWAI Configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y +CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y +CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID=y +CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT=y +CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y +# end of TWAI Configuration + +# +# Legacy ADC Driver Configuration +# +CONFIG_ADC_DISABLE_DAC=y +# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set + +# +# Legacy ADC Calibration Configuration +# +CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y +CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CAL_LUT_ENABLE=y +# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy ADC Calibration Configuration +# end of Legacy ADC Driver Configuration + +# +# Legacy DAC Driver Configurations +# +# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy DAC Driver Configurations + +# +# Legacy MCPWM Driver Configurations +# +# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy MCPWM Driver Configurations + +# +# Legacy Timer Group Driver Configurations +# +# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy Timer Group Driver Configurations + +# +# Legacy RMT Driver Configurations +# +# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy RMT Driver Configurations + +# +# Legacy I2S Driver Configurations +# +# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy I2S Driver Configurations + +# +# Legacy PCNT Driver Configurations +# +# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy PCNT Driver Configurations + +# +# Legacy SDM Driver Configurations +# +# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy SDM Driver Configurations +# end of Driver Configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set +CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set +CONFIG_EFUSE_MAX_BLK_LEN=192 +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +# CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set +# CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + +# +# ADC and ADC Calibration +# +# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set + +# +# ADC Calibration Configurations +# +CONFIG_ADC_CALI_EFUSE_TP_ENABLE=y +CONFIG_ADC_CALI_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CALI_LUT_ENABLE=y +# end of ADC Calibration Configurations + +CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# CONFIG_ADC_ENABLE_DEBUG_LOG is not set +# end of ADC and ADC Calibration + +# +# Wireless Coexistence +# +CONFIG_ESP_COEX_ENABLED=y +# CONFIG_ESP_COEX_GPIO_DEBUG is not set +# end of Wireless Coexistence + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# end of Common ESP-related + +# +# ESP-Driver:DAC Configurations +# +# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# CONFIG_DAC_ISR_IRAM_SAFE is not set +# CONFIG_DAC_ENABLE_DEBUG_LOG is not set +CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y +# end of ESP-Driver:DAC Configurations + +# +# ESP-Driver:GPIO Configurations +# +# CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set +# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:GPIO Configurations + +# +# ESP-Driver:GPTimer Configurations +# +CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y +# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:GPTimer Configurations + +# +# ESP-Driver:I2C Configurations +# +# CONFIG_I2C_ISR_IRAM_SAFE is not set +# CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set +# end of ESP-Driver:I2C Configurations + +# +# ESP-Driver:I2S Configurations +# +# CONFIG_I2S_ISR_IRAM_SAFE is not set +# CONFIG_I2S_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:I2S Configurations + +# +# ESP-Driver:LEDC Configurations +# +# CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:LEDC Configurations + +# +# ESP-Driver:MCPWM Configurations +# +# CONFIG_MCPWM_ISR_IRAM_SAFE is not set +# CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:MCPWM Configurations + +# +# ESP-Driver:PCNT Configurations +# +# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_PCNT_ISR_IRAM_SAFE is not set +# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:PCNT Configurations + +# +# ESP-Driver:RMT Configurations +# +# CONFIG_RMT_ISR_IRAM_SAFE is not set +# CONFIG_RMT_RECV_FUNC_IN_IRAM is not set +# CONFIG_RMT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:RMT Configurations + +# +# ESP-Driver:Sigma Delta Modulator Configurations +# +# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_SDM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Sigma Delta Modulator Configurations + +# +# ESP-Driver:SPI Configurations +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of ESP-Driver:SPI Configurations + +# +# ESP-Driver:Touch Sensor Configurations +# +# CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set +# CONFIG_TOUCH_ISR_IRAM_SAFE is not set +# CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Touch Sensor Configurations + +# +# ESP-Driver:UART Configurations +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of ESP-Driver:UART Configurations + +# +# Ethernet +# +CONFIG_ETH_ENABLED=y +CONFIG_ETH_USE_ESP32_EMAC=y +CONFIG_ETH_PHY_INTERFACE_RMII=y +CONFIG_ETH_RMII_CLK_INPUT=y +# CONFIG_ETH_RMII_CLK_OUTPUT is not set +CONFIG_ETH_RMII_CLK_IN_GPIO=0 +CONFIG_ETH_DMA_BUFFER_SIZE=512 +CONFIG_ETH_DMA_RX_BUFFER_NUM=10 +CONFIG_ETH_DMA_TX_BUFFER_NUM=10 +# CONFIG_ETH_IRAM_OPTIMIZATION is not set +CONFIG_ETH_USE_SPI_ETHERNET=y +# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set +# CONFIG_ETH_SPI_ETHERNET_W5500 is not set +# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set +# CONFIG_ETH_USE_OPENETH is not set +# CONFIG_ETH_TRANSMIT_MUTEX is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +CONFIG_ESP_GDBSTUB_ENABLED=y +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set +CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y +CONFIG_ESP_GDBSTUB_MAX_TASKS=32 +# end of GDB Stub + +# +# ESP HID +# +CONFIG_ESPHID_TASK_SIZE_BT=2048 +CONFIG_ESPHID_TASK_SIZE_BLE=4096 +# end of ESP HID + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set +CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 +# end of ESP HTTPS server + +# +# Hardware Settings +# + +# +# Chip revision +# +CONFIG_ESP32_REV_MIN_0=y +# CONFIG_ESP32_REV_MIN_1 is not set +# CONFIG_ESP32_REV_MIN_1_1 is not set +# CONFIG_ESP32_REV_MIN_2 is not set +# CONFIG_ESP32_REV_MIN_3 is not set +# CONFIG_ESP32_REV_MIN_3_1 is not set +CONFIG_ESP32_REV_MIN=0 +CONFIG_ESP32_REV_MIN_FULL=0 +CONFIG_ESP_REV_MIN_FULL=0 + +# +# Maximum Supported ESP32 Revision (Rev v3.99) +# +CONFIG_ESP32_REV_MAX_FULL=399 +CONFIG_ESP_REV_MAX_FULL=399 +CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL=0 +CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL=99 + +# +# Maximum Supported ESP32 eFuse Block Revision (eFuse Block Rev v0.99) +# +# end of Chip revision + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set +# CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set +# end of MAC Config + +# +# Sleep Config +# +# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set +CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +# CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set +CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set +CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 +# CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set +# CONFIG_ESP_SLEEP_DEBUG is not set +CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y +# end of Sleep Config + +# +# RTC Clock Config +# +CONFIG_RTC_CLK_SRC_INT_RC=y +# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_RTC_CLK_CAL_CYCLES=1024 +# end of RTC Clock Config + +# +# Peripheral Control +# +CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y +# end of Peripheral Control + +# +# Main XTAL Config +# +# CONFIG_XTAL_FREQ_26 is not set +# CONFIG_XTAL_FREQ_32 is not set +CONFIG_XTAL_FREQ_40=y +# CONFIG_XTAL_FREQ_AUTO is not set +CONFIG_XTAL_FREQ=40 +# end of Main XTAL Config + +CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y +# end of Hardware Settings + +# +# ESP-Driver:LCD Controller Configurations +# +# CONFIG_LCD_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:LCD Controller Configurations + +# +# ESP-MM: Memory Management Configurations +# +# end of ESP-MM: Memory Management Configurations + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +# CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y +# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# CONFIG_ESP_NETIF_L2_TAP is not set +# CONFIG_ESP_NETIF_BRIDGE_EN is not set +# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set +# end of ESP NETIF Adapter + +# +# Partition API Configuration +# +# end of Partition API Configuration + +# +# PHY +# +CONFIG_ESP_PHY_ENABLED=y +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set +# CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set +CONFIG_ESP_PHY_RF_CAL_PARTIAL=y +# CONFIG_ESP_PHY_RF_CAL_NONE is not set +# CONFIG_ESP_PHY_RF_CAL_FULL is not set +CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# CONFIG_ESP_PHY_RECORD_USED_TIME is not set +# end of PHY + +# +# Power Management +# +# CONFIG_PM_ENABLE is not set +# CONFIG_PM_SLP_IRAM_OPT is not set +# end of Power Management + +# +# ESP PSRAM +# +# CONFIG_SPIRAM is not set +# end of ESP PSRAM + +# +# ESP Ringbuf +# +# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set +# end of ESP Ringbuf + +# +# ESP Security Specific +# +# end of ESP Security Specific + +# +# ESP System Settings +# +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 + +# +# Memory +# +# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set + +# +# Non-backward compatible options +# +# CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set +# end of Non-backward compatible options +# end of Memory + +# +# Trace memory +# +# CONFIG_ESP32_TRAX is not set +CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 +# end of Trace memory + +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 + +# +# Memory protection +# +# end of Memory protection + +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 +CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set +# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_INT_WDT_CHECK_CPU1=y +CONFIG_ESP_TASK_WDT_EN=y +CONFIG_ESP_TASK_WDT_INIT=y +# CONFIG_ESP_TASK_WDT_PANIC is not set +CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP_DEBUG_OCDAWARE=y +# CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y + +# +# Brownout Detector +# +CONFIG_ESP_BROWNOUT_DET=y +CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_ESP_BROWNOUT_DET_LVL=0 +# end of Brownout Detector + +# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set +CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y +# end of ESP System Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y +CONFIG_ESP_IPC_ISR_ENABLE=y +# end of IPC (Inter-Processor Call) + +# +# ESP Timer (High Resolution Timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set +CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 +CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y +CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +CONFIG_ESP_TIMER_IMPL_TG0_LAC=y +# end of ESP Timer (High Resolution Timer) + +# +# Wi-Fi +# +CONFIG_ESP_WIFI_ENABLED=y +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 +CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 +# CONFIG_ESP_WIFI_CSI_ENABLED is not set +CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP_WIFI_TX_BA_WIN=6 +CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP_WIFI_RX_BA_WIN=6 +CONFIG_ESP_WIFI_NVS_ENABLED=y +CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP_WIFI_IRAM_OPT=y +# CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set +CONFIG_ESP_WIFI_RX_IRAM_OPT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP_WIFI_ENABLE_SAE_PK=y +CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 +CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 +CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 +CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y +CONFIG_ESP_WIFI_GMAC_SUPPORT=y +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set +CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# CONFIG_ESP_WIFI_NAN_ENABLE is not set +CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y +CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# CONFIG_ESP_WIFI_WAPI_PSK is not set +# CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# CONFIG_ESP_WIFI_11R_SUPPORT is not set +# CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set + +# +# WPS Configuration Options +# +# CONFIG_ESP_WIFI_WPS_STRICT is not set +# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set +# end of WPS Configuration Options + +# CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set +CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y +# CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set +# end of Wi-Fi + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +CONFIG_FATFS_VOLUME_COUNT=2 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +# CONFIG_FATFS_SECTOR_512 is not set +CONFIG_FATFS_SECTOR_4096=y +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_USE_STRFUNC_NONE=y +# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set +# CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# CONFIG_FATFS_IMMEDIATE_FSYNC is not set +# CONFIG_FATFS_USE_LABEL is not set +CONFIG_FATFS_LINK_LOCK=y +# end of FAT Filesystem support + +# +# FreeRTOS +# + +# +# Kernel +# +# CONFIG_FREERTOS_SMP is not set +# CONFIG_FREERTOS_UNICORE is not set +CONFIG_FREERTOS_HZ=1000 +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +# CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# CONFIG_FREERTOS_USE_TICK_HOOK is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_USE_TIMERS=y +CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set +CONFIG_FREERTOS_TIMER_TASK_NO_AFFINITY=y +CONFIG_FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set +# end of Kernel + +# +# Port +# +CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# CONFIG_FREERTOS_FPU_IN_ISR is not set +CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# end of Port + +# +# Extra +# +# end of Extra + +CONFIG_FREERTOS_PORT=y +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y +CONFIG_FREERTOS_NUMBER_OF_CORES=2 +# end of FreeRTOS + +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILENT is not set +# CONFIG_HAL_ASSERTION_ENABLE is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 +CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y +CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_USE_HOOKS is not set +# CONFIG_HEAP_TASK_TRACKING is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set +# end of Heap memory debugging + +# +# Log +# + +# +# Log Level +# +# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +CONFIG_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=3 +CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=3 + +# +# Level Settings +# +# CONFIG_LOG_MASTER_LEVEL is not set +CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y +# CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set +# CONFIG_LOG_TAG_LEVEL_IMPL_LINKED_LIST is not set +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_AND_LINKED_LIST=y +# CONFIG_LOG_TAG_LEVEL_CACHE_ARRAY is not set +CONFIG_LOG_TAG_LEVEL_CACHE_BINARY_MIN_HEAP=y +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 +# end of Level Settings +# end of Log Level + +# +# Format +# +# CONFIG_LOG_COLORS is not set +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Format +# end of Log + +# +# LWIP +# +CONFIG_LWIP_ENABLE=y +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# CONFIG_LWIP_NETIF_API is not set +CONFIG_LWIP_TCPIP_TASK_PRIO=18 +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_ND6=y +# CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# CONFIG_LWIP_SO_RCVBUF is not set +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP_DEFAULT_TTL=64 +CONFIG_LWIP_IP4_FRAG=y +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +# CONFIG_LWIP_IP6_REASSEMBLY is not set +CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_ESP_MLDV6_REPORT=y +CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set +# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 +CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 + +# +# DHCP server +# +CONFIG_LWIP_DHCPS=y +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y +CONFIG_LWIP_DHCPS_ADD_DNS=y +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV4=y +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5760 +CONFIG_LWIP_TCP_WND_DEFAULT=5760 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 +CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 +CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 +CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 +# CONFIG_LWIP_PPP_SUPPORT is not set +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +CONFIG_LWIP_SNTP_STARTUP_DELAY=y +CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 +# end of SNTP + +# +# DNS +# +CONFIG_LWIP_DNS_MAX_HOST_IP=1 +CONFIG_LWIP_DNS_MAX_SERVERS=3 +# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set +# CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set +# end of DNS + +CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y +# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set +CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y +# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set +# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_NONE=y +# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_CUSTOM is not set +# CONFIG_LWIP_HOOK_IP6_INPUT_NONE is not set +CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y +# CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set + +# +# mbedTLS v3.x related +# +# CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set +# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set +CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y +CONFIG_MBEDTLS_PKCS7_C=y +# end of mbedTLS v3.x related + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y +# CONFIG_MBEDTLS_SHA3_C is not set +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +CONFIG_MBEDTLS_PSK_MODES=y +CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y +CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y +# CONFIG_MBEDTLS_DHM_C is not set +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +CONFIG_MBEDTLS_ERROR_STRINGS=y +CONFIG_MBEDTLS_FS_IO=y +# end of mbedTLS + +# +# ESP-MQTT Configurations +# +CONFIG_MQTT_PROTOCOL_311=y +# CONFIG_MQTT_PROTOCOL_5 is not set +CONFIG_MQTT_TRANSPORT_SSL=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set +# end of Newlib + +# +# NVS +# +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set +# end of NVS + +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set + +# +# OpenThread Spinel +# +# CONFIG_OPENTHREAD_SPINEL_ONLY is not set +# end of OpenThread Spinel +# end of OpenThread + +# +# Protocomm +# +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_PATCH_VERSION=y +# end of Protocomm + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y +# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set +# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# MMU Config +# +CONFIG_MMU_PAGE_SIZE_64KB=y +CONFIG_MMU_PAGE_MODE="64KB" +CONFIG_MMU_PAGE_SIZE=0x10000 +# end of MMU Config + +# +# Main Flash configuration +# + +# +# SPI Flash behavior when brownout +# +CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y +CONFIG_SPI_FLASH_BROWNOUT_RESET=y +# end of SPI Flash behavior when brownout + +# +# Optional and Experimental Features (READ DOCS FIRST) +# + +# +# Features here require specific hardware (READ DOCS FIRST!) +# +CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 +# CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set +# end of Optional and Experimental Features (READ DOCS FIRST) +# end of Main Flash configuration + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y +CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +CONFIG_WS_TRANSPORT=y +CONFIG_WS_BUFFER_SIZE=1024 +# CONFIG_WS_DYNAMIC_BUFFER is not set +# end of Websocket +# end of TCP Transport + +# +# Ultra Low Power (ULP) Co-processor +# +# CONFIG_ULP_COPROC_ENABLED is not set + +# +# ULP Debugging Options +# +# end of ULP Debugging Options +# end of Ultra Low Power (ULP) Co-processor + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_64BIT is not set +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +# CONFIG_VFS_SELECT_IN_RAM is not set +CONFIG_VFS_SUPPORT_TERMIOS=y +CONFIG_VFS_MAX_COUNT=8 + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# end of Host File System I/O (Semihosting) + +CONFIG_VFS_INITIALIZE_DEV_NULL=y +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y +# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set +# end of Wi-Fi Provisioning Manager +# end of Component config + +# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set + +# Deprecated options for backward compatibility +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# CONFIG_NO_BLOBS is not set +# CONFIG_ESP32_NO_BLOBS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=3 +# CONFIG_APP_ROLLBACK_ENABLE is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +# CONFIG_FLASHMODE_QIO is not set +# CONFIG_FLASHMODE_QOUT is not set +CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DOUT is not set +CONFIG_MONITOR_BAUD=115200 +CONFIG_OPTIMIZATION_LEVEL_DEBUG=y +CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y +CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y +# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_ADC2_DISABLE_DAC=y +# CONFIG_MCPWM_ISR_IN_IRAM is not set +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +CONFIG_GDBSTUB_SUPPORT_TASKS=y +CONFIG_GDBSTUB_MAX_TASKS=32 +# CONFIG_OTA_ALLOW_HTTP is not set +# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set +CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y +CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 +# CONFIG_ESP_SYSTEM_PD_FLASH is not set +CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y +CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y +# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set +# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set +# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set +CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 +# CONFIG_ESP32_XTAL_FREQ_26 is not set +CONFIG_ESP32_XTAL_FREQ_40=y +# CONFIG_ESP32_XTAL_FREQ_AUTO is not set +CONFIG_ESP32_XTAL_FREQ=40 +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# CONFIG_REDUCE_PHY_TX_POWER is not set +# CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set +# CONFIG_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y +# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160 +CONFIG_TRACEMEM_RESERVE_DRAM=0x0 +# CONFIG_ESP32_PANIC_PRINT_HALT is not set +CONFIG_ESP32_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32_PANIC_GDBSTUB is not set +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=3584 +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_CONSOLE_UART_NONE is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +CONFIG_INT_WDT_CHECK_CPU1=y +CONFIG_TASK_WDT=y +CONFIG_ESP_TASK_WDT=y +# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_TIMEOUT_S=5 +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP32_DEBUG_OCDAWARE=y +CONFIG_BROWNOUT_DET=y +CONFIG_ESP32_BROWNOUT_DET=y +CONFIG_BROWNOUT_DET_LVL_SEL_0=y +CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_BROWNOUT_DET_LVL=0 +CONFIG_ESP32_BROWNOUT_DET_LVL=0 +# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set +CONFIG_IPC_TASK_STACK_SIZE=1024 +CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y +CONFIG_WPA_MBEDTLS_CRYPTO=y +CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# CONFIG_WPA_MBO_SUPPORT is not set +# CONFIG_WPA_DPP_SUPPORT is not set +# CONFIG_WPA_11R_SUPPORT is not set +# CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set +# CONFIG_L2_TO_L3_COPY is not set +CONFIG_ESP_GRATUITOUS_ARP=y +CONFIG_GARP_TMR_INTERVAL=60 +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5760 +CONFIG_TCP_WND_DEFAULT=5760 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_HRT is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +# CONFIG_ESP32_ULP_COPROC_ENABLED is not set +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# End of deprecated options diff --git a/sdkconfig.defaults b/sdkconfig.defaults new file mode 100644 index 00000000..d50929ea --- /dev/null +++ b/sdkconfig.defaults @@ -0,0 +1,6 @@ +CONFIG_AUTOSTART_ARDUINO=y +# CONFIG_WS2812_LED_ENABLE is not set +CONFIG_FREERTOS_HZ=1000 +CONFIG_MBEDTLS_PSK_MODES=y +CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y \ No newline at end of file diff --git a/sdkconfig.old b/sdkconfig.old new file mode 100644 index 00000000..07c9dd84 --- /dev/null +++ b/sdkconfig.old @@ -0,0 +1,2103 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) 5.4.1 Project Configuration +# +CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined" +CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined" +CONFIG_SOC_DPORT_WORKAROUND="Not determined" +CONFIG_SOC_CAPS_ECO_VER_MAX=301 +CONFIG_SOC_ADC_SUPPORTED=y +CONFIG_SOC_DAC_SUPPORTED=y +CONFIG_SOC_UART_SUPPORTED=y +CONFIG_SOC_MCPWM_SUPPORTED=y +CONFIG_SOC_GPTIMER_SUPPORTED=y +CONFIG_SOC_SDMMC_HOST_SUPPORTED=y +CONFIG_SOC_BT_SUPPORTED=y +CONFIG_SOC_PCNT_SUPPORTED=y +CONFIG_SOC_PHY_SUPPORTED=y +CONFIG_SOC_WIFI_SUPPORTED=y +CONFIG_SOC_SDIO_SLAVE_SUPPORTED=y +CONFIG_SOC_TWAI_SUPPORTED=y +CONFIG_SOC_EFUSE_SUPPORTED=y +CONFIG_SOC_EMAC_SUPPORTED=y +CONFIG_SOC_ULP_SUPPORTED=y +CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y +CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y +CONFIG_SOC_RTC_MEM_SUPPORTED=y +CONFIG_SOC_I2S_SUPPORTED=y +CONFIG_SOC_RMT_SUPPORTED=y +CONFIG_SOC_SDM_SUPPORTED=y +CONFIG_SOC_GPSPI_SUPPORTED=y +CONFIG_SOC_LEDC_SUPPORTED=y +CONFIG_SOC_I2C_SUPPORTED=y +CONFIG_SOC_SUPPORT_COEXISTENCE=y +CONFIG_SOC_AES_SUPPORTED=y +CONFIG_SOC_MPI_SUPPORTED=y +CONFIG_SOC_SHA_SUPPORTED=y +CONFIG_SOC_FLASH_ENC_SUPPORTED=y +CONFIG_SOC_SECURE_BOOT_SUPPORTED=y +CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y +CONFIG_SOC_BOD_SUPPORTED=y +CONFIG_SOC_ULP_FSM_SUPPORTED=y +CONFIG_SOC_CLK_TREE_SUPPORTED=y +CONFIG_SOC_MPU_SUPPORTED=y +CONFIG_SOC_WDT_SUPPORTED=y +CONFIG_SOC_SPI_FLASH_SUPPORTED=y +CONFIG_SOC_RNG_SUPPORTED=y +CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y +CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y +CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y +CONFIG_SOC_PM_SUPPORTED=y +CONFIG_SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL=5 +CONFIG_SOC_XTAL_SUPPORT_26M=y +CONFIG_SOC_XTAL_SUPPORT_40M=y +CONFIG_SOC_XTAL_SUPPORT_AUTO_DETECT=y +CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DMA_SUPPORTED=y +CONFIG_SOC_ADC_PERIPH_NUM=2 +CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 +CONFIG_SOC_ADC_ATTEN_NUM=4 +CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 +CONFIG_SOC_ADC_PATT_LEN_MAX=16 +CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 +CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=4 +CONFIG_SOC_ADC_DIGI_MONITOR_NUM=0 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=2 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=20 +CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_SHARED_POWER=y +CONFIG_SOC_SHARED_IDCACHE_SUPPORTED=y +CONFIG_SOC_IDCACHE_PER_CORE=y +CONFIG_SOC_CPU_CORES_NUM=2 +CONFIG_SOC_CPU_INTR_NUM=32 +CONFIG_SOC_CPU_HAS_FPU=y +CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y +CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 +CONFIG_SOC_DAC_CHAN_NUM=2 +CONFIG_SOC_DAC_RESOLUTION=8 +CONFIG_SOC_DAC_DMA_16BIT_ALIGN=y +CONFIG_SOC_GPIO_PORT=1 +CONFIG_SOC_GPIO_PIN_COUNT=40 +CONFIG_SOC_GPIO_VALID_GPIO_MASK=0xFFFFFFFFFF +CONFIG_SOC_GPIO_IN_RANGE_MAX=39 +CONFIG_SOC_GPIO_OUT_RANGE_MAX=33 +CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0xEF0FEA +CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y +CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3 +CONFIG_SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP=y +CONFIG_SOC_I2C_NUM=2 +CONFIG_SOC_HP_I2C_NUM=2 +CONFIG_SOC_I2C_FIFO_LEN=32 +CONFIG_SOC_I2C_CMD_REG_NUM=16 +CONFIG_SOC_I2C_SUPPORT_SLAVE=y +CONFIG_SOC_I2C_SUPPORT_APB=y +CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR=y +CONFIG_SOC_I2C_STOP_INDEPENDENT=y +CONFIG_SOC_I2S_NUM=2 +CONFIG_SOC_I2S_HW_VERSION_1=y +CONFIG_SOC_I2S_SUPPORTS_APLL=y +CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y +CONFIG_SOC_I2S_SUPPORTS_PDM=y +CONFIG_SOC_I2S_SUPPORTS_PDM_TX=y +CONFIG_SOC_I2S_PDM_MAX_TX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_PDM_RX=y +CONFIG_SOC_I2S_PDM_MAX_RX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_ADC_DAC=y +CONFIG_SOC_I2S_SUPPORTS_ADC=y +CONFIG_SOC_I2S_SUPPORTS_DAC=y +CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y +CONFIG_SOC_I2S_MAX_DATA_WIDTH=24 +CONFIG_SOC_I2S_TRANS_SIZE_ALIGN_WORD=y +CONFIG_SOC_I2S_LCD_I80_VARIANT=y +CONFIG_SOC_LCD_I80_SUPPORTED=y +CONFIG_SOC_LCD_I80_BUSES=2 +CONFIG_SOC_LCD_I80_BUS_WIDTH=24 +CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y +CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y +CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y +CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y +CONFIG_SOC_LEDC_TIMER_NUM=4 +CONFIG_SOC_LEDC_CHANNEL_NUM=8 +CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=20 +CONFIG_SOC_MCPWM_GROUPS=2 +CONFIG_SOC_MCPWM_TIMERS_PER_GROUP=3 +CONFIG_SOC_MCPWM_OPERATORS_PER_GROUP=3 +CONFIG_SOC_MCPWM_COMPARATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GENERATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_TRIGGERS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GPIO_FAULTS_PER_GROUP=3 +CONFIG_SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP=y +CONFIG_SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER=3 +CONFIG_SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP=3 +CONFIG_SOC_MMU_PERIPH_NUM=2 +CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=3 +CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 +CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 +CONFIG_SOC_PCNT_GROUPS=1 +CONFIG_SOC_PCNT_UNITS_PER_GROUP=8 +CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 +CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 +CONFIG_SOC_RMT_GROUPS=1 +CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_CHANNELS_PER_GROUP=8 +CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 +CONFIG_SOC_RMT_SUPPORT_REF_TICK=y +CONFIG_SOC_RMT_SUPPORT_APB=y +CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y +CONFIG_SOC_RTCIO_PIN_COUNT=18 +CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y +CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y +CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_SDM_GROUPS=1 +CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 +CONFIG_SOC_SDM_CLK_SUPPORT_APB=y +CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y +CONFIG_SOC_SPI_AS_CS_SUPPORTED=y +CONFIG_SOC_SPI_PERIPH_NUM=3 +CONFIG_SOC_SPI_DMA_CHAN_NUM=2 +CONFIG_SOC_SPI_MAX_CS_NUM=3 +CONFIG_SOC_SPI_SUPPORT_CLK_APB=y +CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=64 +CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 +CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y +CONFIG_SOC_TIMER_GROUPS=2 +CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 +CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 +CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y +CONFIG_SOC_LP_TIMER_BIT_WIDTH_LO=32 +CONFIG_SOC_LP_TIMER_BIT_WIDTH_HI=16 +CONFIG_SOC_TOUCH_SENSOR_VERSION=1 +CONFIG_SOC_TOUCH_SENSOR_NUM=10 +CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1 +CONFIG_SOC_TWAI_CONTROLLER_NUM=1 +CONFIG_SOC_TWAI_BRP_MIN=2 +CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y +CONFIG_SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT=y +CONFIG_SOC_UART_NUM=3 +CONFIG_SOC_UART_HP_NUM=3 +CONFIG_SOC_UART_SUPPORT_APB_CLK=y +CONFIG_SOC_UART_SUPPORT_REF_TICK=y +CONFIG_SOC_UART_FIFO_LEN=128 +CONFIG_SOC_UART_BITRATE_MAX=5000000 +CONFIG_SOC_SPIRAM_SUPPORTED=y +CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y +CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG=y +CONFIG_SOC_SHA_ENDIANNESS_BE=y +CONFIG_SOC_SHA_SUPPORT_SHA1=y +CONFIG_SOC_SHA_SUPPORT_SHA256=y +CONFIG_SOC_SHA_SUPPORT_SHA384=y +CONFIG_SOC_SHA_SUPPORT_SHA512=y +CONFIG_SOC_MPI_MEM_BLOCKS_NUM=4 +CONFIG_SOC_MPI_OPERATIONS_NUM=y +CONFIG_SOC_RSA_MAX_BIT_LEN=4096 +CONFIG_SOC_AES_SUPPORT_AES_128=y +CONFIG_SOC_AES_SUPPORT_AES_192=y +CONFIG_SOC_AES_SUPPORT_AES_256=y +CONFIG_SOC_SECURE_BOOT_V1=y +CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=y +CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=32 +CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 +CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y +CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y +CONFIG_SOC_PM_SUPPORT_MODEM_PD=y +CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y +CONFIG_SOC_PM_MODEM_PD_BY_SW=y +CONFIG_SOC_CLK_APLL_SUPPORTED=y +CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y +CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y +CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y +CONFIG_SOC_SDMMC_USE_IOMUX=y +CONFIG_SOC_SDMMC_NUM_SLOTS=2 +CONFIG_SOC_WIFI_WAPI_SUPPORT=y +CONFIG_SOC_WIFI_CSI_SUPPORT=y +CONFIG_SOC_WIFI_MESH_SUPPORT=y +CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y +CONFIG_SOC_WIFI_NAN_SUPPORT=y +CONFIG_SOC_BLE_SUPPORTED=y +CONFIG_SOC_BLE_MESH_SUPPORTED=y +CONFIG_SOC_BT_CLASSIC_SUPPORTED=y +CONFIG_SOC_BLUFI_SUPPORTED=y +CONFIG_SOC_BT_H2C_ENC_KEY_CTRL_ENH_VSC_SUPPORTED=y +CONFIG_SOC_ULP_HAS_ADC=y +CONFIG_SOC_PHY_COMBO_MODULE=y +CONFIG_SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK=y +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TOOLCHAIN="gcc" +CONFIG_IDF_TOOLCHAIN_GCC=y +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET_ARCH="xtensa" +CONFIG_IDF_TARGET="esp32" +CONFIG_IDF_INIT_VERSION="5.4.1" +CONFIG_IDF_TARGET_ESP32=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# CONFIG_APP_REPRODUCIBLE_BUILD is not set +# CONFIG_APP_NO_BLOBS is not set +# CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# end of Build type + +# +# Bootloader config +# + +# +# Bootloader manager +# +CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y +CONFIG_BOOTLOADER_PROJECT_VER=1 +# end of Bootloader manager + +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set + +# +# Log +# +# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=3 + +# +# Format +# +# CONFIG_BOOTLOADER_LOG_COLORS is not set +CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y +# end of Format +# end of Log + +# +# Serial Flash Configurations +# +# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +# end of Serial Flash Configurations + +# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_V1_SUPPORTED=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +# end of Security features + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 +# end of Application manager + +CONFIG_ESP_ROM_HAS_CRC_LE=y +CONFIG_ESP_ROM_HAS_CRC_BE=y +CONFIG_ESP_ROM_HAS_MZ_CRC32=y +CONFIG_ESP_ROM_HAS_JPEG_DECODE=y +CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y +CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y +CONFIG_ESP_ROM_HAS_NEWLIB=y +CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y +CONFIG_ESP_ROM_HAS_NEWLIB_32BIT_TIME=y +CONFIG_ESP_ROM_HAS_SW_FLOAT=y +CONFIG_ESP_ROM_USB_OTG_NUM=-1 +CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1 +CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y +CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y + +# +# Serial flasher config +# +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHMODE="dio" +# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="40m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="2MB" +# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set +# CONFIG_PARTITION_TABLE_CUSTOM is not set +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Compiler options +# +CONFIG_COMPILER_OPTIMIZATION_DEBUG=y +# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set +# CONFIG_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y +CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set +CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y +# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +CONFIG_COMPILER_RT_LIB_GCCLIB=y +CONFIG_COMPILER_RT_LIB_NAME="gcc" +CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y +# CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set +# CONFIG_COMPILER_STATIC_ANALYZER is not set +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_JTAG is not set +CONFIG_APPTRACE_DEST_NONE=y +# CONFIG_APPTRACE_DEST_UART1 is not set +# CONFIG_APPTRACE_DEST_UART2 is not set +CONFIG_APPTRACE_DEST_UART_NONE=y +CONFIG_APPTRACE_UART_TASK_PRIO=1 +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# Bluetooth +# +# CONFIG_BT_ENABLED is not set +CONFIG_BT_ALARM_MAX_NUM=50 +# end of Bluetooth + +# +# Console Library +# +# CONFIG_CONSOLE_SORTED_HELP is not set +# end of Console Library + +# +# Driver Configurations +# + +# +# TWAI Configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y +CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y +CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID=y +CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT=y +CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y +# end of TWAI Configuration + +# +# Legacy ADC Driver Configuration +# +CONFIG_ADC_DISABLE_DAC=y +# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set + +# +# Legacy ADC Calibration Configuration +# +CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y +CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CAL_LUT_ENABLE=y +# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy ADC Calibration Configuration +# end of Legacy ADC Driver Configuration + +# +# Legacy DAC Driver Configurations +# +# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy DAC Driver Configurations + +# +# Legacy MCPWM Driver Configurations +# +# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy MCPWM Driver Configurations + +# +# Legacy Timer Group Driver Configurations +# +# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy Timer Group Driver Configurations + +# +# Legacy RMT Driver Configurations +# +# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy RMT Driver Configurations + +# +# Legacy I2S Driver Configurations +# +# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy I2S Driver Configurations + +# +# Legacy PCNT Driver Configurations +# +# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy PCNT Driver Configurations + +# +# Legacy SDM Driver Configurations +# +# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy SDM Driver Configurations +# end of Driver Configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set +CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set +CONFIG_EFUSE_MAX_BLK_LEN=192 +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +# CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set +# CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + +# +# ADC and ADC Calibration +# +# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set + +# +# ADC Calibration Configurations +# +CONFIG_ADC_CALI_EFUSE_TP_ENABLE=y +CONFIG_ADC_CALI_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CALI_LUT_ENABLE=y +# end of ADC Calibration Configurations + +CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# CONFIG_ADC_ENABLE_DEBUG_LOG is not set +# end of ADC and ADC Calibration + +# +# Wireless Coexistence +# +CONFIG_ESP_COEX_ENABLED=y +# CONFIG_ESP_COEX_GPIO_DEBUG is not set +# end of Wireless Coexistence + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# end of Common ESP-related + +# +# ESP-Driver:DAC Configurations +# +# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# CONFIG_DAC_ISR_IRAM_SAFE is not set +# CONFIG_DAC_ENABLE_DEBUG_LOG is not set +CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y +# end of ESP-Driver:DAC Configurations + +# +# ESP-Driver:GPIO Configurations +# +# CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set +# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:GPIO Configurations + +# +# ESP-Driver:GPTimer Configurations +# +CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y +# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:GPTimer Configurations + +# +# ESP-Driver:I2C Configurations +# +# CONFIG_I2C_ISR_IRAM_SAFE is not set +# CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set +# end of ESP-Driver:I2C Configurations + +# +# ESP-Driver:I2S Configurations +# +# CONFIG_I2S_ISR_IRAM_SAFE is not set +# CONFIG_I2S_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:I2S Configurations + +# +# ESP-Driver:LEDC Configurations +# +# CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:LEDC Configurations + +# +# ESP-Driver:MCPWM Configurations +# +# CONFIG_MCPWM_ISR_IRAM_SAFE is not set +# CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:MCPWM Configurations + +# +# ESP-Driver:PCNT Configurations +# +# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_PCNT_ISR_IRAM_SAFE is not set +# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:PCNT Configurations + +# +# ESP-Driver:RMT Configurations +# +# CONFIG_RMT_ISR_IRAM_SAFE is not set +# CONFIG_RMT_RECV_FUNC_IN_IRAM is not set +# CONFIG_RMT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:RMT Configurations + +# +# ESP-Driver:Sigma Delta Modulator Configurations +# +# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_SDM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Sigma Delta Modulator Configurations + +# +# ESP-Driver:SPI Configurations +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of ESP-Driver:SPI Configurations + +# +# ESP-Driver:Touch Sensor Configurations +# +# CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set +# CONFIG_TOUCH_ISR_IRAM_SAFE is not set +# CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Touch Sensor Configurations + +# +# ESP-Driver:UART Configurations +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of ESP-Driver:UART Configurations + +# +# Ethernet +# +CONFIG_ETH_ENABLED=y +CONFIG_ETH_USE_ESP32_EMAC=y +CONFIG_ETH_PHY_INTERFACE_RMII=y +CONFIG_ETH_RMII_CLK_INPUT=y +# CONFIG_ETH_RMII_CLK_OUTPUT is not set +CONFIG_ETH_RMII_CLK_IN_GPIO=0 +CONFIG_ETH_DMA_BUFFER_SIZE=512 +CONFIG_ETH_DMA_RX_BUFFER_NUM=10 +CONFIG_ETH_DMA_TX_BUFFER_NUM=10 +# CONFIG_ETH_IRAM_OPTIMIZATION is not set +CONFIG_ETH_USE_SPI_ETHERNET=y +# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set +# CONFIG_ETH_SPI_ETHERNET_W5500 is not set +# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set +# CONFIG_ETH_USE_OPENETH is not set +# CONFIG_ETH_TRANSMIT_MUTEX is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +CONFIG_ESP_GDBSTUB_ENABLED=y +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set +CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y +CONFIG_ESP_GDBSTUB_MAX_TASKS=32 +# end of GDB Stub + +# +# ESP HID +# +CONFIG_ESPHID_TASK_SIZE_BT=2048 +CONFIG_ESPHID_TASK_SIZE_BLE=4096 +# end of ESP HID + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set +CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 +# end of ESP HTTPS server + +# +# Hardware Settings +# + +# +# Chip revision +# +CONFIG_ESP32_REV_MIN_0=y +# CONFIG_ESP32_REV_MIN_1 is not set +# CONFIG_ESP32_REV_MIN_1_1 is not set +# CONFIG_ESP32_REV_MIN_2 is not set +# CONFIG_ESP32_REV_MIN_3 is not set +# CONFIG_ESP32_REV_MIN_3_1 is not set +CONFIG_ESP32_REV_MIN=0 +CONFIG_ESP32_REV_MIN_FULL=0 +CONFIG_ESP_REV_MIN_FULL=0 + +# +# Maximum Supported ESP32 Revision (Rev v3.99) +# +CONFIG_ESP32_REV_MAX_FULL=399 +CONFIG_ESP_REV_MAX_FULL=399 +CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL=0 +CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL=99 + +# +# Maximum Supported ESP32 eFuse Block Revision (eFuse Block Rev v0.99) +# +# end of Chip revision + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set +# CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set +# end of MAC Config + +# +# Sleep Config +# +# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set +CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +# CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set +CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set +CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 +# CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set +# CONFIG_ESP_SLEEP_DEBUG is not set +CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y +# end of Sleep Config + +# +# RTC Clock Config +# +CONFIG_RTC_CLK_SRC_INT_RC=y +# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_RTC_CLK_CAL_CYCLES=1024 +# end of RTC Clock Config + +# +# Peripheral Control +# +CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y +# end of Peripheral Control + +# +# Main XTAL Config +# +# CONFIG_XTAL_FREQ_26 is not set +# CONFIG_XTAL_FREQ_32 is not set +CONFIG_XTAL_FREQ_40=y +# CONFIG_XTAL_FREQ_AUTO is not set +CONFIG_XTAL_FREQ=40 +# end of Main XTAL Config + +CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y +# end of Hardware Settings + +# +# ESP-Driver:LCD Controller Configurations +# +# CONFIG_LCD_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:LCD Controller Configurations + +# +# ESP-MM: Memory Management Configurations +# +# end of ESP-MM: Memory Management Configurations + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +# CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y +# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# CONFIG_ESP_NETIF_L2_TAP is not set +# CONFIG_ESP_NETIF_BRIDGE_EN is not set +# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set +# end of ESP NETIF Adapter + +# +# Partition API Configuration +# +# end of Partition API Configuration + +# +# PHY +# +CONFIG_ESP_PHY_ENABLED=y +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set +# CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set +CONFIG_ESP_PHY_RF_CAL_PARTIAL=y +# CONFIG_ESP_PHY_RF_CAL_NONE is not set +# CONFIG_ESP_PHY_RF_CAL_FULL is not set +CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# CONFIG_ESP_PHY_RECORD_USED_TIME is not set +# end of PHY + +# +# Power Management +# +# CONFIG_PM_ENABLE is not set +# CONFIG_PM_SLP_IRAM_OPT is not set +# end of Power Management + +# +# ESP PSRAM +# +# CONFIG_SPIRAM is not set +# end of ESP PSRAM + +# +# ESP Ringbuf +# +# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set +# end of ESP Ringbuf + +# +# ESP Security Specific +# +# end of ESP Security Specific + +# +# ESP System Settings +# +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 + +# +# Memory +# +# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set + +# +# Non-backward compatible options +# +# CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set +# end of Non-backward compatible options +# end of Memory + +# +# Trace memory +# +# CONFIG_ESP32_TRAX is not set +CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 +# end of Trace memory + +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 + +# +# Memory protection +# +# end of Memory protection + +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 +CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set +# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_INT_WDT_CHECK_CPU1=y +CONFIG_ESP_TASK_WDT_EN=y +CONFIG_ESP_TASK_WDT_INIT=y +# CONFIG_ESP_TASK_WDT_PANIC is not set +CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP_DEBUG_OCDAWARE=y +# CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y + +# +# Brownout Detector +# +CONFIG_ESP_BROWNOUT_DET=y +CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_ESP_BROWNOUT_DET_LVL=0 +# end of Brownout Detector + +# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set +CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y +# end of ESP System Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y +CONFIG_ESP_IPC_ISR_ENABLE=y +# end of IPC (Inter-Processor Call) + +# +# ESP Timer (High Resolution Timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set +CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 +CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y +CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +CONFIG_ESP_TIMER_IMPL_TG0_LAC=y +# end of ESP Timer (High Resolution Timer) + +# +# Wi-Fi +# +CONFIG_ESP_WIFI_ENABLED=y +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 +CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 +# CONFIG_ESP_WIFI_CSI_ENABLED is not set +CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP_WIFI_TX_BA_WIN=6 +CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP_WIFI_RX_BA_WIN=6 +CONFIG_ESP_WIFI_NVS_ENABLED=y +CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP_WIFI_IRAM_OPT=y +# CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set +CONFIG_ESP_WIFI_RX_IRAM_OPT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP_WIFI_ENABLE_SAE_PK=y +CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 +CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 +CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 +CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y +CONFIG_ESP_WIFI_GMAC_SUPPORT=y +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set +CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# CONFIG_ESP_WIFI_NAN_ENABLE is not set +CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y +CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# CONFIG_ESP_WIFI_WAPI_PSK is not set +# CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# CONFIG_ESP_WIFI_11R_SUPPORT is not set +# CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set + +# +# WPS Configuration Options +# +# CONFIG_ESP_WIFI_WPS_STRICT is not set +# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set +# end of WPS Configuration Options + +# CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set +CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y +# CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set +# end of Wi-Fi + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +CONFIG_FATFS_VOLUME_COUNT=2 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +# CONFIG_FATFS_SECTOR_512 is not set +CONFIG_FATFS_SECTOR_4096=y +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_USE_STRFUNC_NONE=y +# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set +# CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# CONFIG_FATFS_IMMEDIATE_FSYNC is not set +# CONFIG_FATFS_USE_LABEL is not set +CONFIG_FATFS_LINK_LOCK=y +# end of FAT Filesystem support + +# +# FreeRTOS +# + +# +# Kernel +# +# CONFIG_FREERTOS_SMP is not set +# CONFIG_FREERTOS_UNICORE is not set +CONFIG_FREERTOS_HZ=1000 +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +# CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# CONFIG_FREERTOS_USE_TICK_HOOK is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_USE_TIMERS=y +CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set +CONFIG_FREERTOS_TIMER_TASK_NO_AFFINITY=y +CONFIG_FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set +# end of Kernel + +# +# Port +# +CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# CONFIG_FREERTOS_FPU_IN_ISR is not set +CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# end of Port + +# +# Extra +# +# end of Extra + +CONFIG_FREERTOS_PORT=y +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y +CONFIG_FREERTOS_NUMBER_OF_CORES=2 +# end of FreeRTOS + +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILENT is not set +# CONFIG_HAL_ASSERTION_ENABLE is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 +CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y +CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_USE_HOOKS is not set +# CONFIG_HEAP_TASK_TRACKING is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set +# end of Heap memory debugging + +# +# Log +# + +# +# Log Level +# +# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +CONFIG_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=3 +CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=3 + +# +# Level Settings +# +# CONFIG_LOG_MASTER_LEVEL is not set +CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y +# CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set +# CONFIG_LOG_TAG_LEVEL_IMPL_LINKED_LIST is not set +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_AND_LINKED_LIST=y +# CONFIG_LOG_TAG_LEVEL_CACHE_ARRAY is not set +CONFIG_LOG_TAG_LEVEL_CACHE_BINARY_MIN_HEAP=y +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 +# end of Level Settings +# end of Log Level + +# +# Format +# +# CONFIG_LOG_COLORS is not set +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Format +# end of Log + +# +# LWIP +# +CONFIG_LWIP_ENABLE=y +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# CONFIG_LWIP_NETIF_API is not set +CONFIG_LWIP_TCPIP_TASK_PRIO=18 +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_ND6=y +# CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# CONFIG_LWIP_SO_RCVBUF is not set +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP_DEFAULT_TTL=64 +CONFIG_LWIP_IP4_FRAG=y +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +# CONFIG_LWIP_IP6_REASSEMBLY is not set +CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_ESP_MLDV6_REPORT=y +CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set +# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 +CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 + +# +# DHCP server +# +CONFIG_LWIP_DHCPS=y +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y +CONFIG_LWIP_DHCPS_ADD_DNS=y +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV4=y +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5760 +CONFIG_LWIP_TCP_WND_DEFAULT=5760 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 +CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 +CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 +CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 +# CONFIG_LWIP_PPP_SUPPORT is not set +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +CONFIG_LWIP_SNTP_STARTUP_DELAY=y +CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 +# end of SNTP + +# +# DNS +# +CONFIG_LWIP_DNS_MAX_HOST_IP=1 +CONFIG_LWIP_DNS_MAX_SERVERS=3 +# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set +# CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set +# end of DNS + +CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y +# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set +CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y +# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set +# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_NONE=y +# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_CUSTOM is not set +# CONFIG_LWIP_HOOK_IP6_INPUT_NONE is not set +CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y +# CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set + +# +# mbedTLS v3.x related +# +# CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set +# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set +CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y +CONFIG_MBEDTLS_PKCS7_C=y +# end of mbedTLS v3.x related + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y +# CONFIG_MBEDTLS_SHA3_C is not set +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +CONFIG_MBEDTLS_PSK_MODES=y +CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y +CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y +# CONFIG_MBEDTLS_DHM_C is not set +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +CONFIG_MBEDTLS_ERROR_STRINGS=y +CONFIG_MBEDTLS_FS_IO=y +# end of mbedTLS + +# +# ESP-MQTT Configurations +# +CONFIG_MQTT_PROTOCOL_311=y +# CONFIG_MQTT_PROTOCOL_5 is not set +CONFIG_MQTT_TRANSPORT_SSL=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set +# end of Newlib + +# +# NVS +# +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set +# end of NVS + +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set + +# +# OpenThread Spinel +# +# CONFIG_OPENTHREAD_SPINEL_ONLY is not set +# end of OpenThread Spinel +# end of OpenThread + +# +# Protocomm +# +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_PATCH_VERSION=y +# end of Protocomm + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y +# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set +# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# MMU Config +# +CONFIG_MMU_PAGE_SIZE_64KB=y +CONFIG_MMU_PAGE_MODE="64KB" +CONFIG_MMU_PAGE_SIZE=0x10000 +# end of MMU Config + +# +# Main Flash configuration +# + +# +# SPI Flash behavior when brownout +# +CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y +CONFIG_SPI_FLASH_BROWNOUT_RESET=y +# end of SPI Flash behavior when brownout + +# +# Optional and Experimental Features (READ DOCS FIRST) +# + +# +# Features here require specific hardware (READ DOCS FIRST!) +# +CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 +# CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set +# end of Optional and Experimental Features (READ DOCS FIRST) +# end of Main Flash configuration + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y +CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +CONFIG_WS_TRANSPORT=y +CONFIG_WS_BUFFER_SIZE=1024 +# CONFIG_WS_DYNAMIC_BUFFER is not set +# end of Websocket +# end of TCP Transport + +# +# Ultra Low Power (ULP) Co-processor +# +# CONFIG_ULP_COPROC_ENABLED is not set + +# +# ULP Debugging Options +# +# end of ULP Debugging Options +# end of Ultra Low Power (ULP) Co-processor + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_64BIT is not set +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +# CONFIG_VFS_SELECT_IN_RAM is not set +CONFIG_VFS_SUPPORT_TERMIOS=y +CONFIG_VFS_MAX_COUNT=8 + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# end of Host File System I/O (Semihosting) + +CONFIG_VFS_INITIALIZE_DEV_NULL=y +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y +# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set +# end of Wi-Fi Provisioning Manager +# end of Component config + +# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set + +# Deprecated options for backward compatibility +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# CONFIG_NO_BLOBS is not set +# CONFIG_ESP32_NO_BLOBS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=3 +# CONFIG_APP_ROLLBACK_ENABLE is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +# CONFIG_FLASHMODE_QIO is not set +# CONFIG_FLASHMODE_QOUT is not set +CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DOUT is not set +CONFIG_MONITOR_BAUD=115200 +CONFIG_OPTIMIZATION_LEVEL_DEBUG=y +CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y +CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y +# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_ADC2_DISABLE_DAC=y +# CONFIG_MCPWM_ISR_IN_IRAM is not set +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +CONFIG_GDBSTUB_SUPPORT_TASKS=y +CONFIG_GDBSTUB_MAX_TASKS=32 +# CONFIG_OTA_ALLOW_HTTP is not set +# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set +CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y +CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 +# CONFIG_ESP_SYSTEM_PD_FLASH is not set +CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y +CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y +# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set +# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set +# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set +CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 +# CONFIG_ESP32_XTAL_FREQ_26 is not set +CONFIG_ESP32_XTAL_FREQ_40=y +# CONFIG_ESP32_XTAL_FREQ_AUTO is not set +CONFIG_ESP32_XTAL_FREQ=40 +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# CONFIG_REDUCE_PHY_TX_POWER is not set +# CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set +# CONFIG_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y +# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160 +CONFIG_TRACEMEM_RESERVE_DRAM=0x0 +# CONFIG_ESP32_PANIC_PRINT_HALT is not set +CONFIG_ESP32_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32_PANIC_GDBSTUB is not set +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=3584 +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_CONSOLE_UART_NONE is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +CONFIG_INT_WDT_CHECK_CPU1=y +CONFIG_TASK_WDT=y +CONFIG_ESP_TASK_WDT=y +# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_TIMEOUT_S=5 +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP32_DEBUG_OCDAWARE=y +CONFIG_BROWNOUT_DET=y +CONFIG_ESP32_BROWNOUT_DET=y +CONFIG_BROWNOUT_DET_LVL_SEL_0=y +CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_BROWNOUT_DET_LVL=0 +CONFIG_ESP32_BROWNOUT_DET_LVL=0 +# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set +CONFIG_IPC_TASK_STACK_SIZE=1024 +CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y +CONFIG_WPA_MBEDTLS_CRYPTO=y +CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# CONFIG_WPA_MBO_SUPPORT is not set +# CONFIG_WPA_DPP_SUPPORT is not set +# CONFIG_WPA_11R_SUPPORT is not set +# CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set +# CONFIG_L2_TO_L3_COPY is not set +CONFIG_ESP_GRATUITOUS_ARP=y +CONFIG_GARP_TMR_INTERVAL=60 +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5760 +CONFIG_TCP_WND_DEFAULT=5760 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_HRT is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +# CONFIG_ESP32_ULP_COPROC_ENABLED is not set +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# End of deprecated options diff --git a/sdkconfig.release b/sdkconfig.release new file mode 100644 index 00000000..6aa2dd4c --- /dev/null +++ b/sdkconfig.release @@ -0,0 +1,2548 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) 5.4.1 Project Configuration +# +CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined" +CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined" +CONFIG_SOC_DPORT_WORKAROUND="Not determined" +CONFIG_SOC_CAPS_ECO_VER_MAX=301 +CONFIG_SOC_ADC_SUPPORTED=y +CONFIG_SOC_DAC_SUPPORTED=y +CONFIG_SOC_UART_SUPPORTED=y +CONFIG_SOC_MCPWM_SUPPORTED=y +CONFIG_SOC_GPTIMER_SUPPORTED=y +CONFIG_SOC_SDMMC_HOST_SUPPORTED=y +CONFIG_SOC_BT_SUPPORTED=y +CONFIG_SOC_PCNT_SUPPORTED=y +CONFIG_SOC_PHY_SUPPORTED=y +CONFIG_SOC_WIFI_SUPPORTED=y +CONFIG_SOC_SDIO_SLAVE_SUPPORTED=y +CONFIG_SOC_TWAI_SUPPORTED=y +CONFIG_SOC_EFUSE_SUPPORTED=y +CONFIG_SOC_EMAC_SUPPORTED=y +CONFIG_SOC_ULP_SUPPORTED=y +CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y +CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y +CONFIG_SOC_RTC_MEM_SUPPORTED=y +CONFIG_SOC_I2S_SUPPORTED=y +CONFIG_SOC_RMT_SUPPORTED=y +CONFIG_SOC_SDM_SUPPORTED=y +CONFIG_SOC_GPSPI_SUPPORTED=y +CONFIG_SOC_LEDC_SUPPORTED=y +CONFIG_SOC_I2C_SUPPORTED=y +CONFIG_SOC_SUPPORT_COEXISTENCE=y +CONFIG_SOC_AES_SUPPORTED=y +CONFIG_SOC_MPI_SUPPORTED=y +CONFIG_SOC_SHA_SUPPORTED=y +CONFIG_SOC_FLASH_ENC_SUPPORTED=y +CONFIG_SOC_SECURE_BOOT_SUPPORTED=y +CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y +CONFIG_SOC_BOD_SUPPORTED=y +CONFIG_SOC_ULP_FSM_SUPPORTED=y +CONFIG_SOC_CLK_TREE_SUPPORTED=y +CONFIG_SOC_MPU_SUPPORTED=y +CONFIG_SOC_WDT_SUPPORTED=y +CONFIG_SOC_SPI_FLASH_SUPPORTED=y +CONFIG_SOC_RNG_SUPPORTED=y +CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y +CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y +CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y +CONFIG_SOC_PM_SUPPORTED=y +CONFIG_SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL=5 +CONFIG_SOC_XTAL_SUPPORT_26M=y +CONFIG_SOC_XTAL_SUPPORT_40M=y +CONFIG_SOC_XTAL_SUPPORT_AUTO_DETECT=y +CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DMA_SUPPORTED=y +CONFIG_SOC_ADC_PERIPH_NUM=2 +CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 +CONFIG_SOC_ADC_ATTEN_NUM=4 +CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 +CONFIG_SOC_ADC_PATT_LEN_MAX=16 +CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 +CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=4 +CONFIG_SOC_ADC_DIGI_MONITOR_NUM=0 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=2 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=20 +CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_SHARED_POWER=y +CONFIG_SOC_SHARED_IDCACHE_SUPPORTED=y +CONFIG_SOC_IDCACHE_PER_CORE=y +CONFIG_SOC_CPU_CORES_NUM=2 +CONFIG_SOC_CPU_INTR_NUM=32 +CONFIG_SOC_CPU_HAS_FPU=y +CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y +CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 +CONFIG_SOC_DAC_CHAN_NUM=2 +CONFIG_SOC_DAC_RESOLUTION=8 +CONFIG_SOC_DAC_DMA_16BIT_ALIGN=y +CONFIG_SOC_GPIO_PORT=1 +CONFIG_SOC_GPIO_PIN_COUNT=40 +CONFIG_SOC_GPIO_VALID_GPIO_MASK=0xFFFFFFFFFF +CONFIG_SOC_GPIO_IN_RANGE_MAX=39 +CONFIG_SOC_GPIO_OUT_RANGE_MAX=33 +CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0xEF0FEA +CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y +CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3 +CONFIG_SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP=y +CONFIG_SOC_I2C_NUM=2 +CONFIG_SOC_HP_I2C_NUM=2 +CONFIG_SOC_I2C_FIFO_LEN=32 +CONFIG_SOC_I2C_CMD_REG_NUM=16 +CONFIG_SOC_I2C_SUPPORT_SLAVE=y +CONFIG_SOC_I2C_SUPPORT_APB=y +CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR=y +CONFIG_SOC_I2C_STOP_INDEPENDENT=y +CONFIG_SOC_I2S_NUM=2 +CONFIG_SOC_I2S_HW_VERSION_1=y +CONFIG_SOC_I2S_SUPPORTS_APLL=y +CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y +CONFIG_SOC_I2S_SUPPORTS_PDM=y +CONFIG_SOC_I2S_SUPPORTS_PDM_TX=y +CONFIG_SOC_I2S_PDM_MAX_TX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_PDM_RX=y +CONFIG_SOC_I2S_PDM_MAX_RX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_ADC_DAC=y +CONFIG_SOC_I2S_SUPPORTS_ADC=y +CONFIG_SOC_I2S_SUPPORTS_DAC=y +CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y +CONFIG_SOC_I2S_MAX_DATA_WIDTH=24 +CONFIG_SOC_I2S_TRANS_SIZE_ALIGN_WORD=y +CONFIG_SOC_I2S_LCD_I80_VARIANT=y +CONFIG_SOC_LCD_I80_SUPPORTED=y +CONFIG_SOC_LCD_I80_BUSES=2 +CONFIG_SOC_LCD_I80_BUS_WIDTH=24 +CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y +CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y +CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y +CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y +CONFIG_SOC_LEDC_TIMER_NUM=4 +CONFIG_SOC_LEDC_CHANNEL_NUM=8 +CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=20 +CONFIG_SOC_MCPWM_GROUPS=2 +CONFIG_SOC_MCPWM_TIMERS_PER_GROUP=3 +CONFIG_SOC_MCPWM_OPERATORS_PER_GROUP=3 +CONFIG_SOC_MCPWM_COMPARATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GENERATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_TRIGGERS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GPIO_FAULTS_PER_GROUP=3 +CONFIG_SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP=y +CONFIG_SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER=3 +CONFIG_SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP=3 +CONFIG_SOC_MMU_PERIPH_NUM=2 +CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=3 +CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 +CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 +CONFIG_SOC_PCNT_GROUPS=1 +CONFIG_SOC_PCNT_UNITS_PER_GROUP=8 +CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 +CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 +CONFIG_SOC_RMT_GROUPS=1 +CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_CHANNELS_PER_GROUP=8 +CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 +CONFIG_SOC_RMT_SUPPORT_REF_TICK=y +CONFIG_SOC_RMT_SUPPORT_APB=y +CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y +CONFIG_SOC_RTCIO_PIN_COUNT=18 +CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y +CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y +CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_SDM_GROUPS=1 +CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 +CONFIG_SOC_SDM_CLK_SUPPORT_APB=y +CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y +CONFIG_SOC_SPI_AS_CS_SUPPORTED=y +CONFIG_SOC_SPI_PERIPH_NUM=3 +CONFIG_SOC_SPI_DMA_CHAN_NUM=2 +CONFIG_SOC_SPI_MAX_CS_NUM=3 +CONFIG_SOC_SPI_SUPPORT_CLK_APB=y +CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=64 +CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 +CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y +CONFIG_SOC_TIMER_GROUPS=2 +CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 +CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 +CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y +CONFIG_SOC_LP_TIMER_BIT_WIDTH_LO=32 +CONFIG_SOC_LP_TIMER_BIT_WIDTH_HI=16 +CONFIG_SOC_TOUCH_SENSOR_VERSION=1 +CONFIG_SOC_TOUCH_SENSOR_NUM=10 +CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1 +CONFIG_SOC_TWAI_CONTROLLER_NUM=1 +CONFIG_SOC_TWAI_BRP_MIN=2 +CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y +CONFIG_SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT=y +CONFIG_SOC_UART_NUM=3 +CONFIG_SOC_UART_HP_NUM=3 +CONFIG_SOC_UART_SUPPORT_APB_CLK=y +CONFIG_SOC_UART_SUPPORT_REF_TICK=y +CONFIG_SOC_UART_FIFO_LEN=128 +CONFIG_SOC_UART_BITRATE_MAX=5000000 +CONFIG_SOC_SPIRAM_SUPPORTED=y +CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y +CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG=y +CONFIG_SOC_SHA_ENDIANNESS_BE=y +CONFIG_SOC_SHA_SUPPORT_SHA1=y +CONFIG_SOC_SHA_SUPPORT_SHA256=y +CONFIG_SOC_SHA_SUPPORT_SHA384=y +CONFIG_SOC_SHA_SUPPORT_SHA512=y +CONFIG_SOC_MPI_MEM_BLOCKS_NUM=4 +CONFIG_SOC_MPI_OPERATIONS_NUM=y +CONFIG_SOC_RSA_MAX_BIT_LEN=4096 +CONFIG_SOC_AES_SUPPORT_AES_128=y +CONFIG_SOC_AES_SUPPORT_AES_192=y +CONFIG_SOC_AES_SUPPORT_AES_256=y +CONFIG_SOC_SECURE_BOOT_V1=y +CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=y +CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=32 +CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 +CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y +CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y +CONFIG_SOC_PM_SUPPORT_MODEM_PD=y +CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y +CONFIG_SOC_PM_MODEM_PD_BY_SW=y +CONFIG_SOC_CLK_APLL_SUPPORTED=y +CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y +CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y +CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y +CONFIG_SOC_SDMMC_USE_IOMUX=y +CONFIG_SOC_SDMMC_NUM_SLOTS=2 +CONFIG_SOC_WIFI_WAPI_SUPPORT=y +CONFIG_SOC_WIFI_CSI_SUPPORT=y +CONFIG_SOC_WIFI_MESH_SUPPORT=y +CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y +CONFIG_SOC_WIFI_NAN_SUPPORT=y +CONFIG_SOC_BLE_SUPPORTED=y +CONFIG_SOC_BLE_MESH_SUPPORTED=y +CONFIG_SOC_BT_CLASSIC_SUPPORTED=y +CONFIG_SOC_BLUFI_SUPPORTED=y +CONFIG_SOC_BT_H2C_ENC_KEY_CTRL_ENH_VSC_SUPPORTED=y +CONFIG_SOC_ULP_HAS_ADC=y +CONFIG_SOC_PHY_COMBO_MODULE=y +CONFIG_SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK=y +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TOOLCHAIN="gcc" +CONFIG_IDF_TOOLCHAIN_GCC=y +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET_ARCH="xtensa" +CONFIG_IDF_TARGET="esp32" +CONFIG_IDF_INIT_VERSION="5.4.1" +CONFIG_IDF_TARGET_ESP32=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# CONFIG_APP_REPRODUCIBLE_BUILD is not set +# CONFIG_APP_NO_BLOBS is not set +# CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# end of Build type + +# +# Bootloader config +# + +# +# Bootloader manager +# +CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y +CONFIG_BOOTLOADER_PROJECT_VER=1 +# end of Bootloader manager + +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set + +# +# Log +# +# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=3 + +# +# Format +# +# CONFIG_BOOTLOADER_LOG_COLORS is not set +CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y +# end of Format +# end of Log + +# +# Serial Flash Configurations +# +# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +# end of Serial Flash Configurations + +# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_V1_SUPPORTED=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +# end of Security features + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 +# end of Application manager + +CONFIG_ESP_ROM_HAS_CRC_LE=y +CONFIG_ESP_ROM_HAS_CRC_BE=y +CONFIG_ESP_ROM_HAS_MZ_CRC32=y +CONFIG_ESP_ROM_HAS_JPEG_DECODE=y +CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y +CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y +CONFIG_ESP_ROM_HAS_NEWLIB=y +CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y +CONFIG_ESP_ROM_HAS_NEWLIB_32BIT_TIME=y +CONFIG_ESP_ROM_HAS_SW_FLOAT=y +CONFIG_ESP_ROM_USB_OTG_NUM=-1 +CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1 +CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y +CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y + +# +# Serial flasher config +# +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHMODE="dio" +# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="40m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="2MB" +# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set +# CONFIG_PARTITION_TABLE_CUSTOM is not set +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Arduino Configuration +# +CONFIG_ARDUINO_VARIANT="esp32" +CONFIG_ENABLE_ARDUINO_DEPENDS=y +# CONFIG_AUTOSTART_ARDUINO is not set +# CONFIG_ARDUINO_RUN_CORE0 is not set +CONFIG_ARDUINO_RUN_CORE1=y +# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_RUNNING_CORE=1 +CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 +# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set +CONFIG_ARDUINO_EVENT_RUN_CORE1=y +# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set +CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y +CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=2048 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 +CONFIG_ARDUINO_UDP_RUN_CORE0=y +# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set +# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_UDP_RUNNING_CORE=0 +CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 +# CONFIG_ARDUINO_ISR_IRAM is not set +# CONFIG_DISABLE_HAL_LOCKS is not set + +# +# Debug Log Configuration +# +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE=y +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=0 +# CONFIG_ARDUHAL_LOG_COLORS is not set +# CONFIG_ARDUHAL_ESP_LOG is not set +# end of Debug Log Configuration + +# CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set +CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS=y +CONFIG_ARDUHAL_PARTITION_SCHEME="min_spiffs" +CONFIG_ARDUINO_SELECTIVE_COMPILATION=y +CONFIG_ARDUINO_SELECTIVE_SPI=y +CONFIG_ARDUINO_SELECTIVE_Wire=y +CONFIG_ARDUINO_SELECTIVE_ESP_SR=y +CONFIG_ARDUINO_SELECTIVE_EEPROM=y +# CONFIG_ARDUINO_SELECTIVE_Preferences is not set +# CONFIG_ARDUINO_SELECTIVE_Ticker is not set +CONFIG_ARDUINO_SELECTIVE_Update=y +# CONFIG_ARDUINO_SELECTIVE_Zigbee is not set +CONFIG_ARDUINO_SELECTIVE_FS=y +# CONFIG_ARDUINO_SELECTIVE_SD is not set +# CONFIG_ARDUINO_SELECTIVE_SD_MMC is not set +# CONFIG_ARDUINO_SELECTIVE_SPIFFS is not set +# CONFIG_ARDUINO_SELECTIVE_FFat is not set +CONFIG_ARDUINO_SELECTIVE_LittleFS=y +CONFIG_ARDUINO_SELECTIVE_Network=y +# CONFIG_ARDUINO_SELECTIVE_Ethernet is not set +CONFIG_ARDUINO_SELECTIVE_PPP=y +CONFIG_ARDUINO_SELECTIVE_ArduinoOTA=y +CONFIG_ARDUINO_SELECTIVE_AsyncUDP=y +CONFIG_ARDUINO_SELECTIVE_DNSServer=y +CONFIG_ARDUINO_SELECTIVE_ESPmDNS=y +CONFIG_ARDUINO_SELECTIVE_HTTPClient=y +# CONFIG_ARDUINO_SELECTIVE_Matter is not set +# CONFIG_ARDUINO_SELECTIVE_NetBIOS is not set +CONFIG_ARDUINO_SELECTIVE_WebServer=y +CONFIG_ARDUINO_SELECTIVE_WiFi=y +CONFIG_ARDUINO_SELECTIVE_NetworkClientSecure=y +CONFIG_ARDUINO_SELECTIVE_WiFiProv=y +CONFIG_ARDUINO_SELECTIVE_BLE=y +# CONFIG_ARDUINO_SELECTIVE_BluetoothSerial is not set +CONFIG_ARDUINO_SELECTIVE_SimpleBLE=y +# CONFIG_ARDUINO_SELECTIVE_RainMaker is not set +# CONFIG_ARDUINO_SELECTIVE_OpenThread is not set +# CONFIG_ARDUINO_SELECTIVE_Insights is not set +# end of Arduino Configuration + +# +# Compiler options +# +# CONFIG_COMPILER_OPTIMIZATION_DEBUG is not set +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y +CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set +CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y +# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +CONFIG_COMPILER_RT_LIB_GCCLIB=y +CONFIG_COMPILER_RT_LIB_NAME="gcc" +CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y +# CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set +# CONFIG_COMPILER_STATIC_ANALYZER is not set +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_JTAG is not set +CONFIG_APPTRACE_DEST_NONE=y +# CONFIG_APPTRACE_DEST_UART1 is not set +# CONFIG_APPTRACE_DEST_UART2 is not set +CONFIG_APPTRACE_DEST_UART_NONE=y +CONFIG_APPTRACE_UART_TASK_PRIO=1 +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# Bluetooth +# +CONFIG_BT_ENABLED=y +# CONFIG_BT_BLUEDROID_ENABLED is not set +CONFIG_BT_NIMBLE_ENABLED=y +# CONFIG_BT_CONTROLLER_ONLY is not set +CONFIG_BT_CONTROLLER_ENABLED=y +# CONFIG_BT_CONTROLLER_DISABLED is not set + +# +# NimBLE Options +# +CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y +# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_NONE is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_WARNING is not set +CONFIG_BT_NIMBLE_LOG_LEVEL_INFO=y +# CONFIG_BT_NIMBLE_LOG_LEVEL_DEBUG is not set +CONFIG_BT_NIMBLE_LOG_LEVEL=1 +CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 +CONFIG_BT_NIMBLE_MAX_BONDS=1 +CONFIG_BT_NIMBLE_MAX_CCCDS=1 +CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM=0 +CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y +# CONFIG_BT_NIMBLE_PINNED_TO_CORE_1 is not set +CONFIG_BT_NIMBLE_PINNED_TO_CORE=0 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=4096 +CONFIG_BT_NIMBLE_ROLE_CENTRAL=y +CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y +CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y +CONFIG_BT_NIMBLE_ROLE_OBSERVER=y +# CONFIG_BT_NIMBLE_NVS_PERSIST is not set +# CONFIG_BT_NIMBLE_SMP_ID_RESET is not set +# CONFIG_BT_NIMBLE_SECURITY_ENABLE is not set +# CONFIG_BT_NIMBLE_DEBUG is not set +# CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set +CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" +CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 +CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=256 +CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE=0 + +# +# Memory Settings +# +CONFIG_BT_NIMBLE_MSYS_1_BLOCK_COUNT=12 +CONFIG_BT_NIMBLE_MSYS_1_BLOCK_SIZE=256 +CONFIG_BT_NIMBLE_MSYS_2_BLOCK_COUNT=24 +CONFIG_BT_NIMBLE_MSYS_2_BLOCK_SIZE=320 +CONFIG_BT_NIMBLE_TRANSPORT_ACL_FROM_LL_COUNT=24 +CONFIG_BT_NIMBLE_TRANSPORT_ACL_SIZE=255 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_COUNT=30 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_DISCARD_COUNT=8 +CONFIG_BT_NIMBLE_L2CAP_COC_SDU_BUFF_COUNT=1 +# end of Memory Settings + +CONFIG_BT_NIMBLE_GATT_MAX_PROCS=4 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL=y +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y +CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 +# CONFIG_BT_NIMBLE_MESH is not set +CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y +CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 +# CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set +# CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set +CONFIG_BT_NIMBLE_WHITELIST_SIZE=1 +# CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set +# CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set +CONFIG_BT_NIMBLE_USE_ESP_TIMER=y +CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y +# CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set + +# +# GAP Service +# + +# +# GAP Appearance write permissions +# +# CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set +# end of GAP Appearance write permissions + +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ENC=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHN=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHR=0 +CONFIG_BT_NIMBLE_SVC_GAP_CAR_CHAR_NOT_SUPP=y +# CONFIG_BT_NIMBLE_SVC_GAP_CAR_NOT_SUPP is not set +# CONFIG_BT_NIMBLE_SVC_GAP_CAR_SUPP is not set +CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 + +# +# GAP device name write permissions +# +# CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set +# end of GAP device name write permissions + +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_ENC=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHEN=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHOR=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 +# CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL is not set +# end of GAP Service + +# +# BLE Services +# +# CONFIG_BT_NIMBLE_HID_SERVICE is not set +# CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY is not set + +# +# Device Information Service +# +# CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME is not set +# CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER is not set +# CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION is not set +# CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION is not set +# CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION is not set +# CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID is not set +# CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID is not set +# CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED is not set +# end of Device Information Service +# end of BLE Services + +# CONFIG_BT_NIMBLE_VS_SUPPORT is not set +# CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set +# CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set +# CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set +# CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT is not set + +# +# Host-controller Transport +# +CONFIG_UART_HW_FLOWCTRL_DISABLE=y +# CONFIG_UART_HW_FLOWCTRL_CTS_RTS is not set +CONFIG_BT_NIMBLE_HCI_UART_FLOW_CTRL=0 +CONFIG_BT_NIMBLE_HCI_UART_RTS_PIN=19 +CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 +# end of Host-controller Transport + +CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 +# CONFIG_BT_NIMBLE_SUBRATE is not set +# end of NimBLE Options + +# +# Controller Options +# +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +# CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set +# CONFIG_BTDM_CTRL_MODE_BTDM is not set +CONFIG_BTDM_CTRL_BLE_MAX_CONN=3 +CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 +CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 +CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 +CONFIG_BTDM_CTRL_PCM_FSYNCSHP_EFF=0 +CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=3 +CONFIG_BTDM_CTRL_BR_EDR_MIN_ENC_KEY_SZ_DFT_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CTRL_PINNED_TO_CORE_0=y +# CONFIG_BTDM_CTRL_PINNED_TO_CORE_1 is not set +CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 +CONFIG_BTDM_CTRL_HCI_MODE_VHCI=y +# CONFIG_BTDM_CTRL_HCI_MODE_UART_H4 is not set + +# +# MODEM SLEEP Options +# +CONFIG_BTDM_CTRL_MODEM_SLEEP=y +CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG=y +# CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_EVED is not set +CONFIG_BTDM_CTRL_LPCLK_SEL_MAIN_XTAL=y +# end of MODEM SLEEP Options + +CONFIG_BTDM_BLE_DEFAULT_SCA_250PPM=y +CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 +CONFIG_BTDM_BLE_SCAN_DUPL=y +CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y +# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA is not set +# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE is not set +CONFIG_BTDM_SCAN_DUPL_TYPE=0 +CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 +CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 +# CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set +CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y +# CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set +# CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set +CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y +CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 +CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 + +# +# BLE disconnects when Instant Passed (0x28) occurs +# +# CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set +# CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set +# end of BLE disconnects when Instant Passed (0x28) occurs + +CONFIG_BTDM_BLE_CHAN_ASS_EN=y +CONFIG_BTDM_BLE_PING_EN=y +# CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 is not set +CONFIG_BTDM_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_CTRL_HLI=y +# end of Controller Options + +# +# Common Options +# +CONFIG_BT_ALARM_MAX_NUM=50 +# CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set +# end of Common Options + +# CONFIG_BT_HCI_LOG_DEBUG_EN is not set +# end of Bluetooth + +# CONFIG_BLE_MESH is not set + +# +# Console Library +# +# CONFIG_CONSOLE_SORTED_HELP is not set +# end of Console Library + +# +# Driver Configurations +# + +# +# TWAI Configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y +CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y +CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID=y +CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT=y +CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y +# end of TWAI Configuration + +# +# Legacy ADC Driver Configuration +# +CONFIG_ADC_DISABLE_DAC=y +# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set + +# +# Legacy ADC Calibration Configuration +# +CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y +CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CAL_LUT_ENABLE=y +# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy ADC Calibration Configuration +# end of Legacy ADC Driver Configuration + +# +# Legacy DAC Driver Configurations +# +# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy DAC Driver Configurations + +# +# Legacy MCPWM Driver Configurations +# +# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy MCPWM Driver Configurations + +# +# Legacy Timer Group Driver Configurations +# +# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy Timer Group Driver Configurations + +# +# Legacy RMT Driver Configurations +# +# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy RMT Driver Configurations + +# +# Legacy I2S Driver Configurations +# +# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy I2S Driver Configurations + +# +# Legacy PCNT Driver Configurations +# +# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy PCNT Driver Configurations + +# +# Legacy SDM Driver Configurations +# +# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy SDM Driver Configurations +# end of Driver Configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set +CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set +CONFIG_EFUSE_MAX_BLK_LEN=192 +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +# CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set +# CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + +# +# ADC and ADC Calibration +# +# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set + +# +# ADC Calibration Configurations +# +CONFIG_ADC_CALI_EFUSE_TP_ENABLE=y +CONFIG_ADC_CALI_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CALI_LUT_ENABLE=y +# end of ADC Calibration Configurations + +CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# CONFIG_ADC_ENABLE_DEBUG_LOG is not set +# end of ADC and ADC Calibration + +# +# Wireless Coexistence +# +CONFIG_ESP_COEX_ENABLED=y +CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y +# CONFIG_ESP_COEX_POWER_MANAGEMENT is not set +# CONFIG_ESP_COEX_GPIO_DEBUG is not set +# end of Wireless Coexistence + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# end of Common ESP-related + +# +# ESP-Driver:DAC Configurations +# +# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# CONFIG_DAC_ISR_IRAM_SAFE is not set +# CONFIG_DAC_ENABLE_DEBUG_LOG is not set +CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y +# end of ESP-Driver:DAC Configurations + +# +# ESP-Driver:GPIO Configurations +# +# CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set +# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:GPIO Configurations + +# +# ESP-Driver:GPTimer Configurations +# +CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y +# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:GPTimer Configurations + +# +# ESP-Driver:I2C Configurations +# +# CONFIG_I2C_ISR_IRAM_SAFE is not set +# CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set +# end of ESP-Driver:I2C Configurations + +# +# ESP-Driver:I2S Configurations +# +# CONFIG_I2S_ISR_IRAM_SAFE is not set +# CONFIG_I2S_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:I2S Configurations + +# +# ESP-Driver:LEDC Configurations +# +# CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:LEDC Configurations + +# +# ESP-Driver:MCPWM Configurations +# +# CONFIG_MCPWM_ISR_IRAM_SAFE is not set +# CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:MCPWM Configurations + +# +# ESP-Driver:PCNT Configurations +# +# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_PCNT_ISR_IRAM_SAFE is not set +# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:PCNT Configurations + +# +# ESP-Driver:RMT Configurations +# +# CONFIG_RMT_ISR_IRAM_SAFE is not set +# CONFIG_RMT_RECV_FUNC_IN_IRAM is not set +# CONFIG_RMT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:RMT Configurations + +# +# ESP-Driver:Sigma Delta Modulator Configurations +# +# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_SDM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Sigma Delta Modulator Configurations + +# +# ESP-Driver:SPI Configurations +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of ESP-Driver:SPI Configurations + +# +# ESP-Driver:Touch Sensor Configurations +# +# CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set +# CONFIG_TOUCH_ISR_IRAM_SAFE is not set +# CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Touch Sensor Configurations + +# +# ESP-Driver:UART Configurations +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of ESP-Driver:UART Configurations + +# +# Ethernet +# +# CONFIG_ETH_USE_ESP32_EMAC is not set +# CONFIG_ETH_USE_SPI_ETHERNET is not set +# CONFIG_ETH_USE_OPENETH is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +CONFIG_ESP_GDBSTUB_ENABLED=y +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set +CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y +CONFIG_ESP_GDBSTUB_MAX_TASKS=32 +# end of GDB Stub + +# +# ESP HID +# +CONFIG_ESPHID_TASK_SIZE_BT=2048 +CONFIG_ESPHID_TASK_SIZE_BLE=4096 +# end of ESP HID + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set +CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 +# end of ESP HTTPS server + +# +# Hardware Settings +# + +# +# Chip revision +# +CONFIG_ESP32_REV_MIN_0=y +# CONFIG_ESP32_REV_MIN_1 is not set +# CONFIG_ESP32_REV_MIN_1_1 is not set +# CONFIG_ESP32_REV_MIN_2 is not set +# CONFIG_ESP32_REV_MIN_3 is not set +# CONFIG_ESP32_REV_MIN_3_1 is not set +CONFIG_ESP32_REV_MIN=0 +CONFIG_ESP32_REV_MIN_FULL=0 +CONFIG_ESP_REV_MIN_FULL=0 + +# +# Maximum Supported ESP32 Revision (Rev v3.99) +# +CONFIG_ESP32_REV_MAX_FULL=399 +CONFIG_ESP_REV_MAX_FULL=399 +CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL=0 +CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL=99 + +# +# Maximum Supported ESP32 eFuse Block Revision (eFuse Block Rev v0.99) +# +# end of Chip revision + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set +# CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set +# end of MAC Config + +# +# Sleep Config +# +# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set +CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +# CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set +CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set +CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 +# CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set +# CONFIG_ESP_SLEEP_DEBUG is not set +CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y +# end of Sleep Config + +# +# RTC Clock Config +# +CONFIG_RTC_CLK_SRC_INT_RC=y +# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_RTC_CLK_CAL_CYCLES=1024 +# end of RTC Clock Config + +# +# Peripheral Control +# +CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y +# end of Peripheral Control + +# +# Main XTAL Config +# +# CONFIG_XTAL_FREQ_26 is not set +# CONFIG_XTAL_FREQ_32 is not set +CONFIG_XTAL_FREQ_40=y +# CONFIG_XTAL_FREQ_AUTO is not set +CONFIG_XTAL_FREQ=40 +# end of Main XTAL Config + +CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y +# end of Hardware Settings + +# +# ESP-Driver:LCD Controller Configurations +# +# CONFIG_LCD_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:LCD Controller Configurations + +# +# ESP-MM: Memory Management Configurations +# +# end of ESP-MM: Memory Management Configurations + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +# CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y +# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# CONFIG_ESP_NETIF_L2_TAP is not set +# CONFIG_ESP_NETIF_BRIDGE_EN is not set +# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set +# end of ESP NETIF Adapter + +# +# Partition API Configuration +# +# end of Partition API Configuration + +# +# PHY +# +CONFIG_ESP_PHY_ENABLED=y +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set +# CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set +CONFIG_ESP_PHY_RF_CAL_PARTIAL=y +# CONFIG_ESP_PHY_RF_CAL_NONE is not set +# CONFIG_ESP_PHY_RF_CAL_FULL is not set +CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# CONFIG_ESP_PHY_RECORD_USED_TIME is not set +# end of PHY + +# +# Power Management +# +# CONFIG_PM_ENABLE is not set +# CONFIG_PM_SLP_IRAM_OPT is not set +# end of Power Management + +# +# ESP PSRAM +# +# CONFIG_SPIRAM is not set +# end of ESP PSRAM + +# +# ESP Ringbuf +# +# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set +# end of ESP Ringbuf + +# +# ESP Security Specific +# +# end of ESP Security Specific + +# +# ESP System Settings +# +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 + +# +# Memory +# +# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set + +# +# Non-backward compatible options +# +# CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set +# end of Non-backward compatible options +# end of Memory + +# +# Trace memory +# +# CONFIG_ESP32_TRAX is not set +CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 +# end of Trace memory + +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 + +# +# Memory protection +# +# end of Memory protection + +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 +CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set +# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_INT_WDT_CHECK_CPU1=y +CONFIG_ESP_TASK_WDT_EN=y +CONFIG_ESP_TASK_WDT_INIT=y +# CONFIG_ESP_TASK_WDT_PANIC is not set +CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP_DEBUG_OCDAWARE=y +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y + +# +# Brownout Detector +# +CONFIG_ESP_BROWNOUT_DET=y +CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_ESP_BROWNOUT_DET_LVL=0 +# end of Brownout Detector + +# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set +CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y +# end of ESP System Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y +CONFIG_ESP_IPC_ISR_ENABLE=y +# end of IPC (Inter-Processor Call) + +# +# ESP Timer (High Resolution Timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set +CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 +CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y +CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +CONFIG_ESP_TIMER_IMPL_TG0_LAC=y +# end of ESP Timer (High Resolution Timer) + +# +# Wi-Fi +# +CONFIG_ESP_WIFI_ENABLED=y +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 +CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 +# CONFIG_ESP_WIFI_CSI_ENABLED is not set +CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP_WIFI_TX_BA_WIN=6 +CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP_WIFI_RX_BA_WIN=6 +CONFIG_ESP_WIFI_NVS_ENABLED=y +CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +# CONFIG_ESP_WIFI_IRAM_OPT is not set +# CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set +# CONFIG_ESP_WIFI_RX_IRAM_OPT is not set +CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP_WIFI_ENABLE_SAE_PK=y +CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 +CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 +CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 +CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y +CONFIG_ESP_WIFI_GMAC_SUPPORT=y +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set +CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# CONFIG_ESP_WIFI_NAN_ENABLE is not set +CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y +CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# CONFIG_ESP_WIFI_WAPI_PSK is not set +# CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# CONFIG_ESP_WIFI_11R_SUPPORT is not set +# CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set + +# +# WPS Configuration Options +# +# CONFIG_ESP_WIFI_WPS_STRICT is not set +# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set +# end of WPS Configuration Options + +# CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set +CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y +# CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set +# end of Wi-Fi + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +CONFIG_FATFS_VOLUME_COUNT=2 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +# CONFIG_FATFS_SECTOR_512 is not set +CONFIG_FATFS_SECTOR_4096=y +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_USE_STRFUNC_NONE=y +# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set +# CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# CONFIG_FATFS_IMMEDIATE_FSYNC is not set +# CONFIG_FATFS_USE_LABEL is not set +CONFIG_FATFS_LINK_LOCK=y +# end of FAT Filesystem support + +# +# FreeRTOS +# + +# +# Kernel +# +# CONFIG_FREERTOS_SMP is not set +# CONFIG_FREERTOS_UNICORE is not set +CONFIG_FREERTOS_HZ=1000 +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +# CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# CONFIG_FREERTOS_USE_TICK_HOOK is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_USE_TIMERS=y +CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set +CONFIG_FREERTOS_TIMER_TASK_NO_AFFINITY=y +CONFIG_FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set +# end of Kernel + +# +# Port +# +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# CONFIG_FREERTOS_FPU_IN_ISR is not set +CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# end of Port + +# +# Extra +# +# end of Extra + +CONFIG_FREERTOS_PORT=y +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y +CONFIG_FREERTOS_NUMBER_OF_CORES=2 +# end of FreeRTOS + +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILENT is not set +# CONFIG_HAL_ASSERTION_ENABLE is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 +CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y +CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_USE_HOOKS is not set +# CONFIG_HEAP_TASK_TRACKING is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set +# end of Heap memory debugging + +# +# Log +# + +# +# Log Level +# +CONFIG_LOG_DEFAULT_LEVEL_NONE=y +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=0 +CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_ERROR is not set +# CONFIG_LOG_MAXIMUM_LEVEL_WARN is not set +# CONFIG_LOG_MAXIMUM_LEVEL_INFO is not set +# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=0 + +# +# Level Settings +# +# CONFIG_LOG_MASTER_LEVEL is not set +CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y +# CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set +# CONFIG_LOG_TAG_LEVEL_IMPL_LINKED_LIST is not set +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_AND_LINKED_LIST=y +# CONFIG_LOG_TAG_LEVEL_CACHE_ARRAY is not set +CONFIG_LOG_TAG_LEVEL_CACHE_BINARY_MIN_HEAP=y +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 +# end of Level Settings +# end of Log Level + +# +# Format +# +# CONFIG_LOG_COLORS is not set +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Format +# end of Log + +# +# LWIP +# +CONFIG_LWIP_ENABLE=y +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# CONFIG_LWIP_NETIF_API is not set +CONFIG_LWIP_TCPIP_TASK_PRIO=18 +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_ND6=y +# CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +CONFIG_LWIP_SO_RCVBUF=y +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP_DEFAULT_TTL=64 +CONFIG_LWIP_IP4_FRAG=y +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +# CONFIG_LWIP_IP6_REASSEMBLY is not set +CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_ESP_MLDV6_REPORT=y +CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set +# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 +CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 + +# +# DHCP server +# +CONFIG_LWIP_DHCPS=y +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y +CONFIG_LWIP_DHCPS_ADD_DNS=y +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV4=y +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5760 +CONFIG_LWIP_TCP_WND_DEFAULT=5760 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 +CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 +CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 +CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 +# CONFIG_LWIP_PPP_SUPPORT is not set +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +CONFIG_LWIP_SNTP_STARTUP_DELAY=y +CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 +# end of SNTP + +# +# DNS +# +CONFIG_LWIP_DNS_MAX_HOST_IP=1 +CONFIG_LWIP_DNS_MAX_SERVERS=3 +# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set +# CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set +# end of DNS + +CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y +# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set +CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y +# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set +# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_NONE=y +# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_CUSTOM is not set +# CONFIG_LWIP_HOOK_IP6_INPUT_NONE is not set +CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y +# CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set + +# +# mbedTLS v3.x related +# +# CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set +# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set +CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y +CONFIG_MBEDTLS_PKCS7_C=y +# end of mbedTLS v3.x related + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y +# CONFIG_MBEDTLS_SHA3_C is not set +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +CONFIG_MBEDTLS_PSK_MODES=y +CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y +CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y +# CONFIG_MBEDTLS_DHM_C is not set +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +CONFIG_MBEDTLS_ERROR_STRINGS=y +CONFIG_MBEDTLS_FS_IO=y +# end of mbedTLS + +# +# ESP-MQTT Configurations +# +# CONFIG_MQTT_PROTOCOL_311 is not set +# CONFIG_MQTT_PROTOCOL_5 is not set +# CONFIG_MQTT_TRANSPORT_SSL is not set +# CONFIG_MQTT_TRANSPORT_WEBSOCKET is not set +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set +# end of Newlib + +# +# NVS +# +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set +# end of NVS + +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set + +# +# OpenThread Spinel +# +# CONFIG_OPENTHREAD_SPINEL_ONLY is not set +# end of OpenThread Spinel +# end of OpenThread + +# +# Protocomm +# +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_PATCH_VERSION=y +# end of Protocomm + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y +# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set +# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# MMU Config +# +CONFIG_MMU_PAGE_SIZE_64KB=y +CONFIG_MMU_PAGE_MODE="64KB" +CONFIG_MMU_PAGE_SIZE=0x10000 +# end of MMU Config + +# +# Main Flash configuration +# + +# +# SPI Flash behavior when brownout +# +CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y +CONFIG_SPI_FLASH_BROWNOUT_RESET=y +# end of SPI Flash behavior when brownout + +# +# Optional and Experimental Features (READ DOCS FIRST) +# + +# +# Features here require specific hardware (READ DOCS FIRST!) +# +CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 +# CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set +# end of Optional and Experimental Features (READ DOCS FIRST) +# end of Main Flash configuration + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y +CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +CONFIG_WS_TRANSPORT=y +CONFIG_WS_BUFFER_SIZE=1024 +# CONFIG_WS_DYNAMIC_BUFFER is not set +# end of Websocket +# end of TCP Transport + +# +# Ultra Low Power (ULP) Co-processor +# +# CONFIG_ULP_COPROC_ENABLED is not set + +# +# ULP Debugging Options +# +# end of ULP Debugging Options +# end of Ultra Low Power (ULP) Co-processor + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_64BIT is not set +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +# CONFIG_VFS_SELECT_IN_RAM is not set +CONFIG_VFS_SUPPORT_TERMIOS=y +CONFIG_VFS_MAX_COUNT=8 + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# end of Host File System I/O (Semihosting) + +CONFIG_VFS_INITIALIZE_DEV_NULL=y +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_WIFI_PROV_BLE_BONDING is not set +CONFIG_WIFI_PROV_BLE_SEC_CONN=y +# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set +# CONFIG_WIFI_PROV_BLE_NOTIFY is not set +# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set +CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y +# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set +# end of Wi-Fi Provisioning Manager + +# +# Zigbee +# +# CONFIG_ZB_ENABLED is not set +# end of Zigbee + +# +# mDNS +# +CONFIG_MDNS_MAX_INTERFACES=3 +CONFIG_MDNS_MAX_SERVICES=10 +CONFIG_MDNS_TASK_PRIORITY=1 +CONFIG_MDNS_ACTION_QUEUE_LEN=16 +CONFIG_MDNS_TASK_STACK_SIZE=4096 +# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_MDNS_TASK_AFFINITY_CPU0=y +# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set +CONFIG_MDNS_TASK_AFFINITY=0x0 + +# +# MDNS Memory Configuration +# +CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y +CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y +# CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set +# end of MDNS Memory Configuration + +CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 +CONFIG_MDNS_TIMER_PERIOD_MS=100 +# CONFIG_MDNS_NETWORKING_SOCKET is not set +# CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set +# CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set +CONFIG_MDNS_ENABLE_CONSOLE_CLI=y +# CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set +CONFIG_MDNS_MULTIPLE_INSTANCE=y + +# +# MDNS Predefined interfaces +# +CONFIG_MDNS_PREDEF_NETIF_STA=y +CONFIG_MDNS_PREDEF_NETIF_AP=y +# end of MDNS Predefined interfaces +# end of mDNS + +# +# Network Provisioning Manager +# +CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y +CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_NETWORK_PROV_BLE_BONDING is not set +CONFIG_NETWORK_PROV_BLE_SEC_CONN=y +# CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set +# CONFIG_NETWORK_PROV_KEEP_BLE_ON_AFTER_PROV is not set +CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y +# CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set +# end of Network Provisioning Manager + +# +# LittleFS +# +# CONFIG_LITTLEFS_SDMMC_SUPPORT is not set +CONFIG_LITTLEFS_MAX_PARTITIONS=3 +CONFIG_LITTLEFS_PAGE_SIZE=256 +CONFIG_LITTLEFS_OBJ_NAME_LEN=64 +CONFIG_LITTLEFS_READ_SIZE=128 +CONFIG_LITTLEFS_WRITE_SIZE=128 +CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 +CONFIG_LITTLEFS_CACHE_SIZE=512 +CONFIG_LITTLEFS_BLOCK_CYCLES=512 +CONFIG_LITTLEFS_USE_MTIME=y +# CONFIG_LITTLEFS_USE_ONLY_HASH is not set +# CONFIG_LITTLEFS_HUMAN_READABLE is not set +CONFIG_LITTLEFS_MTIME_USE_SECONDS=y +# CONFIG_LITTLEFS_MTIME_USE_NONCE is not set +# CONFIG_LITTLEFS_SPIFFS_COMPAT is not set +# CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set +# CONFIG_LITTLEFS_FCNTL_GET_PATH is not set +# CONFIG_LITTLEFS_MULTIVERSION is not set +# CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set +CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y +# CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set +CONFIG_LITTLEFS_ASSERTS=y +# CONFIG_LITTLEFS_MMAP_PARTITION is not set +# end of LittleFS +# end of Component config + +# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set + +# Deprecated options for backward compatibility +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# CONFIG_NO_BLOBS is not set +# CONFIG_ESP32_NO_BLOBS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=3 +# CONFIG_APP_ROLLBACK_ENABLE is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +# CONFIG_FLASHMODE_QIO is not set +# CONFIG_FLASHMODE_QOUT is not set +CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DOUT is not set +CONFIG_MONITOR_BAUD=115200 +# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set +CONFIG_OPTIMIZATION_LEVEL_RELEASE=y +CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +# CONFIG_BLUEDROID_ENABLED is not set +CONFIG_NIMBLE_ENABLED=y +CONFIG_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y +# CONFIG_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set +CONFIG_NIMBLE_MAX_CONNECTIONS=7 +CONFIG_NIMBLE_MAX_BONDS=1 +CONFIG_NIMBLE_MAX_CCCDS=1 +CONFIG_NIMBLE_L2CAP_COC_MAX_NUM=0 +CONFIG_NIMBLE_PINNED_TO_CORE_0=y +# CONFIG_NIMBLE_PINNED_TO_CORE_1 is not set +CONFIG_NIMBLE_PINNED_TO_CORE=0 +CONFIG_NIMBLE_TASK_STACK_SIZE=4096 +CONFIG_BT_NIMBLE_TASK_STACK_SIZE=4096 +CONFIG_NIMBLE_ROLE_CENTRAL=y +CONFIG_NIMBLE_ROLE_PERIPHERAL=y +CONFIG_NIMBLE_ROLE_BROADCASTER=y +CONFIG_NIMBLE_ROLE_OBSERVER=y +# CONFIG_NIMBLE_NVS_PERSIST is not set +# CONFIG_NIMBLE_DEBUG is not set +CONFIG_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" +CONFIG_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 +CONFIG_NIMBLE_ATT_PREFERRED_MTU=256 +CONFIG_NIMBLE_SVC_GAP_APPEARANCE=0 +CONFIG_BT_NIMBLE_MSYS1_BLOCK_COUNT=12 +CONFIG_BT_NIMBLE_ACL_BUF_COUNT=24 +CONFIG_BT_NIMBLE_ACL_BUF_SIZE=255 +CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70 +CONFIG_BT_NIMBLE_HCI_EVT_HI_BUF_COUNT=30 +CONFIG_BT_NIMBLE_HCI_EVT_LO_BUF_COUNT=8 +CONFIG_NIMBLE_HS_FLOW_CTRL=y +CONFIG_NIMBLE_HS_FLOW_CTRL_ITVL=1000 +CONFIG_NIMBLE_HS_FLOW_CTRL_THRESH=2 +CONFIG_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y +CONFIG_NIMBLE_RPA_TIMEOUT=900 +# CONFIG_NIMBLE_MESH is not set +CONFIG_NIMBLE_CRYPTO_STACK_MBEDTLS=y +CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y +# CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY is not set +# CONFIG_BTDM_CONTROLLER_MODE_BTDM is not set +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=3 +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=3 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 +CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI=y +# CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4 is not set +CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=y +CONFIG_BLE_SCAN_DUPLICATE=y +CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y +# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA is not set +# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR is not set +CONFIG_SCAN_DUPLICATE_TYPE=0 +CONFIG_DUPLICATE_SCAN_CACHE_SIZE=100 +# CONFIG_BLE_MESH_SCAN_DUPLICATE_EN is not set +CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y +CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED=y +CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM=100 +CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 +CONFIG_ADC2_DISABLE_DAC=y +CONFIG_SW_COEXIST_ENABLE=y +CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y +CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y +# CONFIG_MCPWM_ISR_IN_IRAM is not set +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +CONFIG_GDBSTUB_SUPPORT_TASKS=y +CONFIG_GDBSTUB_MAX_TASKS=32 +# CONFIG_OTA_ALLOW_HTTP is not set +# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set +CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y +CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 +# CONFIG_ESP_SYSTEM_PD_FLASH is not set +CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y +CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y +# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set +# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set +# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set +CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 +# CONFIG_ESP32_XTAL_FREQ_26 is not set +CONFIG_ESP32_XTAL_FREQ_40=y +# CONFIG_ESP32_XTAL_FREQ_AUTO is not set +CONFIG_ESP32_XTAL_FREQ=40 +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# CONFIG_REDUCE_PHY_TX_POWER is not set +# CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set +# CONFIG_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y +# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160 +CONFIG_TRACEMEM_RESERVE_DRAM=0x0 +# CONFIG_ESP32_PANIC_PRINT_HALT is not set +CONFIG_ESP32_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32_PANIC_GDBSTUB is not set +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=3584 +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_CONSOLE_UART_NONE is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +CONFIG_INT_WDT_CHECK_CPU1=y +CONFIG_TASK_WDT=y +CONFIG_ESP_TASK_WDT=y +# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_TIMEOUT_S=5 +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP32_DEBUG_OCDAWARE=y +CONFIG_BROWNOUT_DET=y +CONFIG_ESP32_BROWNOUT_DET=y +CONFIG_BROWNOUT_DET_LVL_SEL_0=y +CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_BROWNOUT_DET_LVL=0 +CONFIG_ESP32_BROWNOUT_DET_LVL=0 +# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set +CONFIG_IPC_TASK_STACK_SIZE=1024 +CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +# CONFIG_ESP32_WIFI_IRAM_OPT is not set +# CONFIG_ESP32_WIFI_RX_IRAM_OPT is not set +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y +CONFIG_WPA_MBEDTLS_CRYPTO=y +CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# CONFIG_WPA_MBO_SUPPORT is not set +# CONFIG_WPA_DPP_SUPPORT is not set +# CONFIG_WPA_11R_SUPPORT is not set +# CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set +# CONFIG_L2_TO_L3_COPY is not set +CONFIG_ESP_GRATUITOUS_ARP=y +CONFIG_GARP_TMR_INTERVAL=60 +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5760 +CONFIG_TCP_WND_DEFAULT=5760 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_HRT is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +# CONFIG_ESP32_ULP_COPROC_ENABLED is not set +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# End of deprecated options diff --git a/sdkconfig.release.old b/sdkconfig.release.old new file mode 100644 index 00000000..8017e96b --- /dev/null +++ b/sdkconfig.release.old @@ -0,0 +1,2197 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) 5.3.2 Project Configuration +# +CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined" +CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined" +CONFIG_SOC_DPORT_WORKAROUND="Not determined" +CONFIG_SOC_CAPS_ECO_VER_MAX=301 +CONFIG_SOC_ADC_SUPPORTED=y +CONFIG_SOC_DAC_SUPPORTED=y +CONFIG_SOC_UART_SUPPORTED=y +CONFIG_SOC_MCPWM_SUPPORTED=y +CONFIG_SOC_GPTIMER_SUPPORTED=y +CONFIG_SOC_SDMMC_HOST_SUPPORTED=y +CONFIG_SOC_BT_SUPPORTED=y +CONFIG_SOC_PCNT_SUPPORTED=y +CONFIG_SOC_PHY_SUPPORTED=y +CONFIG_SOC_WIFI_SUPPORTED=y +CONFIG_SOC_SDIO_SLAVE_SUPPORTED=y +CONFIG_SOC_TWAI_SUPPORTED=y +CONFIG_SOC_EFUSE_SUPPORTED=y +CONFIG_SOC_EMAC_SUPPORTED=y +CONFIG_SOC_ULP_SUPPORTED=y +CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y +CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y +CONFIG_SOC_RTC_MEM_SUPPORTED=y +CONFIG_SOC_I2S_SUPPORTED=y +CONFIG_SOC_RMT_SUPPORTED=y +CONFIG_SOC_SDM_SUPPORTED=y +CONFIG_SOC_GPSPI_SUPPORTED=y +CONFIG_SOC_LEDC_SUPPORTED=y +CONFIG_SOC_I2C_SUPPORTED=y +CONFIG_SOC_SUPPORT_COEXISTENCE=y +CONFIG_SOC_AES_SUPPORTED=y +CONFIG_SOC_MPI_SUPPORTED=y +CONFIG_SOC_SHA_SUPPORTED=y +CONFIG_SOC_FLASH_ENC_SUPPORTED=y +CONFIG_SOC_SECURE_BOOT_SUPPORTED=y +CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y +CONFIG_SOC_BOD_SUPPORTED=y +CONFIG_SOC_ULP_FSM_SUPPORTED=y +CONFIG_SOC_CLK_TREE_SUPPORTED=y +CONFIG_SOC_MPU_SUPPORTED=y +CONFIG_SOC_WDT_SUPPORTED=y +CONFIG_SOC_SPI_FLASH_SUPPORTED=y +CONFIG_SOC_RNG_SUPPORTED=y +CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y +CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y +CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y +CONFIG_SOC_PM_SUPPORTED=y +CONFIG_SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL=5 +CONFIG_SOC_XTAL_SUPPORT_26M=y +CONFIG_SOC_XTAL_SUPPORT_40M=y +CONFIG_SOC_XTAL_SUPPORT_AUTO_DETECT=y +CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DMA_SUPPORTED=y +CONFIG_SOC_ADC_PERIPH_NUM=2 +CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 +CONFIG_SOC_ADC_ATTEN_NUM=4 +CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 +CONFIG_SOC_ADC_PATT_LEN_MAX=16 +CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 +CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=4 +CONFIG_SOC_ADC_DIGI_MONITOR_NUM=0 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=2 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=20 +CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_SHARED_POWER=y +CONFIG_SOC_SHARED_IDCACHE_SUPPORTED=y +CONFIG_SOC_IDCACHE_PER_CORE=y +CONFIG_SOC_CPU_CORES_NUM=2 +CONFIG_SOC_CPU_INTR_NUM=32 +CONFIG_SOC_CPU_HAS_FPU=y +CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y +CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 +CONFIG_SOC_DAC_CHAN_NUM=2 +CONFIG_SOC_DAC_RESOLUTION=8 +CONFIG_SOC_DAC_DMA_16BIT_ALIGN=y +CONFIG_SOC_GPIO_PORT=1 +CONFIG_SOC_GPIO_PIN_COUNT=40 +CONFIG_SOC_GPIO_VALID_GPIO_MASK=0xFFFFFFFFFF +CONFIG_SOC_GPIO_IN_RANGE_MAX=39 +CONFIG_SOC_GPIO_OUT_RANGE_MAX=33 +CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0xEF0FEA +CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y +CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3 +CONFIG_SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP=y +CONFIG_SOC_I2C_NUM=2 +CONFIG_SOC_HP_I2C_NUM=2 +CONFIG_SOC_I2C_FIFO_LEN=32 +CONFIG_SOC_I2C_CMD_REG_NUM=16 +CONFIG_SOC_I2C_SUPPORT_SLAVE=y +CONFIG_SOC_I2C_SUPPORT_APB=y +CONFIG_SOC_I2C_STOP_INDEPENDENT=y +CONFIG_SOC_I2S_NUM=2 +CONFIG_SOC_I2S_HW_VERSION_1=y +CONFIG_SOC_I2S_SUPPORTS_APLL=y +CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y +CONFIG_SOC_I2S_SUPPORTS_PDM=y +CONFIG_SOC_I2S_SUPPORTS_PDM_TX=y +CONFIG_SOC_I2S_PDM_MAX_TX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_PDM_RX=y +CONFIG_SOC_I2S_PDM_MAX_RX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_ADC_DAC=y +CONFIG_SOC_I2S_SUPPORTS_ADC=y +CONFIG_SOC_I2S_SUPPORTS_DAC=y +CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y +CONFIG_SOC_I2S_MAX_DATA_WIDTH=24 +CONFIG_SOC_I2S_TRANS_SIZE_ALIGN_WORD=y +CONFIG_SOC_I2S_LCD_I80_VARIANT=y +CONFIG_SOC_LCD_I80_SUPPORTED=y +CONFIG_SOC_LCD_I80_BUSES=2 +CONFIG_SOC_LCD_I80_BUS_WIDTH=24 +CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y +CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y +CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y +CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y +CONFIG_SOC_LEDC_CHANNEL_NUM=8 +CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=20 +CONFIG_SOC_MCPWM_GROUPS=2 +CONFIG_SOC_MCPWM_TIMERS_PER_GROUP=3 +CONFIG_SOC_MCPWM_OPERATORS_PER_GROUP=3 +CONFIG_SOC_MCPWM_COMPARATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GENERATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_TRIGGERS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GPIO_FAULTS_PER_GROUP=3 +CONFIG_SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP=y +CONFIG_SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER=3 +CONFIG_SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP=3 +CONFIG_SOC_MMU_PERIPH_NUM=2 +CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=3 +CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 +CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 +CONFIG_SOC_PCNT_GROUPS=1 +CONFIG_SOC_PCNT_UNITS_PER_GROUP=8 +CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 +CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 +CONFIG_SOC_RMT_GROUPS=1 +CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_CHANNELS_PER_GROUP=8 +CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 +CONFIG_SOC_RMT_SUPPORT_REF_TICK=y +CONFIG_SOC_RMT_SUPPORT_APB=y +CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y +CONFIG_SOC_RTCIO_PIN_COUNT=18 +CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y +CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y +CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_SDM_GROUPS=1 +CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 +CONFIG_SOC_SDM_CLK_SUPPORT_APB=y +CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y +CONFIG_SOC_SPI_AS_CS_SUPPORTED=y +CONFIG_SOC_SPI_PERIPH_NUM=3 +CONFIG_SOC_SPI_DMA_CHAN_NUM=2 +CONFIG_SOC_SPI_MAX_CS_NUM=3 +CONFIG_SOC_SPI_SUPPORT_CLK_APB=y +CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=64 +CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 +CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y +CONFIG_SOC_TIMER_GROUPS=2 +CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 +CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 +CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y +CONFIG_SOC_TOUCH_SENSOR_VERSION=1 +CONFIG_SOC_TOUCH_SENSOR_NUM=10 +CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1 +CONFIG_SOC_TWAI_CONTROLLER_NUM=1 +CONFIG_SOC_TWAI_BRP_MIN=2 +CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y +CONFIG_SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT=y +CONFIG_SOC_UART_NUM=3 +CONFIG_SOC_UART_HP_NUM=3 +CONFIG_SOC_UART_SUPPORT_APB_CLK=y +CONFIG_SOC_UART_SUPPORT_REF_TICK=y +CONFIG_SOC_UART_FIFO_LEN=128 +CONFIG_SOC_UART_BITRATE_MAX=5000000 +CONFIG_SOC_SPIRAM_SUPPORTED=y +CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y +CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG=y +CONFIG_SOC_SHA_ENDIANNESS_BE=y +CONFIG_SOC_SHA_SUPPORT_SHA1=y +CONFIG_SOC_SHA_SUPPORT_SHA256=y +CONFIG_SOC_SHA_SUPPORT_SHA384=y +CONFIG_SOC_SHA_SUPPORT_SHA512=y +CONFIG_SOC_MPI_MEM_BLOCKS_NUM=4 +CONFIG_SOC_MPI_OPERATIONS_NUM=y +CONFIG_SOC_RSA_MAX_BIT_LEN=4096 +CONFIG_SOC_AES_SUPPORT_AES_128=y +CONFIG_SOC_AES_SUPPORT_AES_192=y +CONFIG_SOC_AES_SUPPORT_AES_256=y +CONFIG_SOC_SECURE_BOOT_V1=y +CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=y +CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=32 +CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 +CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y +CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y +CONFIG_SOC_PM_SUPPORT_MODEM_PD=y +CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y +CONFIG_SOC_CLK_APLL_SUPPORTED=y +CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y +CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y +CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y +CONFIG_SOC_SDMMC_USE_IOMUX=y +CONFIG_SOC_SDMMC_NUM_SLOTS=2 +CONFIG_SOC_WIFI_WAPI_SUPPORT=y +CONFIG_SOC_WIFI_CSI_SUPPORT=y +CONFIG_SOC_WIFI_MESH_SUPPORT=y +CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y +CONFIG_SOC_WIFI_NAN_SUPPORT=y +CONFIG_SOC_BLE_SUPPORTED=y +CONFIG_SOC_BLE_MESH_SUPPORTED=y +CONFIG_SOC_BT_CLASSIC_SUPPORTED=y +CONFIG_SOC_BLUFI_SUPPORTED=y +CONFIG_SOC_BT_H2C_ENC_KEY_CTRL_ENH_VSC_SUPPORTED=y +CONFIG_SOC_ULP_HAS_ADC=y +CONFIG_SOC_PHY_COMBO_MODULE=y +CONFIG_SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK=y +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TOOLCHAIN="gcc" +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET_ARCH="xtensa" +CONFIG_IDF_TARGET="esp32" +CONFIG_IDF_INIT_VERSION="5.4.1" +CONFIG_IDF_TARGET_ESP32=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# CONFIG_APP_REPRODUCIBLE_BUILD is not set +# CONFIG_APP_NO_BLOBS is not set +# CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# end of Build type + +# +# Bootloader config +# + +# +# Bootloader manager +# +CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y +CONFIG_BOOTLOADER_PROJECT_VER=1 +# end of Bootloader manager + +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=3 + +# +# Serial Flash Configurations +# +# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +# end of Serial Flash Configurations + +# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_V1_SUPPORTED=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +# end of Security features + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 +# end of Application manager + +CONFIG_ESP_ROM_HAS_CRC_LE=y +CONFIG_ESP_ROM_HAS_CRC_BE=y +CONFIG_ESP_ROM_HAS_MZ_CRC32=y +CONFIG_ESP_ROM_HAS_JPEG_DECODE=y +CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y +CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y +CONFIG_ESP_ROM_HAS_NEWLIB=y +CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y +CONFIG_ESP_ROM_HAS_NEWLIB_32BIT_TIME=y +CONFIG_ESP_ROM_HAS_SW_FLOAT=y +CONFIG_ESP_ROM_USB_OTG_NUM=-1 +CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1 +CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y + +# +# Serial flasher config +# +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHMODE="dio" +# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="40m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="2MB" +# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_CUSTOM is not set +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Arduino Configuration +# +CONFIG_ARDUINO_VARIANT="esp32" +CONFIG_ENABLE_ARDUINO_DEPENDS=y +# CONFIG_AUTOSTART_ARDUINO is not set +# CONFIG_ARDUINO_RUN_CORE0 is not set +CONFIG_ARDUINO_RUN_CORE1=y +# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_RUNNING_CORE=1 +CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 +# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set +CONFIG_ARDUINO_EVENT_RUN_CORE1=y +# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set +CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y +CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=2048 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 +CONFIG_ARDUINO_UDP_RUN_CORE0=y +# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set +# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_UDP_RUNNING_CORE=0 +CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 +# CONFIG_ARDUINO_ISR_IRAM is not set +# CONFIG_DISABLE_HAL_LOCKS is not set + +# +# Debug Log Configuration +# +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE=y +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=0 +# CONFIG_ARDUHAL_LOG_COLORS is not set +# CONFIG_ARDUHAL_ESP_LOG is not set +# end of Debug Log Configuration + +# CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set +CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS=y +CONFIG_ARDUHAL_PARTITION_SCHEME="min_spiffs" +CONFIG_ARDUINO_SELECTIVE_COMPILATION=y +CONFIG_ARDUINO_SELECTIVE_SPI=y +CONFIG_ARDUINO_SELECTIVE_Wire=y +CONFIG_ARDUINO_SELECTIVE_ESP_SR=y +CONFIG_ARDUINO_SELECTIVE_EEPROM=y +# CONFIG_ARDUINO_SELECTIVE_Preferences is not set +# CONFIG_ARDUINO_SELECTIVE_Ticker is not set +CONFIG_ARDUINO_SELECTIVE_Update=y +# CONFIG_ARDUINO_SELECTIVE_Zigbee is not set +CONFIG_ARDUINO_SELECTIVE_FS=y +# CONFIG_ARDUINO_SELECTIVE_SD is not set +# CONFIG_ARDUINO_SELECTIVE_SD_MMC is not set +# CONFIG_ARDUINO_SELECTIVE_SPIFFS is not set +# CONFIG_ARDUINO_SELECTIVE_FFat is not set +CONFIG_ARDUINO_SELECTIVE_LittleFS=y +CONFIG_ARDUINO_SELECTIVE_Network=y +# CONFIG_ARDUINO_SELECTIVE_Ethernet is not set +CONFIG_ARDUINO_SELECTIVE_PPP=y +CONFIG_ARDUINO_SELECTIVE_ArduinoOTA=y +CONFIG_ARDUINO_SELECTIVE_AsyncUDP=y +CONFIG_ARDUINO_SELECTIVE_DNSServer=y +CONFIG_ARDUINO_SELECTIVE_ESPmDNS=y +CONFIG_ARDUINO_SELECTIVE_HTTPClient=y +# CONFIG_ARDUINO_SELECTIVE_Matter is not set +# CONFIG_ARDUINO_SELECTIVE_NetBIOS is not set +CONFIG_ARDUINO_SELECTIVE_WebServer=y +CONFIG_ARDUINO_SELECTIVE_WiFi=y +CONFIG_ARDUINO_SELECTIVE_NetworkClientSecure=y +CONFIG_ARDUINO_SELECTIVE_WiFiProv=y +CONFIG_ARDUINO_SELECTIVE_BLE=y +# CONFIG_ARDUINO_SELECTIVE_BluetoothSerial is not set +CONFIG_ARDUINO_SELECTIVE_SimpleBLE=y +# CONFIG_ARDUINO_SELECTIVE_RainMaker is not set +# CONFIG_ARDUINO_SELECTIVE_OpenThread is not set +# CONFIG_ARDUINO_SELECTIVE_Insights is not set +# end of Arduino Configuration + +# +# Compiler options +# +CONFIG_COMPILER_OPTIMIZATION_DEBUG=y +# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set +# CONFIG_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set +CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +CONFIG_COMPILER_RT_LIB_GCCLIB=y +CONFIG_COMPILER_RT_LIB_NAME="gcc" +CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y +# CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_JTAG is not set +CONFIG_APPTRACE_DEST_NONE=y +# CONFIG_APPTRACE_DEST_UART1 is not set +# CONFIG_APPTRACE_DEST_UART2 is not set +CONFIG_APPTRACE_DEST_UART_NONE=y +CONFIG_APPTRACE_UART_TASK_PRIO=1 +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# Bluetooth +# +CONFIG_BT_ENABLED=y +# CONFIG_BT_BLUEDROID_ENABLED is not set +CONFIG_BT_NIMBLE_ENABLED=y +# CONFIG_BT_CONTROLLER_ONLY is not set +CONFIG_BT_CONTROLLER_ENABLED=y +# CONFIG_BT_CONTROLLER_DISABLED is not set + +# +# NimBLE Options +# +CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y +# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_NONE is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_WARNING is not set +CONFIG_BT_NIMBLE_LOG_LEVEL_INFO=y +# CONFIG_BT_NIMBLE_LOG_LEVEL_DEBUG is not set +CONFIG_BT_NIMBLE_LOG_LEVEL=1 +CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 +CONFIG_BT_NIMBLE_MAX_BONDS=1 +CONFIG_BT_NIMBLE_MAX_CCCDS=1 +CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM=0 +CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y +# CONFIG_BT_NIMBLE_PINNED_TO_CORE_1 is not set +CONFIG_BT_NIMBLE_PINNED_TO_CORE=0 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=4096 +CONFIG_BT_NIMBLE_ROLE_CENTRAL=y +CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y +CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y +CONFIG_BT_NIMBLE_ROLE_OBSERVER=y +# CONFIG_BT_NIMBLE_NVS_PERSIST is not set +# CONFIG_BT_NIMBLE_SMP_ID_RESET is not set +# CONFIG_BT_NIMBLE_SECURITY_ENABLE is not set +# CONFIG_BT_NIMBLE_DEBUG is not set +# CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set +CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" +CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 +CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=256 +CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE=0 + +# +# Memory Settings +# +CONFIG_BT_NIMBLE_MSYS_1_BLOCK_COUNT=12 +CONFIG_BT_NIMBLE_MSYS_1_BLOCK_SIZE=256 +CONFIG_BT_NIMBLE_MSYS_2_BLOCK_COUNT=24 +CONFIG_BT_NIMBLE_MSYS_2_BLOCK_SIZE=320 +CONFIG_BT_NIMBLE_TRANSPORT_ACL_FROM_LL_COUNT=24 +CONFIG_BT_NIMBLE_TRANSPORT_ACL_SIZE=255 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_COUNT=30 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_DISCARD_COUNT=8 +CONFIG_BT_NIMBLE_L2CAP_COC_SDU_BUFF_COUNT=1 +# end of Memory Settings + +CONFIG_BT_NIMBLE_GATT_MAX_PROCS=4 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL=y +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y +CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 +# CONFIG_BT_NIMBLE_MESH is not set +CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y +CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 +# CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set +# CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set +CONFIG_BT_NIMBLE_WHITELIST_SIZE=1 +# CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set +# CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set +CONFIG_BT_NIMBLE_USE_ESP_TIMER=y +CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y +# CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set + +# +# GAP Service +# + +# +# GAP Appearance write permissions +# +# CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set +# end of GAP Appearance write permissions + +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ENC=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHN=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHR=0 +CONFIG_BT_NIMBLE_SVC_GAP_CAR_CHAR_NOT_SUPP=y +# CONFIG_BT_NIMBLE_SVC_GAP_CAR_NOT_SUPP is not set +# CONFIG_BT_NIMBLE_SVC_GAP_CAR_SUPP is not set +CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 + +# +# GAP device name write permissions +# +# CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set +# end of GAP device name write permissions + +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_ENC=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHEN=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHOR=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 +# CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL is not set +# end of GAP Service + +# +# BLE Services +# +# CONFIG_BT_NIMBLE_HID_SERVICE is not set +# CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY is not set + +# +# Device Information Service +# +# CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME is not set +# CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER is not set +# CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION is not set +# CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION is not set +# CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION is not set +# CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID is not set +# CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID is not set +# CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED is not set +# end of Device Information Service +# end of BLE Services + +# CONFIG_BT_NIMBLE_VS_SUPPORT is not set +# CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set +# CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set +# CONFIG_BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN is not set +# CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set + +# +# Host-controller Transport +# +CONFIG_UART_HW_FLOWCTRL_DISABLE=y +# CONFIG_UART_HW_FLOWCTRL_CTS_RTS is not set +CONFIG_BT_NIMBLE_HCI_UART_FLOW_CTRL=0 +CONFIG_BT_NIMBLE_HCI_UART_RTS_PIN=19 +CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 +# end of Host-controller Transport + +CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 +# CONFIG_BT_NIMBLE_SUBRATE is not set +# end of NimBLE Options + +# +# Controller Options +# +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +# CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set +# CONFIG_BTDM_CTRL_MODE_BTDM is not set +CONFIG_BTDM_CTRL_BLE_MAX_CONN=3 +CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 +CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 +CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 +CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=3 +CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CTRL_PINNED_TO_CORE_0=y +# CONFIG_BTDM_CTRL_PINNED_TO_CORE_1 is not set +CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 +CONFIG_BTDM_CTRL_HCI_MODE_VHCI=y +# CONFIG_BTDM_CTRL_HCI_MODE_UART_H4 is not set + +# +# MODEM SLEEP Options +# +CONFIG_BTDM_CTRL_MODEM_SLEEP=y +CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG=y +# CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_EVED is not set +CONFIG_BTDM_CTRL_LPCLK_SEL_MAIN_XTAL=y +# end of MODEM SLEEP Options + +CONFIG_BTDM_BLE_DEFAULT_SCA_250PPM=y +CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 +CONFIG_BTDM_BLE_SCAN_DUPL=y +CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y +# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA is not set +# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE is not set +CONFIG_BTDM_SCAN_DUPL_TYPE=0 +CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 +CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 +# CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set +CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y +# CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set +# CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set +CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y +CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 +CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 + +# +# BLE disconnect when instant passed +# +# CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set +# CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set +# end of BLE disconnect when instant passed + +CONFIG_BTDM_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_CTRL_HLI=y +# end of Controller Options + +# +# Common Options +# +CONFIG_BT_ALARM_MAX_NUM=50 +# end of Common Options + +# CONFIG_BT_HCI_LOG_DEBUG_EN is not set +# end of Bluetooth + +# CONFIG_BLE_MESH is not set + +# +# Console Library +# +# CONFIG_CONSOLE_SORTED_HELP is not set +# end of Console Library + +# +# Driver Configurations +# + +# +# TWAI Configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y +CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y +CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID=y +CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT=y +CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y +# end of TWAI Configuration + +# +# Legacy ADC Driver Configuration +# +CONFIG_ADC_DISABLE_DAC=y +# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set + +# +# Legacy ADC Calibration Configuration +# +CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y +CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CAL_LUT_ENABLE=y +# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy ADC Calibration Configuration +# end of Legacy ADC Driver Configuration + +# +# Legacy DAC Driver Configurations +# +# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy DAC Driver Configurations + +# +# Legacy MCPWM Driver Configurations +# +# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy MCPWM Driver Configurations + +# +# Legacy Timer Group Driver Configurations +# +# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy Timer Group Driver Configurations + +# +# Legacy RMT Driver Configurations +# +# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy RMT Driver Configurations + +# +# Legacy I2S Driver Configurations +# +# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy I2S Driver Configurations + +# +# Legacy PCNT Driver Configurations +# +# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy PCNT Driver Configurations + +# +# Legacy SDM Driver Configurations +# +# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy SDM Driver Configurations +# end of Driver Configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set +CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set +CONFIG_EFUSE_MAX_BLK_LEN=192 +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +# CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set +# CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + +# +# ADC and ADC Calibration +# +# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set + +# +# ADC Calibration Configurations +# +CONFIG_ADC_CALI_EFUSE_TP_ENABLE=y +CONFIG_ADC_CALI_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CALI_LUT_ENABLE=y +# end of ADC Calibration Configurations + +CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# CONFIG_ADC_ENABLE_DEBUG_LOG is not set +# end of ADC and ADC Calibration + +# +# Wireless Coexistence +# +CONFIG_ESP_COEX_ENABLED=y +CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y +# CONFIG_ESP_COEX_POWER_MANAGEMENT is not set +# CONFIG_ESP_COEX_GPIO_DEBUG is not set +# end of Wireless Coexistence + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# end of Common ESP-related + +# +# ESP-Driver:DAC Configurations +# +# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# CONFIG_DAC_ISR_IRAM_SAFE is not set +# CONFIG_DAC_ENABLE_DEBUG_LOG is not set +CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y +# end of ESP-Driver:DAC Configurations + +# +# ESP-Driver:GPIO Configurations +# +# CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set +# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:GPIO Configurations + +# +# ESP-Driver:GPTimer Configurations +# +CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y +# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:GPTimer Configurations + +# +# ESP-Driver:I2C Configurations +# +# CONFIG_I2C_ISR_IRAM_SAFE is not set +# CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:I2C Configurations + +# +# ESP-Driver:I2S Configurations +# +# CONFIG_I2S_ISR_IRAM_SAFE is not set +# CONFIG_I2S_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:I2S Configurations + +# +# ESP-Driver:LEDC Configurations +# +# CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:LEDC Configurations + +# +# ESP-Driver:MCPWM Configurations +# +# CONFIG_MCPWM_ISR_IRAM_SAFE is not set +# CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:MCPWM Configurations + +# +# ESP-Driver:PCNT Configurations +# +# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_PCNT_ISR_IRAM_SAFE is not set +# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:PCNT Configurations + +# +# ESP-Driver:RMT Configurations +# +# CONFIG_RMT_ISR_IRAM_SAFE is not set +# CONFIG_RMT_RECV_FUNC_IN_IRAM is not set +# CONFIG_RMT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:RMT Configurations + +# +# ESP-Driver:Sigma Delta Modulator Configurations +# +# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_SDM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Sigma Delta Modulator Configurations + +# +# ESP-Driver:SPI Configurations +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of ESP-Driver:SPI Configurations + +# +# ESP-Driver:Touch Sensor Configurations +# +# CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set +# CONFIG_TOUCH_ISR_IRAM_SAFE is not set +# CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Touch Sensor Configurations + +# +# ESP-Driver:UART Configurations +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of ESP-Driver:UART Configurations + +# +# Ethernet +# +# CONFIG_ETH_USE_ESP32_EMAC is not set +# CONFIG_ETH_USE_SPI_ETHERNET is not set +# CONFIG_ETH_USE_OPENETH is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +CONFIG_ESP_GDBSTUB_ENABLED=y +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set +CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y +CONFIG_ESP_GDBSTUB_MAX_TASKS=32 +# end of GDB Stub + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +# end of ESP HTTPS server + +# +# Hardware Settings +# + +# +# Chip revision +# +CONFIG_ESP32_REV_MIN_0=y +# CONFIG_ESP32_REV_MIN_1 is not set +# CONFIG_ESP32_REV_MIN_1_1 is not set +# CONFIG_ESP32_REV_MIN_2 is not set +# CONFIG_ESP32_REV_MIN_3 is not set +# CONFIG_ESP32_REV_MIN_3_1 is not set +CONFIG_ESP32_REV_MIN=0 +CONFIG_ESP32_REV_MIN_FULL=0 +CONFIG_ESP_REV_MIN_FULL=0 + +# +# Maximum Supported ESP32 Revision (Rev v3.99) +# +CONFIG_ESP32_REV_MAX_FULL=399 +CONFIG_ESP_REV_MAX_FULL=399 +CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL=0 +CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL=99 + +# +# Maximum Supported ESP32 eFuse Block Revision (eFuse Block Rev v0.99) +# +# end of Chip revision + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set +# CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set +# end of MAC Config + +# +# Sleep Config +# +# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set +CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +# CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set +CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set +CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 +# CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set +# CONFIG_ESP_SLEEP_DEBUG is not set +CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y +# end of Sleep Config + +# +# RTC Clock Config +# +CONFIG_RTC_CLK_SRC_INT_RC=y +# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_RTC_CLK_CAL_CYCLES=1024 +# end of RTC Clock Config + +# +# Peripheral Control +# +CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y +# end of Peripheral Control + +# +# Main XTAL Config +# +# CONFIG_XTAL_FREQ_26 is not set +CONFIG_XTAL_FREQ_40=y +# CONFIG_XTAL_FREQ_AUTO is not set +CONFIG_XTAL_FREQ=40 +# end of Main XTAL Config + +CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y +# end of Hardware Settings + +# +# LCD and Touch Panel +# + +# +# LCD Touch Drivers are maintained in the IDF Component Registry +# + +# +# LCD Peripheral Configuration +# +# CONFIG_LCD_ENABLE_DEBUG_LOG is not set +# end of LCD Peripheral Configuration +# end of LCD and Touch Panel + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# CONFIG_ESP_NETIF_L2_TAP is not set +# CONFIG_ESP_NETIF_BRIDGE_EN is not set +# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set +# end of ESP NETIF Adapter + +# +# Partition API Configuration +# +# end of Partition API Configuration + +# +# PHY +# +CONFIG_ESP_PHY_ENABLED=y +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set +# CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set +CONFIG_ESP_PHY_RF_CAL_PARTIAL=y +# CONFIG_ESP_PHY_RF_CAL_NONE is not set +# CONFIG_ESP_PHY_RF_CAL_FULL is not set +CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# end of PHY + +# +# Power Management +# +# CONFIG_PM_ENABLE is not set +# CONFIG_PM_SLP_IRAM_OPT is not set +# end of Power Management + +# +# ESP PSRAM +# +# CONFIG_SPIRAM is not set +# end of ESP PSRAM + +# +# ESP Ringbuf +# +# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set +# end of ESP Ringbuf + +# +# ESP System Settings +# +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 + +# +# Memory +# +# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set + +# +# Non-backward compatible options +# +# CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set +# end of Non-backward compatible options +# end of Memory + +# +# Trace memory +# +# CONFIG_ESP32_TRAX is not set +CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 +# end of Trace memory + +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 + +# +# Memory protection +# +# end of Memory protection + +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 +CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set +# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_INT_WDT_CHECK_CPU1=y +CONFIG_ESP_TASK_WDT_EN=y +CONFIG_ESP_TASK_WDT_INIT=y +# CONFIG_ESP_TASK_WDT_PANIC is not set +CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP_DEBUG_OCDAWARE=y +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y + +# +# Brownout Detector +# +CONFIG_ESP_BROWNOUT_DET=y +CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_ESP_BROWNOUT_DET_LVL=0 +# end of Brownout Detector + +# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set +CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y +# end of ESP System Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y +CONFIG_ESP_IPC_ISR_ENABLE=y +# end of IPC (Inter-Processor Call) + +# +# ESP Timer (High Resolution Timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set +CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 +CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y +CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +CONFIG_ESP_TIMER_IMPL_TG0_LAC=y +# end of ESP Timer (High Resolution Timer) + +# +# Wi-Fi +# +CONFIG_ESP_WIFI_ENABLED=y +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 +CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 +# CONFIG_ESP_WIFI_CSI_ENABLED is not set +CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP_WIFI_TX_BA_WIN=6 +CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP_WIFI_RX_BA_WIN=6 +CONFIG_ESP_WIFI_NVS_ENABLED=y +CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +# CONFIG_ESP_WIFI_IRAM_OPT is not set +# CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set +# CONFIG_ESP_WIFI_RX_IRAM_OPT is not set +CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP_WIFI_ENABLE_SAE_PK=y +CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 +CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 +CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 +CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y +CONFIG_ESP_WIFI_GMAC_SUPPORT=y +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set +CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# CONFIG_ESP_WIFI_NAN_ENABLE is not set +CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y +CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# CONFIG_ESP_WIFI_WAPI_PSK is not set +# CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# CONFIG_ESP_WIFI_11R_SUPPORT is not set +# CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set + +# +# WPS Configuration Options +# +# CONFIG_ESP_WIFI_WPS_STRICT is not set +# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set +# end of WPS Configuration Options + +# CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set +CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y +# CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set +# end of Wi-Fi + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +CONFIG_FATFS_VOLUME_COUNT=2 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +# CONFIG_FATFS_SECTOR_512 is not set +CONFIG_FATFS_SECTOR_4096=y +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# CONFIG_FATFS_IMMEDIATE_FSYNC is not set +# CONFIG_FATFS_USE_LABEL is not set +CONFIG_FATFS_LINK_LOCK=y +# end of FAT Filesystem support + +# +# FreeRTOS +# + +# +# Kernel +# +# CONFIG_FREERTOS_SMP is not set +# CONFIG_FREERTOS_UNICORE is not set +CONFIG_FREERTOS_HZ=1000 +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +# CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# CONFIG_FREERTOS_USE_TICK_HOOK is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set +CONFIG_FREERTOS_TIMER_TASK_NO_AFFINITY=y +CONFIG_FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set +# end of Kernel + +# +# Port +# +CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# CONFIG_FREERTOS_FPU_IN_ISR is not set +CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# end of Port + +CONFIG_FREERTOS_PORT=y +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y +CONFIG_FREERTOS_NUMBER_OF_CORES=2 +# end of FreeRTOS + +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILENT is not set +# CONFIG_HAL_ASSERTION_ENABLE is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 +CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y +CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y +# CONFIG_HAL_ECDSA_GEN_SIG_CM is not set +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_USE_HOOKS is not set +# CONFIG_HEAP_TASK_TRACKING is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set +# end of Heap memory debugging + +# +# Log output +# +CONFIG_LOG_DEFAULT_LEVEL_NONE=y +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=0 +CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_ERROR is not set +# CONFIG_LOG_MAXIMUM_LEVEL_WARN is not set +# CONFIG_LOG_MAXIMUM_LEVEL_INFO is not set +# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=0 +# CONFIG_LOG_MASTER_LEVEL is not set +# CONFIG_LOG_COLORS is not set +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Log output + +# +# LWIP +# +CONFIG_LWIP_ENABLE=y +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# CONFIG_LWIP_NETIF_API is not set +CONFIG_LWIP_TCPIP_TASK_PRIO=18 +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_ND6=y +# CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +CONFIG_LWIP_SO_RCVBUF=y +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP_DEFAULT_TTL=64 +CONFIG_LWIP_IP4_FRAG=y +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +# CONFIG_LWIP_IP6_REASSEMBLY is not set +CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_ESP_MLDV6_REPORT=y +CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 +CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 + +# +# DHCP server +# +CONFIG_LWIP_DHCPS=y +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV4=y +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5760 +CONFIG_LWIP_TCP_WND_DEFAULT=5760 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 +CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 +CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 +CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +CONFIG_LWIP_SNTP_STARTUP_DELAY=y +CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 +# end of SNTP + +# +# DNS +# +CONFIG_LWIP_DNS_MAX_HOST_IP=1 +CONFIG_LWIP_DNS_MAX_SERVERS=3 +# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set +# CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set +# end of DNS + +CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y +# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set +CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y +# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set +# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_NONE=y +# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_CUSTOM is not set +# CONFIG_LWIP_HOOK_IP6_INPUT_NONE is not set +CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y +# CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set + +# +# mbedTLS v3.x related +# +# CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set +# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set +CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y +CONFIG_MBEDTLS_PKCS7_C=y +# end of mbedTLS v3.x related + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y +# CONFIG_MBEDTLS_SHA3_C is not set +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +CONFIG_MBEDTLS_PSK_MODES=y +CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +# CONFIG_MBEDTLS_DHM_C is not set +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +CONFIG_MBEDTLS_ERROR_STRINGS=y +CONFIG_MBEDTLS_FS_IO=y +# end of mbedTLS + +# +# ESP-MQTT Configurations +# +# CONFIG_MQTT_PROTOCOL_311 is not set +# CONFIG_MQTT_PROTOCOL_5 is not set +# CONFIG_MQTT_TRANSPORT_SSL is not set +# CONFIG_MQTT_TRANSPORT_WEBSOCKET is not set +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set +# end of Newlib + +# +# NVS +# +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set +# end of NVS + +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set + +# +# OpenThread Spinel +# +# CONFIG_OPENTHREAD_SPINEL_ONLY is not set +# end of OpenThread Spinel +# end of OpenThread + +# +# Protocomm +# +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +# end of Protocomm + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y +# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set +# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# MMU Config +# +CONFIG_MMU_PAGE_SIZE_64KB=y +CONFIG_MMU_PAGE_MODE="64KB" +CONFIG_MMU_PAGE_SIZE=0x10000 +# end of MMU Config + +# +# Main Flash configuration +# + +# +# SPI Flash behavior when brownout +# +CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y +CONFIG_SPI_FLASH_BROWNOUT_RESET=y +# end of SPI Flash behavior when brownout + +# +# Optional and Experimental Features (READ DOCS FIRST) +# + +# +# Features here require specific hardware (READ DOCS FIRST!) +# +CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 +# CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set +# end of Optional and Experimental Features (READ DOCS FIRST) +# end of Main Flash configuration + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y +CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +CONFIG_WS_TRANSPORT=y +CONFIG_WS_BUFFER_SIZE=1024 +# CONFIG_WS_DYNAMIC_BUFFER is not set +# end of Websocket +# end of TCP Transport + +# +# Ultra Low Power (ULP) Co-processor +# +# CONFIG_ULP_COPROC_ENABLED is not set + +# +# ULP Debugging Options +# +# end of ULP Debugging Options +# end of Ultra Low Power (ULP) Co-processor + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_64BIT is not set +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +# CONFIG_VFS_SELECT_IN_RAM is not set +CONFIG_VFS_SUPPORT_TERMIOS=y +CONFIG_VFS_MAX_COUNT=8 + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# end of Host File System I/O (Semihosting) +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_WIFI_PROV_BLE_BONDING is not set +CONFIG_WIFI_PROV_BLE_SEC_CONN=y +# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set +# CONFIG_WIFI_PROV_BLE_NOTIFY is not set +# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set +CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y +# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set +# end of Wi-Fi Provisioning Manager + +# +# Zigbee +# +# CONFIG_ZB_ENABLED is not set +# end of Zigbee + +# +# esp-modem +# +CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y +# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set +CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 +# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set +# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set +CONFIG_ESP_MODEM_C_API_STR_MAX=128 +# CONFIG_ESP_MODEM_URC_HANDLER is not set +# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set +# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set +# end of esp-modem + +# +# mDNS +# +CONFIG_MDNS_MAX_INTERFACES=3 +CONFIG_MDNS_MAX_SERVICES=10 +CONFIG_MDNS_TASK_PRIORITY=1 +CONFIG_MDNS_ACTION_QUEUE_LEN=16 +CONFIG_MDNS_TASK_STACK_SIZE=4096 +# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_MDNS_TASK_AFFINITY_CPU0=y +# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set +CONFIG_MDNS_TASK_AFFINITY=0x0 + +# +# MDNS Memory Configuration +# +CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y +CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y +# CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set +# end of MDNS Memory Configuration + +CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 +CONFIG_MDNS_TIMER_PERIOD_MS=100 +# CONFIG_MDNS_NETWORKING_SOCKET is not set +# CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set +# CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set +CONFIG_MDNS_ENABLE_CONSOLE_CLI=y +# CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set +CONFIG_MDNS_MULTIPLE_INSTANCE=y + +# +# MDNS Predefined interfaces +# +CONFIG_MDNS_PREDEF_NETIF_STA=y +CONFIG_MDNS_PREDEF_NETIF_AP=y +# end of MDNS Predefined interfaces +# end of mDNS + +# +# Network Provisioning Manager +# +CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y +CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_NETWORK_PROV_BLE_BONDING is not set +CONFIG_NETWORK_PROV_BLE_SEC_CONN=y +# CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set +# CONFIG_NETWORK_PROV_KEEP_BLE_ON_AFTER_PROV is not set +CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y +# CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set +# end of Network Provisioning Manager + +# +# LittleFS +# +# CONFIG_LITTLEFS_SDMMC_SUPPORT is not set +CONFIG_LITTLEFS_MAX_PARTITIONS=3 +CONFIG_LITTLEFS_PAGE_SIZE=256 +CONFIG_LITTLEFS_OBJ_NAME_LEN=64 +CONFIG_LITTLEFS_READ_SIZE=128 +CONFIG_LITTLEFS_WRITE_SIZE=128 +CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 +CONFIG_LITTLEFS_CACHE_SIZE=512 +CONFIG_LITTLEFS_BLOCK_CYCLES=512 +CONFIG_LITTLEFS_USE_MTIME=y +# CONFIG_LITTLEFS_USE_ONLY_HASH is not set +# CONFIG_LITTLEFS_HUMAN_READABLE is not set +CONFIG_LITTLEFS_MTIME_USE_SECONDS=y +# CONFIG_LITTLEFS_MTIME_USE_NONCE is not set +# CONFIG_LITTLEFS_SPIFFS_COMPAT is not set +# CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set +# CONFIG_LITTLEFS_FCNTL_GET_PATH is not set +# CONFIG_LITTLEFS_MULTIVERSION is not set +# CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set +CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y +# CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set +CONFIG_LITTLEFS_ASSERTS=y +# CONFIG_LITTLEFS_MMAP_PARTITION is not set +# end of LittleFS +# end of Component config + +# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..483bc0cf --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,6 @@ +# This file was automatically generated for projects +# without default 'CMakeLists.txt' file. + +FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*) + +idf_component_register(SRCS ${app_sources}) diff --git a/src/Main.cpp b/src/Main.cpp index 47d2db11..92de8f73 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -7,6 +7,7 @@ #include "Main.h" #include "SS2KLog.h" +#include "esp_system.h" #include #include #include @@ -74,7 +75,8 @@ void SS2K::stopTasks() { } } -void setup() { +extern "C" void app_main() { + initArduino(); // Serial port for debugging purposes Serial.begin(115200); SS2K_LOG(MAIN_LOG_TAG, "Compiled %s%s", __DATE__, __TIME__); diff --git a/src/SS2KLog.cpp b/src/SS2KLog.cpp index cbe1e647..bc83c437 100644 --- a/src/SS2KLog.cpp +++ b/src/SS2KLog.cpp @@ -21,11 +21,7 @@ void LogHandler::addAppender(ILogAppender *appender) { _appenders.push_back(appe void LogHandler::initialize() { for (ILogAppender *appender : _appenders) { - try { - appender->Initialize(); - } catch (...) { - SS2K_LOG(LOG_HANDLER_TAG, "Fatal error during initialize of log appender."); - } + appender->Initialize(); } } @@ -41,11 +37,7 @@ void LogHandler::writeLogs() { buffer[receivedBytes] = '\0'; for (ILogAppender *appender : _appenders) { - try { appender->Log(buffer); - } catch (...) { - SS2K_LOG(LOG_HANDLER_TAG, "Fatal error during writing to log appender."); - } } } SS2K_LOG(LOG_HANDLER_TAG, "Exit writeLogs(). Messages remaining in buffer."); From f5e95fe22ec300a103b6cd92d051f18c61053699 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 24 Jun 2025 14:57:05 -0500 Subject: [PATCH 246/451] trying to compile with espressif plugin --- .vscode/settings.json | 2 +- CMakeLists.txt | 8 +- dependencies.lock | 13 +- include/CMakeLists.txt | 6 + sdkconfig.old | 2103 --------------------------------- sdkconfig.release | 2548 ---------------------------------------- sdkconfig.release.old | 2197 ---------------------------------- src/CMakeLists.txt | 3 +- 8 files changed, 25 insertions(+), 6855 deletions(-) create mode 100644 include/CMakeLists.txt delete mode 100644 sdkconfig.old delete mode 100644 sdkconfig.release delete mode 100644 sdkconfig.release.old diff --git a/.vscode/settings.json b/.vscode/settings.json index 2888d84a..baf137d4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -119,6 +119,6 @@ "VERSIONFILE", "WEBSERVER" ], - "idf.pythonInstallPath": "/opt/homebrew/bin/python3", + "idf.pythonInstallPath": "C:\\Users\\anthony\\.espressif\\tools\\idf-python\\3.11.2\\python.exe", "idf.flashType": "UART", } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a5f975e..39913c92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.16.0) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(SmartSpin2k) -include_directories( - ${PROJECT_SOURCE_DIR}/include - ${PROJECT_SOURCE_DIR}/src -) \ No newline at end of file +add_subdirectory(include) + + + diff --git a/dependencies.lock b/dependencies.lock index 3aef0ca5..937a8ec5 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -41,6 +41,16 @@ dependencies: registry_url: https://components.espressif.com/ type: service version: 1.6.3 + espressif/esp_modem: + component_hash: b541c3f5765d3ba062c0d004b9ca6da6d0af908293421c2dbe046c537fb2a011 + dependencies: + - name: idf + require: private + version: '>=4.1' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.4.0 espressif/mdns: component_hash: 3ec0af5f6bce310512e90f482388d21cc7c0e99668172d2f895356165fc6f7c5 dependencies: @@ -81,10 +91,11 @@ direct_dependencies: - espressif/cbor - espressif/esp-zboss-lib - espressif/esp-zigbee-lib +- espressif/esp_modem - espressif/mdns - espressif/network_provisioning - idf - joltwallet/littlefs -manifest_hash: cdea08c215af25ecb07f34a572afe529ccee1d11a022752ebfb3b54cbc0cb5f8 +manifest_hash: e9919b5b28bb7bb038864af176d8e81936400eff14ef44258dd5186bdc427ec2 target: esp32 version: 2.0.0 diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt new file mode 100644 index 00000000..6c5c1ddd --- /dev/null +++ b/include/CMakeLists.txt @@ -0,0 +1,6 @@ +# This file was automatically generated for projects +# without default 'CMakeLists.txt' file. + +FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/include/*.*) + +#idf_component_register(SRCS ${app_sources}) \ No newline at end of file diff --git a/sdkconfig.old b/sdkconfig.old deleted file mode 100644 index 07c9dd84..00000000 --- a/sdkconfig.old +++ /dev/null @@ -1,2103 +0,0 @@ -# -# Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) 5.4.1 Project Configuration -# -CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined" -CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined" -CONFIG_SOC_DPORT_WORKAROUND="Not determined" -CONFIG_SOC_CAPS_ECO_VER_MAX=301 -CONFIG_SOC_ADC_SUPPORTED=y -CONFIG_SOC_DAC_SUPPORTED=y -CONFIG_SOC_UART_SUPPORTED=y -CONFIG_SOC_MCPWM_SUPPORTED=y -CONFIG_SOC_GPTIMER_SUPPORTED=y -CONFIG_SOC_SDMMC_HOST_SUPPORTED=y -CONFIG_SOC_BT_SUPPORTED=y -CONFIG_SOC_PCNT_SUPPORTED=y -CONFIG_SOC_PHY_SUPPORTED=y -CONFIG_SOC_WIFI_SUPPORTED=y -CONFIG_SOC_SDIO_SLAVE_SUPPORTED=y -CONFIG_SOC_TWAI_SUPPORTED=y -CONFIG_SOC_EFUSE_SUPPORTED=y -CONFIG_SOC_EMAC_SUPPORTED=y -CONFIG_SOC_ULP_SUPPORTED=y -CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y -CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y -CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y -CONFIG_SOC_RTC_MEM_SUPPORTED=y -CONFIG_SOC_I2S_SUPPORTED=y -CONFIG_SOC_RMT_SUPPORTED=y -CONFIG_SOC_SDM_SUPPORTED=y -CONFIG_SOC_GPSPI_SUPPORTED=y -CONFIG_SOC_LEDC_SUPPORTED=y -CONFIG_SOC_I2C_SUPPORTED=y -CONFIG_SOC_SUPPORT_COEXISTENCE=y -CONFIG_SOC_AES_SUPPORTED=y -CONFIG_SOC_MPI_SUPPORTED=y -CONFIG_SOC_SHA_SUPPORTED=y -CONFIG_SOC_FLASH_ENC_SUPPORTED=y -CONFIG_SOC_SECURE_BOOT_SUPPORTED=y -CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y -CONFIG_SOC_BOD_SUPPORTED=y -CONFIG_SOC_ULP_FSM_SUPPORTED=y -CONFIG_SOC_CLK_TREE_SUPPORTED=y -CONFIG_SOC_MPU_SUPPORTED=y -CONFIG_SOC_WDT_SUPPORTED=y -CONFIG_SOC_SPI_FLASH_SUPPORTED=y -CONFIG_SOC_RNG_SUPPORTED=y -CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y -CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y -CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y -CONFIG_SOC_PM_SUPPORTED=y -CONFIG_SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL=5 -CONFIG_SOC_XTAL_SUPPORT_26M=y -CONFIG_SOC_XTAL_SUPPORT_40M=y -CONFIG_SOC_XTAL_SUPPORT_AUTO_DETECT=y -CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y -CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y -CONFIG_SOC_ADC_DMA_SUPPORTED=y -CONFIG_SOC_ADC_PERIPH_NUM=2 -CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 -CONFIG_SOC_ADC_ATTEN_NUM=4 -CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 -CONFIG_SOC_ADC_PATT_LEN_MAX=16 -CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=9 -CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 -CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 -CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=4 -CONFIG_SOC_ADC_DIGI_MONITOR_NUM=0 -CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=2 -CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=20 -CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=9 -CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=12 -CONFIG_SOC_ADC_SHARED_POWER=y -CONFIG_SOC_SHARED_IDCACHE_SUPPORTED=y -CONFIG_SOC_IDCACHE_PER_CORE=y -CONFIG_SOC_CPU_CORES_NUM=2 -CONFIG_SOC_CPU_INTR_NUM=32 -CONFIG_SOC_CPU_HAS_FPU=y -CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y -CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 -CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 -CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 -CONFIG_SOC_DAC_CHAN_NUM=2 -CONFIG_SOC_DAC_RESOLUTION=8 -CONFIG_SOC_DAC_DMA_16BIT_ALIGN=y -CONFIG_SOC_GPIO_PORT=1 -CONFIG_SOC_GPIO_PIN_COUNT=40 -CONFIG_SOC_GPIO_VALID_GPIO_MASK=0xFFFFFFFFFF -CONFIG_SOC_GPIO_IN_RANGE_MAX=39 -CONFIG_SOC_GPIO_OUT_RANGE_MAX=33 -CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0xEF0FEA -CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y -CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3 -CONFIG_SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP=y -CONFIG_SOC_I2C_NUM=2 -CONFIG_SOC_HP_I2C_NUM=2 -CONFIG_SOC_I2C_FIFO_LEN=32 -CONFIG_SOC_I2C_CMD_REG_NUM=16 -CONFIG_SOC_I2C_SUPPORT_SLAVE=y -CONFIG_SOC_I2C_SUPPORT_APB=y -CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR=y -CONFIG_SOC_I2C_STOP_INDEPENDENT=y -CONFIG_SOC_I2S_NUM=2 -CONFIG_SOC_I2S_HW_VERSION_1=y -CONFIG_SOC_I2S_SUPPORTS_APLL=y -CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y -CONFIG_SOC_I2S_SUPPORTS_PDM=y -CONFIG_SOC_I2S_SUPPORTS_PDM_TX=y -CONFIG_SOC_I2S_PDM_MAX_TX_LINES=1 -CONFIG_SOC_I2S_SUPPORTS_PDM_RX=y -CONFIG_SOC_I2S_PDM_MAX_RX_LINES=1 -CONFIG_SOC_I2S_SUPPORTS_ADC_DAC=y -CONFIG_SOC_I2S_SUPPORTS_ADC=y -CONFIG_SOC_I2S_SUPPORTS_DAC=y -CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y -CONFIG_SOC_I2S_MAX_DATA_WIDTH=24 -CONFIG_SOC_I2S_TRANS_SIZE_ALIGN_WORD=y -CONFIG_SOC_I2S_LCD_I80_VARIANT=y -CONFIG_SOC_LCD_I80_SUPPORTED=y -CONFIG_SOC_LCD_I80_BUSES=2 -CONFIG_SOC_LCD_I80_BUS_WIDTH=24 -CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y -CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y -CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y -CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y -CONFIG_SOC_LEDC_TIMER_NUM=4 -CONFIG_SOC_LEDC_CHANNEL_NUM=8 -CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=20 -CONFIG_SOC_MCPWM_GROUPS=2 -CONFIG_SOC_MCPWM_TIMERS_PER_GROUP=3 -CONFIG_SOC_MCPWM_OPERATORS_PER_GROUP=3 -CONFIG_SOC_MCPWM_COMPARATORS_PER_OPERATOR=2 -CONFIG_SOC_MCPWM_GENERATORS_PER_OPERATOR=2 -CONFIG_SOC_MCPWM_TRIGGERS_PER_OPERATOR=2 -CONFIG_SOC_MCPWM_GPIO_FAULTS_PER_GROUP=3 -CONFIG_SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP=y -CONFIG_SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER=3 -CONFIG_SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP=3 -CONFIG_SOC_MMU_PERIPH_NUM=2 -CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=3 -CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 -CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 -CONFIG_SOC_PCNT_GROUPS=1 -CONFIG_SOC_PCNT_UNITS_PER_GROUP=8 -CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 -CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 -CONFIG_SOC_RMT_GROUPS=1 -CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=8 -CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=8 -CONFIG_SOC_RMT_CHANNELS_PER_GROUP=8 -CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 -CONFIG_SOC_RMT_SUPPORT_REF_TICK=y -CONFIG_SOC_RMT_SUPPORT_APB=y -CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y -CONFIG_SOC_RTCIO_PIN_COUNT=18 -CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y -CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y -CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y -CONFIG_SOC_SDM_GROUPS=1 -CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 -CONFIG_SOC_SDM_CLK_SUPPORT_APB=y -CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y -CONFIG_SOC_SPI_AS_CS_SUPPORTED=y -CONFIG_SOC_SPI_PERIPH_NUM=3 -CONFIG_SOC_SPI_DMA_CHAN_NUM=2 -CONFIG_SOC_SPI_MAX_CS_NUM=3 -CONFIG_SOC_SPI_SUPPORT_CLK_APB=y -CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=64 -CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 -CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y -CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y -CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y -CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y -CONFIG_SOC_TIMER_GROUPS=2 -CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 -CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 -CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 -CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y -CONFIG_SOC_LP_TIMER_BIT_WIDTH_LO=32 -CONFIG_SOC_LP_TIMER_BIT_WIDTH_HI=16 -CONFIG_SOC_TOUCH_SENSOR_VERSION=1 -CONFIG_SOC_TOUCH_SENSOR_NUM=10 -CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1 -CONFIG_SOC_TWAI_CONTROLLER_NUM=1 -CONFIG_SOC_TWAI_BRP_MIN=2 -CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y -CONFIG_SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT=y -CONFIG_SOC_UART_NUM=3 -CONFIG_SOC_UART_HP_NUM=3 -CONFIG_SOC_UART_SUPPORT_APB_CLK=y -CONFIG_SOC_UART_SUPPORT_REF_TICK=y -CONFIG_SOC_UART_FIFO_LEN=128 -CONFIG_SOC_UART_BITRATE_MAX=5000000 -CONFIG_SOC_SPIRAM_SUPPORTED=y -CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y -CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG=y -CONFIG_SOC_SHA_ENDIANNESS_BE=y -CONFIG_SOC_SHA_SUPPORT_SHA1=y -CONFIG_SOC_SHA_SUPPORT_SHA256=y -CONFIG_SOC_SHA_SUPPORT_SHA384=y -CONFIG_SOC_SHA_SUPPORT_SHA512=y -CONFIG_SOC_MPI_MEM_BLOCKS_NUM=4 -CONFIG_SOC_MPI_OPERATIONS_NUM=y -CONFIG_SOC_RSA_MAX_BIT_LEN=4096 -CONFIG_SOC_AES_SUPPORT_AES_128=y -CONFIG_SOC_AES_SUPPORT_AES_192=y -CONFIG_SOC_AES_SUPPORT_AES_256=y -CONFIG_SOC_SECURE_BOOT_V1=y -CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=y -CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=32 -CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 -CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y -CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y -CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y -CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y -CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y -CONFIG_SOC_PM_SUPPORT_MODEM_PD=y -CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y -CONFIG_SOC_PM_MODEM_PD_BY_SW=y -CONFIG_SOC_CLK_APLL_SUPPORTED=y -CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y -CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y -CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y -CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y -CONFIG_SOC_SDMMC_USE_IOMUX=y -CONFIG_SOC_SDMMC_NUM_SLOTS=2 -CONFIG_SOC_WIFI_WAPI_SUPPORT=y -CONFIG_SOC_WIFI_CSI_SUPPORT=y -CONFIG_SOC_WIFI_MESH_SUPPORT=y -CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y -CONFIG_SOC_WIFI_NAN_SUPPORT=y -CONFIG_SOC_BLE_SUPPORTED=y -CONFIG_SOC_BLE_MESH_SUPPORTED=y -CONFIG_SOC_BT_CLASSIC_SUPPORTED=y -CONFIG_SOC_BLUFI_SUPPORTED=y -CONFIG_SOC_BT_H2C_ENC_KEY_CTRL_ENH_VSC_SUPPORTED=y -CONFIG_SOC_ULP_HAS_ADC=y -CONFIG_SOC_PHY_COMBO_MODULE=y -CONFIG_SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK=y -CONFIG_IDF_CMAKE=y -CONFIG_IDF_TOOLCHAIN="gcc" -CONFIG_IDF_TOOLCHAIN_GCC=y -CONFIG_IDF_TARGET_ARCH_XTENSA=y -CONFIG_IDF_TARGET_ARCH="xtensa" -CONFIG_IDF_TARGET="esp32" -CONFIG_IDF_INIT_VERSION="5.4.1" -CONFIG_IDF_TARGET_ESP32=y -CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 - -# -# Build type -# -CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y -# CONFIG_APP_BUILD_TYPE_RAM is not set -CONFIG_APP_BUILD_GENERATE_BINARIES=y -CONFIG_APP_BUILD_BOOTLOADER=y -CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y -# CONFIG_APP_REPRODUCIBLE_BUILD is not set -# CONFIG_APP_NO_BLOBS is not set -# CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set -# CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set -# end of Build type - -# -# Bootloader config -# - -# -# Bootloader manager -# -CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y -CONFIG_BOOTLOADER_PROJECT_VER=1 -# end of Bootloader manager - -CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 -CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set - -# -# Log -# -# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set -CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y -# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set -CONFIG_BOOTLOADER_LOG_LEVEL=3 - -# -# Format -# -# CONFIG_BOOTLOADER_LOG_COLORS is not set -CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y -# end of Format -# end of Log - -# -# Serial Flash Configurations -# -# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set -CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y -# end of Serial Flash Configurations - -# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set -CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y -# CONFIG_BOOTLOADER_FACTORY_RESET is not set -# CONFIG_BOOTLOADER_APP_TEST is not set -CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y -CONFIG_BOOTLOADER_WDT_ENABLE=y -# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set -CONFIG_BOOTLOADER_WDT_TIME_MS=9000 -# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set -CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 -# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set -# end of Bootloader config - -# -# Security features -# -CONFIG_SECURE_BOOT_V1_SUPPORTED=y -# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set -# CONFIG_SECURE_BOOT is not set -# CONFIG_SECURE_FLASH_ENC_ENABLED is not set -# end of Security features - -# -# Application manager -# -CONFIG_APP_COMPILE_TIME_DATE=y -# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set -# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set -# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set -CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 -# end of Application manager - -CONFIG_ESP_ROM_HAS_CRC_LE=y -CONFIG_ESP_ROM_HAS_CRC_BE=y -CONFIG_ESP_ROM_HAS_MZ_CRC32=y -CONFIG_ESP_ROM_HAS_JPEG_DECODE=y -CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y -CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y -CONFIG_ESP_ROM_HAS_NEWLIB=y -CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y -CONFIG_ESP_ROM_HAS_NEWLIB_32BIT_TIME=y -CONFIG_ESP_ROM_HAS_SW_FLOAT=y -CONFIG_ESP_ROM_USB_OTG_NUM=-1 -CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1 -CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y -CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y - -# -# Serial flasher config -# -# CONFIG_ESPTOOLPY_NO_STUB is not set -# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set -# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set -CONFIG_ESPTOOLPY_FLASHMODE_DIO=y -# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set -CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y -CONFIG_ESPTOOLPY_FLASHMODE="dio" -# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set -CONFIG_ESPTOOLPY_FLASHFREQ_40M=y -# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set -CONFIG_ESPTOOLPY_FLASHFREQ="40m" -# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y -# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="2MB" -# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set -CONFIG_ESPTOOLPY_BEFORE_RESET=y -# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set -CONFIG_ESPTOOLPY_BEFORE="default_reset" -CONFIG_ESPTOOLPY_AFTER_RESET=y -# CONFIG_ESPTOOLPY_AFTER_NORESET is not set -CONFIG_ESPTOOLPY_AFTER="hard_reset" -CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 -# end of Serial flasher config - -# -# Partition Table -# -CONFIG_PARTITION_TABLE_SINGLE_APP=y -# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set -# CONFIG_PARTITION_TABLE_TWO_OTA is not set -# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set -# CONFIG_PARTITION_TABLE_CUSTOM is not set -CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" -CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" -CONFIG_PARTITION_TABLE_OFFSET=0x8000 -CONFIG_PARTITION_TABLE_MD5=y -# end of Partition Table - -# -# Compiler options -# -CONFIG_COMPILER_OPTIMIZATION_DEBUG=y -# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set -# CONFIG_COMPILER_OPTIMIZATION_PERF is not set -# CONFIG_COMPILER_OPTIMIZATION_NONE is not set -CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y -# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set -# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set -CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y -CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y -CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 -# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set -CONFIG_COMPILER_HIDE_PATHS_MACROS=y -# CONFIG_COMPILER_CXX_EXCEPTIONS is not set -# CONFIG_COMPILER_CXX_RTTI is not set -CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y -# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set -# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set -# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set -# CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set -# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set -CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y -# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set -# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set -# CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set -# CONFIG_COMPILER_DUMP_RTL_FILES is not set -CONFIG_COMPILER_RT_LIB_GCCLIB=y -CONFIG_COMPILER_RT_LIB_NAME="gcc" -CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y -# CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set -# CONFIG_COMPILER_STATIC_ANALYZER is not set -# end of Compiler options - -# -# Component config -# - -# -# Application Level Tracing -# -# CONFIG_APPTRACE_DEST_JTAG is not set -CONFIG_APPTRACE_DEST_NONE=y -# CONFIG_APPTRACE_DEST_UART1 is not set -# CONFIG_APPTRACE_DEST_UART2 is not set -CONFIG_APPTRACE_DEST_UART_NONE=y -CONFIG_APPTRACE_UART_TASK_PRIO=1 -CONFIG_APPTRACE_LOCK_ENABLE=y -# end of Application Level Tracing - -# -# Bluetooth -# -# CONFIG_BT_ENABLED is not set -CONFIG_BT_ALARM_MAX_NUM=50 -# end of Bluetooth - -# -# Console Library -# -# CONFIG_CONSOLE_SORTED_HELP is not set -# end of Console Library - -# -# Driver Configurations -# - -# -# TWAI Configuration -# -# CONFIG_TWAI_ISR_IN_IRAM is not set -CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y -CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y -CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID=y -CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT=y -CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y -# end of TWAI Configuration - -# -# Legacy ADC Driver Configuration -# -CONFIG_ADC_DISABLE_DAC=y -# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set - -# -# Legacy ADC Calibration Configuration -# -CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y -CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y -CONFIG_ADC_CAL_LUT_ENABLE=y -# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set -# end of Legacy ADC Calibration Configuration -# end of Legacy ADC Driver Configuration - -# -# Legacy DAC Driver Configurations -# -# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy DAC Driver Configurations - -# -# Legacy MCPWM Driver Configurations -# -# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy MCPWM Driver Configurations - -# -# Legacy Timer Group Driver Configurations -# -# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy Timer Group Driver Configurations - -# -# Legacy RMT Driver Configurations -# -# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy RMT Driver Configurations - -# -# Legacy I2S Driver Configurations -# -# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy I2S Driver Configurations - -# -# Legacy PCNT Driver Configurations -# -# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy PCNT Driver Configurations - -# -# Legacy SDM Driver Configurations -# -# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy SDM Driver Configurations -# end of Driver Configurations - -# -# eFuse Bit Manager -# -# CONFIG_EFUSE_CUSTOM_TABLE is not set -# CONFIG_EFUSE_VIRTUAL is not set -# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set -CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y -# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set -CONFIG_EFUSE_MAX_BLK_LEN=192 -# end of eFuse Bit Manager - -# -# ESP-TLS -# -CONFIG_ESP_TLS_USING_MBEDTLS=y -# CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set -# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set -# CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set -# CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set -# CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set -# CONFIG_ESP_TLS_PSK_VERIFICATION is not set -# CONFIG_ESP_TLS_INSECURE is not set -# end of ESP-TLS - -# -# ADC and ADC Calibration -# -# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set -# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set - -# -# ADC Calibration Configurations -# -CONFIG_ADC_CALI_EFUSE_TP_ENABLE=y -CONFIG_ADC_CALI_EFUSE_VREF_ENABLE=y -CONFIG_ADC_CALI_LUT_ENABLE=y -# end of ADC Calibration Configurations - -CONFIG_ADC_DISABLE_DAC_OUTPUT=y -# CONFIG_ADC_ENABLE_DEBUG_LOG is not set -# end of ADC and ADC Calibration - -# -# Wireless Coexistence -# -CONFIG_ESP_COEX_ENABLED=y -# CONFIG_ESP_COEX_GPIO_DEBUG is not set -# end of Wireless Coexistence - -# -# Common ESP-related -# -CONFIG_ESP_ERR_TO_NAME_LOOKUP=y -# end of Common ESP-related - -# -# ESP-Driver:DAC Configurations -# -# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set -# CONFIG_DAC_ISR_IRAM_SAFE is not set -# CONFIG_DAC_ENABLE_DEBUG_LOG is not set -CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y -# end of ESP-Driver:DAC Configurations - -# -# ESP-Driver:GPIO Configurations -# -# CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set -# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set -# end of ESP-Driver:GPIO Configurations - -# -# ESP-Driver:GPTimer Configurations -# -CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y -# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set -# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set -# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:GPTimer Configurations - -# -# ESP-Driver:I2C Configurations -# -# CONFIG_I2C_ISR_IRAM_SAFE is not set -# CONFIG_I2C_ENABLE_DEBUG_LOG is not set -# CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set -# end of ESP-Driver:I2C Configurations - -# -# ESP-Driver:I2S Configurations -# -# CONFIG_I2S_ISR_IRAM_SAFE is not set -# CONFIG_I2S_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:I2S Configurations - -# -# ESP-Driver:LEDC Configurations -# -# CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set -# end of ESP-Driver:LEDC Configurations - -# -# ESP-Driver:MCPWM Configurations -# -# CONFIG_MCPWM_ISR_IRAM_SAFE is not set -# CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set -# CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:MCPWM Configurations - -# -# ESP-Driver:PCNT Configurations -# -# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set -# CONFIG_PCNT_ISR_IRAM_SAFE is not set -# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:PCNT Configurations - -# -# ESP-Driver:RMT Configurations -# -# CONFIG_RMT_ISR_IRAM_SAFE is not set -# CONFIG_RMT_RECV_FUNC_IN_IRAM is not set -# CONFIG_RMT_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:RMT Configurations - -# -# ESP-Driver:Sigma Delta Modulator Configurations -# -# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set -# CONFIG_SDM_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:Sigma Delta Modulator Configurations - -# -# ESP-Driver:SPI Configurations -# -# CONFIG_SPI_MASTER_IN_IRAM is not set -CONFIG_SPI_MASTER_ISR_IN_IRAM=y -# CONFIG_SPI_SLAVE_IN_IRAM is not set -CONFIG_SPI_SLAVE_ISR_IN_IRAM=y -# end of ESP-Driver:SPI Configurations - -# -# ESP-Driver:Touch Sensor Configurations -# -# CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set -# CONFIG_TOUCH_ISR_IRAM_SAFE is not set -# CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:Touch Sensor Configurations - -# -# ESP-Driver:UART Configurations -# -# CONFIG_UART_ISR_IN_IRAM is not set -# end of ESP-Driver:UART Configurations - -# -# Ethernet -# -CONFIG_ETH_ENABLED=y -CONFIG_ETH_USE_ESP32_EMAC=y -CONFIG_ETH_PHY_INTERFACE_RMII=y -CONFIG_ETH_RMII_CLK_INPUT=y -# CONFIG_ETH_RMII_CLK_OUTPUT is not set -CONFIG_ETH_RMII_CLK_IN_GPIO=0 -CONFIG_ETH_DMA_BUFFER_SIZE=512 -CONFIG_ETH_DMA_RX_BUFFER_NUM=10 -CONFIG_ETH_DMA_TX_BUFFER_NUM=10 -# CONFIG_ETH_IRAM_OPTIMIZATION is not set -CONFIG_ETH_USE_SPI_ETHERNET=y -# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set -# CONFIG_ETH_SPI_ETHERNET_W5500 is not set -# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set -# CONFIG_ETH_USE_OPENETH is not set -# CONFIG_ETH_TRANSMIT_MUTEX is not set -# end of Ethernet - -# -# Event Loop Library -# -# CONFIG_ESP_EVENT_LOOP_PROFILING is not set -CONFIG_ESP_EVENT_POST_FROM_ISR=y -CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y -# end of Event Loop Library - -# -# GDB Stub -# -CONFIG_ESP_GDBSTUB_ENABLED=y -# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set -CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y -CONFIG_ESP_GDBSTUB_MAX_TASKS=32 -# end of GDB Stub - -# -# ESP HID -# -CONFIG_ESPHID_TASK_SIZE_BT=2048 -CONFIG_ESPHID_TASK_SIZE_BLE=4096 -# end of ESP HID - -# -# ESP HTTP client -# -CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y -# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set -# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set -# CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set -CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 -# end of ESP HTTP client - -# -# HTTP Server -# -CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 -CONFIG_HTTPD_MAX_URI_LEN=512 -CONFIG_HTTPD_ERR_RESP_NO_DELAY=y -CONFIG_HTTPD_PURGE_BUF_LEN=32 -# CONFIG_HTTPD_LOG_PURGE_DATA is not set -# CONFIG_HTTPD_WS_SUPPORT is not set -# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set -CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 -# end of HTTP Server - -# -# ESP HTTPS OTA -# -# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set -# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set -CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 -# end of ESP HTTPS OTA - -# -# ESP HTTPS server -# -# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set -CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 -# end of ESP HTTPS server - -# -# Hardware Settings -# - -# -# Chip revision -# -CONFIG_ESP32_REV_MIN_0=y -# CONFIG_ESP32_REV_MIN_1 is not set -# CONFIG_ESP32_REV_MIN_1_1 is not set -# CONFIG_ESP32_REV_MIN_2 is not set -# CONFIG_ESP32_REV_MIN_3 is not set -# CONFIG_ESP32_REV_MIN_3_1 is not set -CONFIG_ESP32_REV_MIN=0 -CONFIG_ESP32_REV_MIN_FULL=0 -CONFIG_ESP_REV_MIN_FULL=0 - -# -# Maximum Supported ESP32 Revision (Rev v3.99) -# -CONFIG_ESP32_REV_MAX_FULL=399 -CONFIG_ESP_REV_MAX_FULL=399 -CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL=0 -CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL=99 - -# -# Maximum Supported ESP32 eFuse Block Revision (eFuse Block Rev v0.99) -# -# end of Chip revision - -# -# MAC Config -# -CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y -CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_FOUR=y -CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 -# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set -CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y -CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 -# CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set -# CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set -# end of MAC Config - -# -# Sleep Config -# -# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set -CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y -# CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set -CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y -# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set -CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 -# CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set -# CONFIG_ESP_SLEEP_DEBUG is not set -CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y -# end of Sleep Config - -# -# RTC Clock Config -# -CONFIG_RTC_CLK_SRC_INT_RC=y -# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set -# CONFIG_RTC_CLK_SRC_EXT_OSC is not set -# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set -CONFIG_RTC_CLK_CAL_CYCLES=1024 -# end of RTC Clock Config - -# -# Peripheral Control -# -CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y -# end of Peripheral Control - -# -# Main XTAL Config -# -# CONFIG_XTAL_FREQ_26 is not set -# CONFIG_XTAL_FREQ_32 is not set -CONFIG_XTAL_FREQ_40=y -# CONFIG_XTAL_FREQ_AUTO is not set -CONFIG_XTAL_FREQ=40 -# end of Main XTAL Config - -CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y -# end of Hardware Settings - -# -# ESP-Driver:LCD Controller Configurations -# -# CONFIG_LCD_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:LCD Controller Configurations - -# -# ESP-MM: Memory Management Configurations -# -# end of ESP-MM: Memory Management Configurations - -# -# ESP NETIF Adapter -# -CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 -# CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set -CONFIG_ESP_NETIF_TCPIP_LWIP=y -# CONFIG_ESP_NETIF_LOOPBACK is not set -CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y -CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y -# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set -# CONFIG_ESP_NETIF_L2_TAP is not set -# CONFIG_ESP_NETIF_BRIDGE_EN is not set -# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set -# end of ESP NETIF Adapter - -# -# Partition API Configuration -# -# end of Partition API Configuration - -# -# PHY -# -CONFIG_ESP_PHY_ENABLED=y -CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y -# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set -CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 -CONFIG_ESP_PHY_MAX_TX_POWER=20 -# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set -# CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set -CONFIG_ESP_PHY_RF_CAL_PARTIAL=y -# CONFIG_ESP_PHY_RF_CAL_NONE is not set -# CONFIG_ESP_PHY_RF_CAL_FULL is not set -CONFIG_ESP_PHY_CALIBRATION_MODE=0 -# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set -# CONFIG_ESP_PHY_RECORD_USED_TIME is not set -# end of PHY - -# -# Power Management -# -# CONFIG_PM_ENABLE is not set -# CONFIG_PM_SLP_IRAM_OPT is not set -# end of Power Management - -# -# ESP PSRAM -# -# CONFIG_SPIRAM is not set -# end of ESP PSRAM - -# -# ESP Ringbuf -# -# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set -# end of ESP Ringbuf - -# -# ESP Security Specific -# -# end of ESP Security Specific - -# -# ESP System Settings -# -# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set -CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y -# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set -CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 - -# -# Memory -# -# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set - -# -# Non-backward compatible options -# -# CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set -# end of Non-backward compatible options -# end of Memory - -# -# Trace memory -# -# CONFIG_ESP32_TRAX is not set -CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 -# end of Trace memory - -# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set -CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y -# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set -# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set -CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 - -# -# Memory protection -# -# end of Memory protection - -CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 -CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y -# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set -# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 -CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 -CONFIG_ESP_CONSOLE_UART_DEFAULT=y -# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set -# CONFIG_ESP_CONSOLE_NONE is not set -CONFIG_ESP_CONSOLE_UART=y -CONFIG_ESP_CONSOLE_UART_NUM=0 -CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0 -CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 -CONFIG_ESP_INT_WDT=y -CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 -CONFIG_ESP_INT_WDT_CHECK_CPU1=y -CONFIG_ESP_TASK_WDT_EN=y -CONFIG_ESP_TASK_WDT_INIT=y -# CONFIG_ESP_TASK_WDT_PANIC is not set -CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 -CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y -CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# CONFIG_ESP_PANIC_HANDLER_IRAM is not set -# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set -CONFIG_ESP_DEBUG_OCDAWARE=y -# CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set -CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y - -# -# Brownout Detector -# -CONFIG_ESP_BROWNOUT_DET=y -CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7 is not set -CONFIG_ESP_BROWNOUT_DET_LVL=0 -# end of Brownout Detector - -# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set -CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y -# end of ESP System Settings - -# -# IPC (Inter-Processor Call) -# -CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 -CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y -CONFIG_ESP_IPC_ISR_ENABLE=y -# end of IPC (Inter-Processor Call) - -# -# ESP Timer (High Resolution Timer) -# -# CONFIG_ESP_TIMER_PROFILING is not set -CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y -CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y -CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 -CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 -# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set -CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 -CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y -CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y -# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set -CONFIG_ESP_TIMER_IMPL_TG0_LAC=y -# end of ESP Timer (High Resolution Timer) - -# -# Wi-Fi -# -CONFIG_ESP_WIFI_ENABLED=y -CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 -CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 -# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set -CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y -CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 -CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32 -CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y -# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set -CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 -CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 -# CONFIG_ESP_WIFI_CSI_ENABLED is not set -CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y -CONFIG_ESP_WIFI_TX_BA_WIN=6 -CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y -CONFIG_ESP_WIFI_RX_BA_WIN=6 -CONFIG_ESP_WIFI_NVS_ENABLED=y -CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y -# CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set -CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 -CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 -CONFIG_ESP_WIFI_IRAM_OPT=y -# CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set -CONFIG_ESP_WIFI_RX_IRAM_OPT=y -CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y -CONFIG_ESP_WIFI_ENABLE_SAE_PK=y -CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y -CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y -# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set -CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 -CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 -CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 -CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y -CONFIG_ESP_WIFI_GMAC_SUPPORT=y -CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y -# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set -CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 -# CONFIG_ESP_WIFI_NAN_ENABLE is not set -CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y -CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y -# CONFIG_ESP_WIFI_WAPI_PSK is not set -# CONFIG_ESP_WIFI_11KV_SUPPORT is not set -# CONFIG_ESP_WIFI_MBO_SUPPORT is not set -# CONFIG_ESP_WIFI_DPP_SUPPORT is not set -# CONFIG_ESP_WIFI_11R_SUPPORT is not set -# CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set - -# -# WPS Configuration Options -# -# CONFIG_ESP_WIFI_WPS_STRICT is not set -# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set -# end of WPS Configuration Options - -# CONFIG_ESP_WIFI_DEBUG_PRINT is not set -# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set -CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y -# CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set -# end of Wi-Fi - -# -# Core dump -# -# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set -# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set -CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y -# end of Core dump - -# -# FAT Filesystem support -# -CONFIG_FATFS_VOLUME_COUNT=2 -CONFIG_FATFS_LFN_NONE=y -# CONFIG_FATFS_LFN_HEAP is not set -# CONFIG_FATFS_LFN_STACK is not set -# CONFIG_FATFS_SECTOR_512 is not set -CONFIG_FATFS_SECTOR_4096=y -# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set -CONFIG_FATFS_CODEPAGE_437=y -# CONFIG_FATFS_CODEPAGE_720 is not set -# CONFIG_FATFS_CODEPAGE_737 is not set -# CONFIG_FATFS_CODEPAGE_771 is not set -# CONFIG_FATFS_CODEPAGE_775 is not set -# CONFIG_FATFS_CODEPAGE_850 is not set -# CONFIG_FATFS_CODEPAGE_852 is not set -# CONFIG_FATFS_CODEPAGE_855 is not set -# CONFIG_FATFS_CODEPAGE_857 is not set -# CONFIG_FATFS_CODEPAGE_860 is not set -# CONFIG_FATFS_CODEPAGE_861 is not set -# CONFIG_FATFS_CODEPAGE_862 is not set -# CONFIG_FATFS_CODEPAGE_863 is not set -# CONFIG_FATFS_CODEPAGE_864 is not set -# CONFIG_FATFS_CODEPAGE_865 is not set -# CONFIG_FATFS_CODEPAGE_866 is not set -# CONFIG_FATFS_CODEPAGE_869 is not set -# CONFIG_FATFS_CODEPAGE_932 is not set -# CONFIG_FATFS_CODEPAGE_936 is not set -# CONFIG_FATFS_CODEPAGE_949 is not set -# CONFIG_FATFS_CODEPAGE_950 is not set -CONFIG_FATFS_CODEPAGE=437 -CONFIG_FATFS_FS_LOCK=0 -CONFIG_FATFS_TIMEOUT_MS=10000 -CONFIG_FATFS_PER_FILE_CACHE=y -# CONFIG_FATFS_USE_FASTSEEK is not set -CONFIG_FATFS_USE_STRFUNC_NONE=y -# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set -# CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set -CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 -# CONFIG_FATFS_IMMEDIATE_FSYNC is not set -# CONFIG_FATFS_USE_LABEL is not set -CONFIG_FATFS_LINK_LOCK=y -# end of FAT Filesystem support - -# -# FreeRTOS -# - -# -# Kernel -# -# CONFIG_FREERTOS_SMP is not set -# CONFIG_FREERTOS_UNICORE is not set -CONFIG_FREERTOS_HZ=1000 -# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set -# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set -CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y -CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 -CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 -# CONFIG_FREERTOS_USE_IDLE_HOOK is not set -# CONFIG_FREERTOS_USE_TICK_HOOK is not set -CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 -# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set -CONFIG_FREERTOS_USE_TIMERS=y -CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" -# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set -# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set -CONFIG_FREERTOS_TIMER_TASK_NO_AFFINITY=y -CONFIG_FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY=0x7FFFFFFF -CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 -CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 -CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 -CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 -CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 -# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set -# CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set -# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set -# CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set -# end of Kernel - -# -# Port -# -CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y -# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set -CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y -# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set -# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set -CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y -CONFIG_FREERTOS_ISR_STACKSIZE=1536 -CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y -# CONFIG_FREERTOS_FPU_IN_ISR is not set -CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y -CONFIG_FREERTOS_CORETIMER_0=y -# CONFIG_FREERTOS_CORETIMER_1 is not set -CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y -# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set -# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set -# end of Port - -# -# Extra -# -# end of Extra - -CONFIG_FREERTOS_PORT=y -CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF -CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y -CONFIG_FREERTOS_DEBUG_OCDAWARE=y -CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y -CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y -CONFIG_FREERTOS_NUMBER_OF_CORES=2 -# end of FreeRTOS - -# -# Hardware Abstraction Layer (HAL) and Low Level (LL) -# -CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y -# CONFIG_HAL_ASSERTION_DISABLE is not set -# CONFIG_HAL_ASSERTION_SILENT is not set -# CONFIG_HAL_ASSERTION_ENABLE is not set -CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 -CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y -CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y -# end of Hardware Abstraction Layer (HAL) and Low Level (LL) - -# -# Heap memory debugging -# -CONFIG_HEAP_POISONING_DISABLED=y -# CONFIG_HEAP_POISONING_LIGHT is not set -# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set -CONFIG_HEAP_TRACING_OFF=y -# CONFIG_HEAP_TRACING_STANDALONE is not set -# CONFIG_HEAP_TRACING_TOHOST is not set -# CONFIG_HEAP_USE_HOOKS is not set -# CONFIG_HEAP_TASK_TRACKING is not set -# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set -# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set -# end of Heap memory debugging - -# -# Log -# - -# -# Log Level -# -# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set -# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set -# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set -CONFIG_LOG_DEFAULT_LEVEL_INFO=y -# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set -# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_LOG_DEFAULT_LEVEL=3 -CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y -# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set -# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set -CONFIG_LOG_MAXIMUM_LEVEL=3 - -# -# Level Settings -# -# CONFIG_LOG_MASTER_LEVEL is not set -CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y -# CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set -# CONFIG_LOG_TAG_LEVEL_IMPL_LINKED_LIST is not set -CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_AND_LINKED_LIST=y -# CONFIG_LOG_TAG_LEVEL_CACHE_ARRAY is not set -CONFIG_LOG_TAG_LEVEL_CACHE_BINARY_MIN_HEAP=y -CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 -# end of Level Settings -# end of Log Level - -# -# Format -# -# CONFIG_LOG_COLORS is not set -CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y -# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set -# end of Format -# end of Log - -# -# LWIP -# -CONFIG_LWIP_ENABLE=y -CONFIG_LWIP_LOCAL_HOSTNAME="espressif" -# CONFIG_LWIP_NETIF_API is not set -CONFIG_LWIP_TCPIP_TASK_PRIO=18 -# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set -# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -# CONFIG_LWIP_L2_TO_L3_COPY is not set -# CONFIG_LWIP_IRAM_OPTIMIZATION is not set -# CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set -CONFIG_LWIP_TIMERS_ONDEMAND=y -CONFIG_LWIP_ND6=y -# CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set -CONFIG_LWIP_MAX_SOCKETS=10 -# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set -# CONFIG_LWIP_SO_LINGER is not set -CONFIG_LWIP_SO_REUSE=y -CONFIG_LWIP_SO_REUSE_RXTOALL=y -# CONFIG_LWIP_SO_RCVBUF is not set -# CONFIG_LWIP_NETBUF_RECVINFO is not set -CONFIG_LWIP_IP_DEFAULT_TTL=64 -CONFIG_LWIP_IP4_FRAG=y -CONFIG_LWIP_IP6_FRAG=y -# CONFIG_LWIP_IP4_REASSEMBLY is not set -# CONFIG_LWIP_IP6_REASSEMBLY is not set -CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 -# CONFIG_LWIP_IP_FORWARD is not set -# CONFIG_LWIP_STATS is not set -CONFIG_LWIP_ESP_GRATUITOUS_ARP=y -CONFIG_LWIP_GARP_TMR_INTERVAL=60 -CONFIG_LWIP_ESP_MLDV6_REPORT=y -CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 -CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 -CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y -# CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set -# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set -# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set -CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y -# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set -CONFIG_LWIP_DHCP_OPTIONS_LEN=68 -CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 -CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 - -# -# DHCP server -# -CONFIG_LWIP_DHCPS=y -CONFIG_LWIP_DHCPS_LEASE_UNIT=60 -CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 -CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y -CONFIG_LWIP_DHCPS_ADD_DNS=y -# end of DHCP server - -# CONFIG_LWIP_AUTOIP is not set -CONFIG_LWIP_IPV4=y -CONFIG_LWIP_IPV6=y -# CONFIG_LWIP_IPV6_AUTOCONFIG is not set -CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 -# CONFIG_LWIP_IPV6_FORWARD is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5760 -CONFIG_LWIP_TCP_WND_DEFAULT=5760 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 -CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP - -# -# UDP -# -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# end of UDP - -# -# Checksums -# -# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set -# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set -CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y -# end of Checksums - -CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 -CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y -# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set -# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set -CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 -CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 -CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 -CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 -# CONFIG_LWIP_PPP_SUPPORT is not set -# CONFIG_LWIP_SLIP_SUPPORT is not set - -# -# ICMP -# -CONFIG_LWIP_ICMP=y -# CONFIG_LWIP_MULTICAST_PING is not set -# CONFIG_LWIP_BROADCAST_PING is not set -# end of ICMP - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API - -# -# SNTP -# -CONFIG_LWIP_SNTP_MAX_SERVERS=1 -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set -CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 -CONFIG_LWIP_SNTP_STARTUP_DELAY=y -CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 -# end of SNTP - -# -# DNS -# -CONFIG_LWIP_DNS_MAX_HOST_IP=1 -CONFIG_LWIP_DNS_MAX_SERVERS=3 -# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set -# CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set -# end of DNS - -CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 -CONFIG_LWIP_ESP_LWIP_ASSERT=y - -# -# Hooks -# -# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set -CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y -# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set -CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y -# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set -# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set -CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y -# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set -# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set -CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_NONE=y -# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_DEFAULT is not set -# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_CUSTOM is not set -CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y -# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set -# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set -CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_NONE=y -# CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_CUSTOM is not set -# CONFIG_LWIP_HOOK_IP6_INPUT_NONE is not set -CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y -# CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set -# end of Hooks - -# CONFIG_LWIP_DEBUG is not set -# end of LWIP - -# -# mbedTLS -# -CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y -# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set -# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set -CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y -CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 -CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 -# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set -# CONFIG_MBEDTLS_DEBUG is not set - -# -# mbedTLS v3.x related -# -# CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set -# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set -# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set -# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set -CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y -CONFIG_MBEDTLS_PKCS7_C=y -# end of mbedTLS v3.x related - -# -# Certificate Bundle -# -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set -# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 -# end of Certificate Bundle - -# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set -CONFIG_MBEDTLS_CMAC_C=y -CONFIG_MBEDTLS_HARDWARE_AES=y -CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y -CONFIG_MBEDTLS_HARDWARE_MPI=y -# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set -CONFIG_MBEDTLS_HARDWARE_SHA=y -CONFIG_MBEDTLS_ROM_MD5=y -# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set -# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set -CONFIG_MBEDTLS_HAVE_TIME=y -# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set -# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set -CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y -CONFIG_MBEDTLS_SHA512_C=y -# CONFIG_MBEDTLS_SHA3_C is not set -CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y -# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set -# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set -# CONFIG_MBEDTLS_TLS_DISABLED is not set -CONFIG_MBEDTLS_TLS_SERVER=y -CONFIG_MBEDTLS_TLS_CLIENT=y -CONFIG_MBEDTLS_TLS_ENABLED=y - -# -# TLS Key Exchange Methods -# -CONFIG_MBEDTLS_PSK_MODES=y -CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_PSK=y -CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_PSK=y -CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y -# end of TLS Key Exchange Methods - -CONFIG_MBEDTLS_SSL_RENEGOTIATION=y -CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y -# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set -# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set -CONFIG_MBEDTLS_SSL_ALPN=y -CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y -CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y - -# -# Symmetric Ciphers -# -CONFIG_MBEDTLS_AES_C=y -# CONFIG_MBEDTLS_CAMELLIA_C is not set -# CONFIG_MBEDTLS_DES_C is not set -# CONFIG_MBEDTLS_BLOWFISH_C is not set -# CONFIG_MBEDTLS_XTEA_C is not set -CONFIG_MBEDTLS_CCM_C=y -CONFIG_MBEDTLS_GCM_C=y -# CONFIG_MBEDTLS_NIST_KW_C is not set -# end of Symmetric Ciphers - -# CONFIG_MBEDTLS_RIPEMD160_C is not set - -# -# Certificates -# -CONFIG_MBEDTLS_PEM_PARSE_C=y -CONFIG_MBEDTLS_PEM_WRITE_C=y -CONFIG_MBEDTLS_X509_CRL_PARSE_C=y -CONFIG_MBEDTLS_X509_CSR_PARSE_C=y -# end of Certificates - -CONFIG_MBEDTLS_ECP_C=y -CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y -CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y -# CONFIG_MBEDTLS_DHM_C is not set -CONFIG_MBEDTLS_ECDH_C=y -CONFIG_MBEDTLS_ECDSA_C=y -# CONFIG_MBEDTLS_ECJPAKE_C is not set -CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y -CONFIG_MBEDTLS_ECP_NIST_OPTIM=y -# CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set -# CONFIG_MBEDTLS_POLY1305_C is not set -# CONFIG_MBEDTLS_CHACHA20_C is not set -# CONFIG_MBEDTLS_HKDF_C is not set -# CONFIG_MBEDTLS_THREADING_C is not set -CONFIG_MBEDTLS_ERROR_STRINGS=y -CONFIG_MBEDTLS_FS_IO=y -# end of mbedTLS - -# -# ESP-MQTT Configurations -# -CONFIG_MQTT_PROTOCOL_311=y -# CONFIG_MQTT_PROTOCOL_5 is not set -CONFIG_MQTT_TRANSPORT_SSL=y -CONFIG_MQTT_TRANSPORT_WEBSOCKET=y -CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y -# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set -# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set -# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set -# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set -# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set -# CONFIG_MQTT_CUSTOM_OUTBOX is not set -# end of ESP-MQTT Configurations - -# -# Newlib -# -CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set -CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y -# CONFIG_NEWLIB_NANO_FORMAT is not set -CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y -# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set -# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set -# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set -# end of Newlib - -# -# NVS -# -# CONFIG_NVS_ASSERT_ERROR_CHECK is not set -# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set -# end of NVS - -# -# OpenThread -# -# CONFIG_OPENTHREAD_ENABLED is not set - -# -# OpenThread Spinel -# -# CONFIG_OPENTHREAD_SPINEL_ONLY is not set -# end of OpenThread Spinel -# end of OpenThread - -# -# Protocomm -# -CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y -CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y -CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y -CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_PATCH_VERSION=y -# end of Protocomm - -# -# PThreads -# -CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 -CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 -CONFIG_PTHREAD_STACK_MIN=768 -CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y -# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set -# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set -CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 -CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" -# end of PThreads - -# -# MMU Config -# -CONFIG_MMU_PAGE_SIZE_64KB=y -CONFIG_MMU_PAGE_MODE="64KB" -CONFIG_MMU_PAGE_SIZE=0x10000 -# end of MMU Config - -# -# Main Flash configuration -# - -# -# SPI Flash behavior when brownout -# -CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y -CONFIG_SPI_FLASH_BROWNOUT_RESET=y -# end of SPI Flash behavior when brownout - -# -# Optional and Experimental Features (READ DOCS FIRST) -# - -# -# Features here require specific hardware (READ DOCS FIRST!) -# -CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 -# CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set -# end of Optional and Experimental Features (READ DOCS FIRST) -# end of Main Flash configuration - -# -# SPI Flash driver -# -# CONFIG_SPI_FLASH_VERIFY_WRITE is not set -# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set -CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y -CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y -# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set -# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set -# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set -# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set -CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y -CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 -CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 -CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 -# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set -# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set -# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set - -# -# Auto-detect flash chips -# -CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y -CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y -CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y -CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y -CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y -CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y -# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set -# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set -# end of Auto-detect flash chips - -CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y -# end of SPI Flash driver - -# -# SPIFFS Configuration -# -CONFIG_SPIFFS_MAX_PARTITIONS=3 - -# -# SPIFFS Cache Configuration -# -CONFIG_SPIFFS_CACHE=y -CONFIG_SPIFFS_CACHE_WR=y -# CONFIG_SPIFFS_CACHE_STATS is not set -# end of SPIFFS Cache Configuration - -CONFIG_SPIFFS_PAGE_CHECK=y -CONFIG_SPIFFS_GC_MAX_RUNS=10 -# CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 -# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set -CONFIG_SPIFFS_USE_MAGIC=y -CONFIG_SPIFFS_USE_MAGIC_LENGTH=y -CONFIG_SPIFFS_META_LENGTH=4 -CONFIG_SPIFFS_USE_MTIME=y - -# -# Debug Configuration -# -# CONFIG_SPIFFS_DBG is not set -# CONFIG_SPIFFS_API_DBG is not set -# CONFIG_SPIFFS_GC_DBG is not set -# CONFIG_SPIFFS_CACHE_DBG is not set -# CONFIG_SPIFFS_CHECK_DBG is not set -# CONFIG_SPIFFS_TEST_VISUALISATION is not set -# end of Debug Configuration -# end of SPIFFS Configuration - -# -# TCP Transport -# - -# -# Websocket -# -CONFIG_WS_TRANSPORT=y -CONFIG_WS_BUFFER_SIZE=1024 -# CONFIG_WS_DYNAMIC_BUFFER is not set -# end of Websocket -# end of TCP Transport - -# -# Ultra Low Power (ULP) Co-processor -# -# CONFIG_ULP_COPROC_ENABLED is not set - -# -# ULP Debugging Options -# -# end of ULP Debugging Options -# end of Ultra Low Power (ULP) Co-processor - -# -# Unity unit testing library -# -CONFIG_UNITY_ENABLE_FLOAT=y -CONFIG_UNITY_ENABLE_DOUBLE=y -# CONFIG_UNITY_ENABLE_64BIT is not set -# CONFIG_UNITY_ENABLE_COLOR is not set -CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y -# CONFIG_UNITY_ENABLE_FIXTURE is not set -# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set -# end of Unity unit testing library - -# -# Virtual file system -# -CONFIG_VFS_SUPPORT_IO=y -CONFIG_VFS_SUPPORT_DIR=y -CONFIG_VFS_SUPPORT_SELECT=y -CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y -# CONFIG_VFS_SELECT_IN_RAM is not set -CONFIG_VFS_SUPPORT_TERMIOS=y -CONFIG_VFS_MAX_COUNT=8 - -# -# Host File System I/O (Semihosting) -# -CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -# end of Host File System I/O (Semihosting) - -CONFIG_VFS_INITIALIZE_DEV_NULL=y -# end of Virtual file system - -# -# Wear Levelling -# -# CONFIG_WL_SECTOR_SIZE_512 is not set -CONFIG_WL_SECTOR_SIZE_4096=y -CONFIG_WL_SECTOR_SIZE=4096 -# end of Wear Levelling - -# -# Wi-Fi Provisioning Manager -# -CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 -CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 -CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y -# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set -# end of Wi-Fi Provisioning Manager -# end of Component config - -# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set - -# Deprecated options for backward compatibility -# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set -# CONFIG_NO_BLOBS is not set -# CONFIG_ESP32_NO_BLOBS is not set -# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set -# CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set -CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y -# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set -CONFIG_LOG_BOOTLOADER_LEVEL=3 -# CONFIG_APP_ROLLBACK_ENABLE is not set -# CONFIG_FLASH_ENCRYPTION_ENABLED is not set -# CONFIG_FLASHMODE_QIO is not set -# CONFIG_FLASHMODE_QOUT is not set -CONFIG_FLASHMODE_DIO=y -# CONFIG_FLASHMODE_DOUT is not set -CONFIG_MONITOR_BAUD=115200 -CONFIG_OPTIMIZATION_LEVEL_DEBUG=y -CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y -CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y -# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set -# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set -CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y -# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set -# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set -CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 -# CONFIG_CXX_EXCEPTIONS is not set -CONFIG_STACK_CHECK_NONE=y -# CONFIG_STACK_CHECK_NORM is not set -# CONFIG_STACK_CHECK_STRONG is not set -# CONFIG_STACK_CHECK_ALL is not set -# CONFIG_WARN_WRITE_STRINGS is not set -# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set -CONFIG_ESP32_APPTRACE_DEST_NONE=y -CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y -CONFIG_ADC2_DISABLE_DAC=y -# CONFIG_MCPWM_ISR_IN_IRAM is not set -# CONFIG_EVENT_LOOP_PROFILING is not set -CONFIG_POST_EVENTS_FROM_ISR=y -CONFIG_POST_EVENTS_FROM_IRAM_ISR=y -CONFIG_GDBSTUB_SUPPORT_TASKS=y -CONFIG_GDBSTUB_MAX_TASKS=32 -# CONFIG_OTA_ALLOW_HTTP is not set -# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set -CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y -CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 -# CONFIG_ESP_SYSTEM_PD_FLASH is not set -CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 -CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 -CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y -CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y -# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set -# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set -# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set -# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set -# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set -# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set -CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 -# CONFIG_ESP32_XTAL_FREQ_26 is not set -CONFIG_ESP32_XTAL_FREQ_40=y -# CONFIG_ESP32_XTAL_FREQ_AUTO is not set -CONFIG_ESP32_XTAL_FREQ=40 -CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y -# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set -CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 -CONFIG_ESP32_PHY_MAX_TX_POWER=20 -# CONFIG_REDUCE_PHY_TX_POWER is not set -# CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set -# CONFIG_SPIRAM_SUPPORT is not set -# CONFIG_ESP32_SPIRAM_SUPPORT is not set -# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set -CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y -# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set -CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160 -CONFIG_TRACEMEM_RESERVE_DRAM=0x0 -# CONFIG_ESP32_PANIC_PRINT_HALT is not set -CONFIG_ESP32_PANIC_PRINT_REBOOT=y -# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set -# CONFIG_ESP32_PANIC_GDBSTUB is not set -CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_MAIN_TASK_STACK_SIZE=3584 -CONFIG_CONSOLE_UART_DEFAULT=y -# CONFIG_CONSOLE_UART_CUSTOM is not set -# CONFIG_CONSOLE_UART_NONE is not set -# CONFIG_ESP_CONSOLE_UART_NONE is not set -CONFIG_CONSOLE_UART=y -CONFIG_CONSOLE_UART_NUM=0 -CONFIG_CONSOLE_UART_BAUDRATE=115200 -CONFIG_INT_WDT=y -CONFIG_INT_WDT_TIMEOUT_MS=300 -CONFIG_INT_WDT_CHECK_CPU1=y -CONFIG_TASK_WDT=y -CONFIG_ESP_TASK_WDT=y -# CONFIG_TASK_WDT_PANIC is not set -CONFIG_TASK_WDT_TIMEOUT_S=5 -CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y -CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set -CONFIG_ESP32_DEBUG_OCDAWARE=y -CONFIG_BROWNOUT_DET=y -CONFIG_ESP32_BROWNOUT_DET=y -CONFIG_BROWNOUT_DET_LVL_SEL_0=y -CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y -# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set -CONFIG_BROWNOUT_DET_LVL=0 -CONFIG_ESP32_BROWNOUT_DET_LVL=0 -# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set -CONFIG_IPC_TASK_STACK_SIZE=1024 -CONFIG_TIMER_TASK_STACK_SIZE=3584 -CONFIG_ESP32_WIFI_ENABLED=y -CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 -CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 -# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set -CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 -CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 -# CONFIG_ESP32_WIFI_CSI_ENABLED is not set -CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y -CONFIG_ESP32_WIFI_TX_BA_WIN=6 -CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y -CONFIG_ESP32_WIFI_RX_BA_WIN=6 -CONFIG_ESP32_WIFI_NVS_ENABLED=y -CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y -# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set -CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 -CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 -CONFIG_ESP32_WIFI_IRAM_OPT=y -CONFIG_ESP32_WIFI_RX_IRAM_OPT=y -CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y -CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y -CONFIG_WPA_MBEDTLS_CRYPTO=y -CONFIG_WPA_MBEDTLS_TLS_CLIENT=y -# CONFIG_WPA_WAPI_PSK is not set -# CONFIG_WPA_11KV_SUPPORT is not set -# CONFIG_WPA_MBO_SUPPORT is not set -# CONFIG_WPA_DPP_SUPPORT is not set -# CONFIG_WPA_11R_SUPPORT is not set -# CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set -# CONFIG_WPA_WPS_STRICT is not set -# CONFIG_WPA_DEBUG_PRINT is not set -# CONFIG_WPA_TESTING_OPTIONS is not set -# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set -# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set -CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y -CONFIG_TIMER_TASK_PRIORITY=1 -CONFIG_TIMER_TASK_STACK_DEPTH=2048 -CONFIG_TIMER_QUEUE_LENGTH=10 -# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set -# CONFIG_HAL_ASSERTION_SILIENT is not set -# CONFIG_L2_TO_L3_COPY is not set -CONFIG_ESP_GRATUITOUS_ARP=y -CONFIG_GARP_TMR_INTERVAL=60 -CONFIG_TCPIP_RECVMBOX_SIZE=32 -CONFIG_TCP_MAXRTX=12 -CONFIG_TCP_SYNMAXRTX=12 -CONFIG_TCP_MSS=1440 -CONFIG_TCP_MSL=60000 -CONFIG_TCP_SND_BUF_DEFAULT=5760 -CONFIG_TCP_WND_DEFAULT=5760 -CONFIG_TCP_RECVMBOX_SIZE=6 -CONFIG_TCP_QUEUE_OOSEQ=y -CONFIG_TCP_OVERSIZE_MSS=y -# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_TCP_OVERSIZE_DISABLE is not set -CONFIG_UDP_RECVMBOX_SIZE=6 -CONFIG_TCPIP_TASK_STACK_SIZE=3072 -CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y -# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set -# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set -CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF -# CONFIG_PPP_SUPPORT is not set -CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y -CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y -# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set -# CONFIG_ESP32_TIME_SYSCALL_USE_HRT is not set -# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set -# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set -CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 -CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 -CONFIG_ESP32_PTHREAD_STACK_MIN=768 -CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y -# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set -# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set -CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 -CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" -CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y -# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set -# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set -# CONFIG_ESP32_ULP_COPROC_ENABLED is not set -CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y -CONFIG_SUPPORT_TERMIOS=y -CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -# End of deprecated options diff --git a/sdkconfig.release b/sdkconfig.release deleted file mode 100644 index 6aa2dd4c..00000000 --- a/sdkconfig.release +++ /dev/null @@ -1,2548 +0,0 @@ -# -# Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) 5.4.1 Project Configuration -# -CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined" -CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined" -CONFIG_SOC_DPORT_WORKAROUND="Not determined" -CONFIG_SOC_CAPS_ECO_VER_MAX=301 -CONFIG_SOC_ADC_SUPPORTED=y -CONFIG_SOC_DAC_SUPPORTED=y -CONFIG_SOC_UART_SUPPORTED=y -CONFIG_SOC_MCPWM_SUPPORTED=y -CONFIG_SOC_GPTIMER_SUPPORTED=y -CONFIG_SOC_SDMMC_HOST_SUPPORTED=y -CONFIG_SOC_BT_SUPPORTED=y -CONFIG_SOC_PCNT_SUPPORTED=y -CONFIG_SOC_PHY_SUPPORTED=y -CONFIG_SOC_WIFI_SUPPORTED=y -CONFIG_SOC_SDIO_SLAVE_SUPPORTED=y -CONFIG_SOC_TWAI_SUPPORTED=y -CONFIG_SOC_EFUSE_SUPPORTED=y -CONFIG_SOC_EMAC_SUPPORTED=y -CONFIG_SOC_ULP_SUPPORTED=y -CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y -CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y -CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y -CONFIG_SOC_RTC_MEM_SUPPORTED=y -CONFIG_SOC_I2S_SUPPORTED=y -CONFIG_SOC_RMT_SUPPORTED=y -CONFIG_SOC_SDM_SUPPORTED=y -CONFIG_SOC_GPSPI_SUPPORTED=y -CONFIG_SOC_LEDC_SUPPORTED=y -CONFIG_SOC_I2C_SUPPORTED=y -CONFIG_SOC_SUPPORT_COEXISTENCE=y -CONFIG_SOC_AES_SUPPORTED=y -CONFIG_SOC_MPI_SUPPORTED=y -CONFIG_SOC_SHA_SUPPORTED=y -CONFIG_SOC_FLASH_ENC_SUPPORTED=y -CONFIG_SOC_SECURE_BOOT_SUPPORTED=y -CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y -CONFIG_SOC_BOD_SUPPORTED=y -CONFIG_SOC_ULP_FSM_SUPPORTED=y -CONFIG_SOC_CLK_TREE_SUPPORTED=y -CONFIG_SOC_MPU_SUPPORTED=y -CONFIG_SOC_WDT_SUPPORTED=y -CONFIG_SOC_SPI_FLASH_SUPPORTED=y -CONFIG_SOC_RNG_SUPPORTED=y -CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y -CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y -CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y -CONFIG_SOC_PM_SUPPORTED=y -CONFIG_SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL=5 -CONFIG_SOC_XTAL_SUPPORT_26M=y -CONFIG_SOC_XTAL_SUPPORT_40M=y -CONFIG_SOC_XTAL_SUPPORT_AUTO_DETECT=y -CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y -CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y -CONFIG_SOC_ADC_DMA_SUPPORTED=y -CONFIG_SOC_ADC_PERIPH_NUM=2 -CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 -CONFIG_SOC_ADC_ATTEN_NUM=4 -CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 -CONFIG_SOC_ADC_PATT_LEN_MAX=16 -CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=9 -CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 -CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 -CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=4 -CONFIG_SOC_ADC_DIGI_MONITOR_NUM=0 -CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=2 -CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=20 -CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=9 -CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=12 -CONFIG_SOC_ADC_SHARED_POWER=y -CONFIG_SOC_SHARED_IDCACHE_SUPPORTED=y -CONFIG_SOC_IDCACHE_PER_CORE=y -CONFIG_SOC_CPU_CORES_NUM=2 -CONFIG_SOC_CPU_INTR_NUM=32 -CONFIG_SOC_CPU_HAS_FPU=y -CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y -CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 -CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 -CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 -CONFIG_SOC_DAC_CHAN_NUM=2 -CONFIG_SOC_DAC_RESOLUTION=8 -CONFIG_SOC_DAC_DMA_16BIT_ALIGN=y -CONFIG_SOC_GPIO_PORT=1 -CONFIG_SOC_GPIO_PIN_COUNT=40 -CONFIG_SOC_GPIO_VALID_GPIO_MASK=0xFFFFFFFFFF -CONFIG_SOC_GPIO_IN_RANGE_MAX=39 -CONFIG_SOC_GPIO_OUT_RANGE_MAX=33 -CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0xEF0FEA -CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y -CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3 -CONFIG_SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP=y -CONFIG_SOC_I2C_NUM=2 -CONFIG_SOC_HP_I2C_NUM=2 -CONFIG_SOC_I2C_FIFO_LEN=32 -CONFIG_SOC_I2C_CMD_REG_NUM=16 -CONFIG_SOC_I2C_SUPPORT_SLAVE=y -CONFIG_SOC_I2C_SUPPORT_APB=y -CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR=y -CONFIG_SOC_I2C_STOP_INDEPENDENT=y -CONFIG_SOC_I2S_NUM=2 -CONFIG_SOC_I2S_HW_VERSION_1=y -CONFIG_SOC_I2S_SUPPORTS_APLL=y -CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y -CONFIG_SOC_I2S_SUPPORTS_PDM=y -CONFIG_SOC_I2S_SUPPORTS_PDM_TX=y -CONFIG_SOC_I2S_PDM_MAX_TX_LINES=1 -CONFIG_SOC_I2S_SUPPORTS_PDM_RX=y -CONFIG_SOC_I2S_PDM_MAX_RX_LINES=1 -CONFIG_SOC_I2S_SUPPORTS_ADC_DAC=y -CONFIG_SOC_I2S_SUPPORTS_ADC=y -CONFIG_SOC_I2S_SUPPORTS_DAC=y -CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y -CONFIG_SOC_I2S_MAX_DATA_WIDTH=24 -CONFIG_SOC_I2S_TRANS_SIZE_ALIGN_WORD=y -CONFIG_SOC_I2S_LCD_I80_VARIANT=y -CONFIG_SOC_LCD_I80_SUPPORTED=y -CONFIG_SOC_LCD_I80_BUSES=2 -CONFIG_SOC_LCD_I80_BUS_WIDTH=24 -CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y -CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y -CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y -CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y -CONFIG_SOC_LEDC_TIMER_NUM=4 -CONFIG_SOC_LEDC_CHANNEL_NUM=8 -CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=20 -CONFIG_SOC_MCPWM_GROUPS=2 -CONFIG_SOC_MCPWM_TIMERS_PER_GROUP=3 -CONFIG_SOC_MCPWM_OPERATORS_PER_GROUP=3 -CONFIG_SOC_MCPWM_COMPARATORS_PER_OPERATOR=2 -CONFIG_SOC_MCPWM_GENERATORS_PER_OPERATOR=2 -CONFIG_SOC_MCPWM_TRIGGERS_PER_OPERATOR=2 -CONFIG_SOC_MCPWM_GPIO_FAULTS_PER_GROUP=3 -CONFIG_SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP=y -CONFIG_SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER=3 -CONFIG_SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP=3 -CONFIG_SOC_MMU_PERIPH_NUM=2 -CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=3 -CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 -CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 -CONFIG_SOC_PCNT_GROUPS=1 -CONFIG_SOC_PCNT_UNITS_PER_GROUP=8 -CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 -CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 -CONFIG_SOC_RMT_GROUPS=1 -CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=8 -CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=8 -CONFIG_SOC_RMT_CHANNELS_PER_GROUP=8 -CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 -CONFIG_SOC_RMT_SUPPORT_REF_TICK=y -CONFIG_SOC_RMT_SUPPORT_APB=y -CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y -CONFIG_SOC_RTCIO_PIN_COUNT=18 -CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y -CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y -CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y -CONFIG_SOC_SDM_GROUPS=1 -CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 -CONFIG_SOC_SDM_CLK_SUPPORT_APB=y -CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y -CONFIG_SOC_SPI_AS_CS_SUPPORTED=y -CONFIG_SOC_SPI_PERIPH_NUM=3 -CONFIG_SOC_SPI_DMA_CHAN_NUM=2 -CONFIG_SOC_SPI_MAX_CS_NUM=3 -CONFIG_SOC_SPI_SUPPORT_CLK_APB=y -CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=64 -CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 -CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y -CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y -CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y -CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y -CONFIG_SOC_TIMER_GROUPS=2 -CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 -CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 -CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 -CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y -CONFIG_SOC_LP_TIMER_BIT_WIDTH_LO=32 -CONFIG_SOC_LP_TIMER_BIT_WIDTH_HI=16 -CONFIG_SOC_TOUCH_SENSOR_VERSION=1 -CONFIG_SOC_TOUCH_SENSOR_NUM=10 -CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1 -CONFIG_SOC_TWAI_CONTROLLER_NUM=1 -CONFIG_SOC_TWAI_BRP_MIN=2 -CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y -CONFIG_SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT=y -CONFIG_SOC_UART_NUM=3 -CONFIG_SOC_UART_HP_NUM=3 -CONFIG_SOC_UART_SUPPORT_APB_CLK=y -CONFIG_SOC_UART_SUPPORT_REF_TICK=y -CONFIG_SOC_UART_FIFO_LEN=128 -CONFIG_SOC_UART_BITRATE_MAX=5000000 -CONFIG_SOC_SPIRAM_SUPPORTED=y -CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y -CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG=y -CONFIG_SOC_SHA_ENDIANNESS_BE=y -CONFIG_SOC_SHA_SUPPORT_SHA1=y -CONFIG_SOC_SHA_SUPPORT_SHA256=y -CONFIG_SOC_SHA_SUPPORT_SHA384=y -CONFIG_SOC_SHA_SUPPORT_SHA512=y -CONFIG_SOC_MPI_MEM_BLOCKS_NUM=4 -CONFIG_SOC_MPI_OPERATIONS_NUM=y -CONFIG_SOC_RSA_MAX_BIT_LEN=4096 -CONFIG_SOC_AES_SUPPORT_AES_128=y -CONFIG_SOC_AES_SUPPORT_AES_192=y -CONFIG_SOC_AES_SUPPORT_AES_256=y -CONFIG_SOC_SECURE_BOOT_V1=y -CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=y -CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=32 -CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 -CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y -CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y -CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y -CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y -CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y -CONFIG_SOC_PM_SUPPORT_MODEM_PD=y -CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y -CONFIG_SOC_PM_MODEM_PD_BY_SW=y -CONFIG_SOC_CLK_APLL_SUPPORTED=y -CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y -CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y -CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y -CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y -CONFIG_SOC_SDMMC_USE_IOMUX=y -CONFIG_SOC_SDMMC_NUM_SLOTS=2 -CONFIG_SOC_WIFI_WAPI_SUPPORT=y -CONFIG_SOC_WIFI_CSI_SUPPORT=y -CONFIG_SOC_WIFI_MESH_SUPPORT=y -CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y -CONFIG_SOC_WIFI_NAN_SUPPORT=y -CONFIG_SOC_BLE_SUPPORTED=y -CONFIG_SOC_BLE_MESH_SUPPORTED=y -CONFIG_SOC_BT_CLASSIC_SUPPORTED=y -CONFIG_SOC_BLUFI_SUPPORTED=y -CONFIG_SOC_BT_H2C_ENC_KEY_CTRL_ENH_VSC_SUPPORTED=y -CONFIG_SOC_ULP_HAS_ADC=y -CONFIG_SOC_PHY_COMBO_MODULE=y -CONFIG_SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK=y -CONFIG_IDF_CMAKE=y -CONFIG_IDF_TOOLCHAIN="gcc" -CONFIG_IDF_TOOLCHAIN_GCC=y -CONFIG_IDF_TARGET_ARCH_XTENSA=y -CONFIG_IDF_TARGET_ARCH="xtensa" -CONFIG_IDF_TARGET="esp32" -CONFIG_IDF_INIT_VERSION="5.4.1" -CONFIG_IDF_TARGET_ESP32=y -CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 - -# -# Build type -# -CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y -# CONFIG_APP_BUILD_TYPE_RAM is not set -CONFIG_APP_BUILD_GENERATE_BINARIES=y -CONFIG_APP_BUILD_BOOTLOADER=y -CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y -# CONFIG_APP_REPRODUCIBLE_BUILD is not set -# CONFIG_APP_NO_BLOBS is not set -# CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set -# CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set -# end of Build type - -# -# Bootloader config -# - -# -# Bootloader manager -# -CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y -CONFIG_BOOTLOADER_PROJECT_VER=1 -# end of Bootloader manager - -CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 -CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set - -# -# Log -# -# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set -CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y -# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set -CONFIG_BOOTLOADER_LOG_LEVEL=3 - -# -# Format -# -# CONFIG_BOOTLOADER_LOG_COLORS is not set -CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y -# end of Format -# end of Log - -# -# Serial Flash Configurations -# -# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set -CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y -# end of Serial Flash Configurations - -# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set -CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y -# CONFIG_BOOTLOADER_FACTORY_RESET is not set -# CONFIG_BOOTLOADER_APP_TEST is not set -CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y -CONFIG_BOOTLOADER_WDT_ENABLE=y -# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set -CONFIG_BOOTLOADER_WDT_TIME_MS=9000 -# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set -CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 -# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set -# end of Bootloader config - -# -# Security features -# -CONFIG_SECURE_BOOT_V1_SUPPORTED=y -# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set -# CONFIG_SECURE_BOOT is not set -# CONFIG_SECURE_FLASH_ENC_ENABLED is not set -# end of Security features - -# -# Application manager -# -CONFIG_APP_COMPILE_TIME_DATE=y -# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set -# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set -# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set -CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 -# end of Application manager - -CONFIG_ESP_ROM_HAS_CRC_LE=y -CONFIG_ESP_ROM_HAS_CRC_BE=y -CONFIG_ESP_ROM_HAS_MZ_CRC32=y -CONFIG_ESP_ROM_HAS_JPEG_DECODE=y -CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y -CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y -CONFIG_ESP_ROM_HAS_NEWLIB=y -CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y -CONFIG_ESP_ROM_HAS_NEWLIB_32BIT_TIME=y -CONFIG_ESP_ROM_HAS_SW_FLOAT=y -CONFIG_ESP_ROM_USB_OTG_NUM=-1 -CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1 -CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y -CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y - -# -# Serial flasher config -# -# CONFIG_ESPTOOLPY_NO_STUB is not set -# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set -# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set -CONFIG_ESPTOOLPY_FLASHMODE_DIO=y -# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set -CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y -CONFIG_ESPTOOLPY_FLASHMODE="dio" -# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set -CONFIG_ESPTOOLPY_FLASHFREQ_40M=y -# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set -CONFIG_ESPTOOLPY_FLASHFREQ="40m" -# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y -# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="2MB" -# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set -CONFIG_ESPTOOLPY_BEFORE_RESET=y -# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set -CONFIG_ESPTOOLPY_BEFORE="default_reset" -CONFIG_ESPTOOLPY_AFTER_RESET=y -# CONFIG_ESPTOOLPY_AFTER_NORESET is not set -CONFIG_ESPTOOLPY_AFTER="hard_reset" -CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 -# end of Serial flasher config - -# -# Partition Table -# -CONFIG_PARTITION_TABLE_SINGLE_APP=y -# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set -# CONFIG_PARTITION_TABLE_TWO_OTA is not set -# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set -# CONFIG_PARTITION_TABLE_CUSTOM is not set -CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" -CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" -CONFIG_PARTITION_TABLE_OFFSET=0x8000 -CONFIG_PARTITION_TABLE_MD5=y -# end of Partition Table - -# -# Arduino Configuration -# -CONFIG_ARDUINO_VARIANT="esp32" -CONFIG_ENABLE_ARDUINO_DEPENDS=y -# CONFIG_AUTOSTART_ARDUINO is not set -# CONFIG_ARDUINO_RUN_CORE0 is not set -CONFIG_ARDUINO_RUN_CORE1=y -# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_RUNNING_CORE=1 -CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 -# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set -CONFIG_ARDUINO_EVENT_RUN_CORE1=y -# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 -# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set -# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set -CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y -CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 -CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=2048 -CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 -CONFIG_ARDUINO_UDP_RUN_CORE0=y -# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set -# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_UDP_RUNNING_CORE=0 -CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 -# CONFIG_ARDUINO_ISR_IRAM is not set -# CONFIG_DISABLE_HAL_LOCKS is not set - -# -# Debug Log Configuration -# -CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE=y -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=0 -# CONFIG_ARDUHAL_LOG_COLORS is not set -# CONFIG_ARDUHAL_ESP_LOG is not set -# end of Debug Log Configuration - -# CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set -CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS=y -CONFIG_ARDUHAL_PARTITION_SCHEME="min_spiffs" -CONFIG_ARDUINO_SELECTIVE_COMPILATION=y -CONFIG_ARDUINO_SELECTIVE_SPI=y -CONFIG_ARDUINO_SELECTIVE_Wire=y -CONFIG_ARDUINO_SELECTIVE_ESP_SR=y -CONFIG_ARDUINO_SELECTIVE_EEPROM=y -# CONFIG_ARDUINO_SELECTIVE_Preferences is not set -# CONFIG_ARDUINO_SELECTIVE_Ticker is not set -CONFIG_ARDUINO_SELECTIVE_Update=y -# CONFIG_ARDUINO_SELECTIVE_Zigbee is not set -CONFIG_ARDUINO_SELECTIVE_FS=y -# CONFIG_ARDUINO_SELECTIVE_SD is not set -# CONFIG_ARDUINO_SELECTIVE_SD_MMC is not set -# CONFIG_ARDUINO_SELECTIVE_SPIFFS is not set -# CONFIG_ARDUINO_SELECTIVE_FFat is not set -CONFIG_ARDUINO_SELECTIVE_LittleFS=y -CONFIG_ARDUINO_SELECTIVE_Network=y -# CONFIG_ARDUINO_SELECTIVE_Ethernet is not set -CONFIG_ARDUINO_SELECTIVE_PPP=y -CONFIG_ARDUINO_SELECTIVE_ArduinoOTA=y -CONFIG_ARDUINO_SELECTIVE_AsyncUDP=y -CONFIG_ARDUINO_SELECTIVE_DNSServer=y -CONFIG_ARDUINO_SELECTIVE_ESPmDNS=y -CONFIG_ARDUINO_SELECTIVE_HTTPClient=y -# CONFIG_ARDUINO_SELECTIVE_Matter is not set -# CONFIG_ARDUINO_SELECTIVE_NetBIOS is not set -CONFIG_ARDUINO_SELECTIVE_WebServer=y -CONFIG_ARDUINO_SELECTIVE_WiFi=y -CONFIG_ARDUINO_SELECTIVE_NetworkClientSecure=y -CONFIG_ARDUINO_SELECTIVE_WiFiProv=y -CONFIG_ARDUINO_SELECTIVE_BLE=y -# CONFIG_ARDUINO_SELECTIVE_BluetoothSerial is not set -CONFIG_ARDUINO_SELECTIVE_SimpleBLE=y -# CONFIG_ARDUINO_SELECTIVE_RainMaker is not set -# CONFIG_ARDUINO_SELECTIVE_OpenThread is not set -# CONFIG_ARDUINO_SELECTIVE_Insights is not set -# end of Arduino Configuration - -# -# Compiler options -# -# CONFIG_COMPILER_OPTIMIZATION_DEBUG is not set -CONFIG_COMPILER_OPTIMIZATION_SIZE=y -# CONFIG_COMPILER_OPTIMIZATION_PERF is not set -# CONFIG_COMPILER_OPTIMIZATION_NONE is not set -CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y -# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set -# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set -CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y -CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y -CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 -# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set -CONFIG_COMPILER_HIDE_PATHS_MACROS=y -# CONFIG_COMPILER_CXX_EXCEPTIONS is not set -# CONFIG_COMPILER_CXX_RTTI is not set -CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y -# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set -# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set -# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set -# CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set -# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set -CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y -# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set -# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set -# CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set -# CONFIG_COMPILER_DUMP_RTL_FILES is not set -CONFIG_COMPILER_RT_LIB_GCCLIB=y -CONFIG_COMPILER_RT_LIB_NAME="gcc" -CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y -# CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set -# CONFIG_COMPILER_STATIC_ANALYZER is not set -# end of Compiler options - -# -# Component config -# - -# -# Application Level Tracing -# -# CONFIG_APPTRACE_DEST_JTAG is not set -CONFIG_APPTRACE_DEST_NONE=y -# CONFIG_APPTRACE_DEST_UART1 is not set -# CONFIG_APPTRACE_DEST_UART2 is not set -CONFIG_APPTRACE_DEST_UART_NONE=y -CONFIG_APPTRACE_UART_TASK_PRIO=1 -CONFIG_APPTRACE_LOCK_ENABLE=y -# end of Application Level Tracing - -# -# Bluetooth -# -CONFIG_BT_ENABLED=y -# CONFIG_BT_BLUEDROID_ENABLED is not set -CONFIG_BT_NIMBLE_ENABLED=y -# CONFIG_BT_CONTROLLER_ONLY is not set -CONFIG_BT_CONTROLLER_ENABLED=y -# CONFIG_BT_CONTROLLER_DISABLED is not set - -# -# NimBLE Options -# -CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y -# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set -# CONFIG_BT_NIMBLE_LOG_LEVEL_NONE is not set -# CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR is not set -# CONFIG_BT_NIMBLE_LOG_LEVEL_WARNING is not set -CONFIG_BT_NIMBLE_LOG_LEVEL_INFO=y -# CONFIG_BT_NIMBLE_LOG_LEVEL_DEBUG is not set -CONFIG_BT_NIMBLE_LOG_LEVEL=1 -CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 -CONFIG_BT_NIMBLE_MAX_BONDS=1 -CONFIG_BT_NIMBLE_MAX_CCCDS=1 -CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM=0 -CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y -# CONFIG_BT_NIMBLE_PINNED_TO_CORE_1 is not set -CONFIG_BT_NIMBLE_PINNED_TO_CORE=0 -CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=4096 -CONFIG_BT_NIMBLE_ROLE_CENTRAL=y -CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y -CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y -CONFIG_BT_NIMBLE_ROLE_OBSERVER=y -# CONFIG_BT_NIMBLE_NVS_PERSIST is not set -# CONFIG_BT_NIMBLE_SMP_ID_RESET is not set -# CONFIG_BT_NIMBLE_SECURITY_ENABLE is not set -# CONFIG_BT_NIMBLE_DEBUG is not set -# CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set -CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" -CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 -CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=256 -CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE=0 - -# -# Memory Settings -# -CONFIG_BT_NIMBLE_MSYS_1_BLOCK_COUNT=12 -CONFIG_BT_NIMBLE_MSYS_1_BLOCK_SIZE=256 -CONFIG_BT_NIMBLE_MSYS_2_BLOCK_COUNT=24 -CONFIG_BT_NIMBLE_MSYS_2_BLOCK_SIZE=320 -CONFIG_BT_NIMBLE_TRANSPORT_ACL_FROM_LL_COUNT=24 -CONFIG_BT_NIMBLE_TRANSPORT_ACL_SIZE=255 -CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70 -CONFIG_BT_NIMBLE_TRANSPORT_EVT_COUNT=30 -CONFIG_BT_NIMBLE_TRANSPORT_EVT_DISCARD_COUNT=8 -CONFIG_BT_NIMBLE_L2CAP_COC_SDU_BUFF_COUNT=1 -# end of Memory Settings - -CONFIG_BT_NIMBLE_GATT_MAX_PROCS=4 -CONFIG_BT_NIMBLE_HS_FLOW_CTRL=y -CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 -CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 -CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y -CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 -# CONFIG_BT_NIMBLE_MESH is not set -CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y -CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 -# CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set -# CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set -CONFIG_BT_NIMBLE_WHITELIST_SIZE=1 -# CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set -# CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set -CONFIG_BT_NIMBLE_USE_ESP_TIMER=y -CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y -# CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set - -# -# GAP Service -# - -# -# GAP Appearance write permissions -# -# CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set -# end of GAP Appearance write permissions - -CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM=0 -CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ENC=0 -CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHN=0 -CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHR=0 -CONFIG_BT_NIMBLE_SVC_GAP_CAR_CHAR_NOT_SUPP=y -# CONFIG_BT_NIMBLE_SVC_GAP_CAR_NOT_SUPP is not set -# CONFIG_BT_NIMBLE_SVC_GAP_CAR_SUPP is not set -CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 - -# -# GAP device name write permissions -# -# CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set -# end of GAP device name write permissions - -CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM=0 -CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_ENC=0 -CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHEN=0 -CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHOR=0 -CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 -CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 -CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 -CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 -# CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL is not set -# end of GAP Service - -# -# BLE Services -# -# CONFIG_BT_NIMBLE_HID_SERVICE is not set -# CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY is not set - -# -# Device Information Service -# -# CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME is not set -# CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER is not set -# CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION is not set -# CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION is not set -# CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION is not set -# CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID is not set -# CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID is not set -# CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED is not set -# end of Device Information Service -# end of BLE Services - -# CONFIG_BT_NIMBLE_VS_SUPPORT is not set -# CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set -# CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set -# CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set -# CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT is not set - -# -# Host-controller Transport -# -CONFIG_UART_HW_FLOWCTRL_DISABLE=y -# CONFIG_UART_HW_FLOWCTRL_CTS_RTS is not set -CONFIG_BT_NIMBLE_HCI_UART_FLOW_CTRL=0 -CONFIG_BT_NIMBLE_HCI_UART_RTS_PIN=19 -CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 -# end of Host-controller Transport - -CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 -# CONFIG_BT_NIMBLE_SUBRATE is not set -# end of NimBLE Options - -# -# Controller Options -# -CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y -# CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set -# CONFIG_BTDM_CTRL_MODE_BTDM is not set -CONFIG_BTDM_CTRL_BLE_MAX_CONN=3 -CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 -CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 -CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 -CONFIG_BTDM_CTRL_PCM_FSYNCSHP_EFF=0 -CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=3 -CONFIG_BTDM_CTRL_BR_EDR_MIN_ENC_KEY_SZ_DFT_EFF=0 -CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 -CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 -CONFIG_BTDM_CTRL_PINNED_TO_CORE_0=y -# CONFIG_BTDM_CTRL_PINNED_TO_CORE_1 is not set -CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 -CONFIG_BTDM_CTRL_HCI_MODE_VHCI=y -# CONFIG_BTDM_CTRL_HCI_MODE_UART_H4 is not set - -# -# MODEM SLEEP Options -# -CONFIG_BTDM_CTRL_MODEM_SLEEP=y -CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG=y -# CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_EVED is not set -CONFIG_BTDM_CTRL_LPCLK_SEL_MAIN_XTAL=y -# end of MODEM SLEEP Options - -CONFIG_BTDM_BLE_DEFAULT_SCA_250PPM=y -CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 -CONFIG_BTDM_BLE_SCAN_DUPL=y -CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y -# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA is not set -# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE is not set -CONFIG_BTDM_SCAN_DUPL_TYPE=0 -CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 -CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 -# CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set -CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y -# CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set -# CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set -CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y -CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 -CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 - -# -# BLE disconnects when Instant Passed (0x28) occurs -# -# CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set -# CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set -# end of BLE disconnects when Instant Passed (0x28) occurs - -CONFIG_BTDM_BLE_CHAN_ASS_EN=y -CONFIG_BTDM_BLE_PING_EN=y -# CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 is not set -CONFIG_BTDM_RESERVE_DRAM=0xdb5c -CONFIG_BTDM_CTRL_HLI=y -# end of Controller Options - -# -# Common Options -# -CONFIG_BT_ALARM_MAX_NUM=50 -# CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set -# end of Common Options - -# CONFIG_BT_HCI_LOG_DEBUG_EN is not set -# end of Bluetooth - -# CONFIG_BLE_MESH is not set - -# -# Console Library -# -# CONFIG_CONSOLE_SORTED_HELP is not set -# end of Console Library - -# -# Driver Configurations -# - -# -# TWAI Configuration -# -# CONFIG_TWAI_ISR_IN_IRAM is not set -CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y -CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y -CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID=y -CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT=y -CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y -# end of TWAI Configuration - -# -# Legacy ADC Driver Configuration -# -CONFIG_ADC_DISABLE_DAC=y -# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set - -# -# Legacy ADC Calibration Configuration -# -CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y -CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y -CONFIG_ADC_CAL_LUT_ENABLE=y -# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set -# end of Legacy ADC Calibration Configuration -# end of Legacy ADC Driver Configuration - -# -# Legacy DAC Driver Configurations -# -# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy DAC Driver Configurations - -# -# Legacy MCPWM Driver Configurations -# -# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy MCPWM Driver Configurations - -# -# Legacy Timer Group Driver Configurations -# -# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy Timer Group Driver Configurations - -# -# Legacy RMT Driver Configurations -# -# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy RMT Driver Configurations - -# -# Legacy I2S Driver Configurations -# -# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy I2S Driver Configurations - -# -# Legacy PCNT Driver Configurations -# -# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy PCNT Driver Configurations - -# -# Legacy SDM Driver Configurations -# -# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy SDM Driver Configurations -# end of Driver Configurations - -# -# eFuse Bit Manager -# -# CONFIG_EFUSE_CUSTOM_TABLE is not set -# CONFIG_EFUSE_VIRTUAL is not set -# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set -CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y -# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set -CONFIG_EFUSE_MAX_BLK_LEN=192 -# end of eFuse Bit Manager - -# -# ESP-TLS -# -CONFIG_ESP_TLS_USING_MBEDTLS=y -# CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set -# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set -# CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set -# CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set -# CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set -# CONFIG_ESP_TLS_PSK_VERIFICATION is not set -# CONFIG_ESP_TLS_INSECURE is not set -# end of ESP-TLS - -# -# ADC and ADC Calibration -# -# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set -# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set - -# -# ADC Calibration Configurations -# -CONFIG_ADC_CALI_EFUSE_TP_ENABLE=y -CONFIG_ADC_CALI_EFUSE_VREF_ENABLE=y -CONFIG_ADC_CALI_LUT_ENABLE=y -# end of ADC Calibration Configurations - -CONFIG_ADC_DISABLE_DAC_OUTPUT=y -# CONFIG_ADC_ENABLE_DEBUG_LOG is not set -# end of ADC and ADC Calibration - -# -# Wireless Coexistence -# -CONFIG_ESP_COEX_ENABLED=y -CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y -# CONFIG_ESP_COEX_POWER_MANAGEMENT is not set -# CONFIG_ESP_COEX_GPIO_DEBUG is not set -# end of Wireless Coexistence - -# -# Common ESP-related -# -CONFIG_ESP_ERR_TO_NAME_LOOKUP=y -# end of Common ESP-related - -# -# ESP-Driver:DAC Configurations -# -# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set -# CONFIG_DAC_ISR_IRAM_SAFE is not set -# CONFIG_DAC_ENABLE_DEBUG_LOG is not set -CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y -# end of ESP-Driver:DAC Configurations - -# -# ESP-Driver:GPIO Configurations -# -# CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set -# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set -# end of ESP-Driver:GPIO Configurations - -# -# ESP-Driver:GPTimer Configurations -# -CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y -# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set -# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set -# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:GPTimer Configurations - -# -# ESP-Driver:I2C Configurations -# -# CONFIG_I2C_ISR_IRAM_SAFE is not set -# CONFIG_I2C_ENABLE_DEBUG_LOG is not set -# CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set -# end of ESP-Driver:I2C Configurations - -# -# ESP-Driver:I2S Configurations -# -# CONFIG_I2S_ISR_IRAM_SAFE is not set -# CONFIG_I2S_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:I2S Configurations - -# -# ESP-Driver:LEDC Configurations -# -# CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set -# end of ESP-Driver:LEDC Configurations - -# -# ESP-Driver:MCPWM Configurations -# -# CONFIG_MCPWM_ISR_IRAM_SAFE is not set -# CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set -# CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:MCPWM Configurations - -# -# ESP-Driver:PCNT Configurations -# -# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set -# CONFIG_PCNT_ISR_IRAM_SAFE is not set -# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:PCNT Configurations - -# -# ESP-Driver:RMT Configurations -# -# CONFIG_RMT_ISR_IRAM_SAFE is not set -# CONFIG_RMT_RECV_FUNC_IN_IRAM is not set -# CONFIG_RMT_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:RMT Configurations - -# -# ESP-Driver:Sigma Delta Modulator Configurations -# -# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set -# CONFIG_SDM_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:Sigma Delta Modulator Configurations - -# -# ESP-Driver:SPI Configurations -# -# CONFIG_SPI_MASTER_IN_IRAM is not set -CONFIG_SPI_MASTER_ISR_IN_IRAM=y -# CONFIG_SPI_SLAVE_IN_IRAM is not set -CONFIG_SPI_SLAVE_ISR_IN_IRAM=y -# end of ESP-Driver:SPI Configurations - -# -# ESP-Driver:Touch Sensor Configurations -# -# CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set -# CONFIG_TOUCH_ISR_IRAM_SAFE is not set -# CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:Touch Sensor Configurations - -# -# ESP-Driver:UART Configurations -# -# CONFIG_UART_ISR_IN_IRAM is not set -# end of ESP-Driver:UART Configurations - -# -# Ethernet -# -# CONFIG_ETH_USE_ESP32_EMAC is not set -# CONFIG_ETH_USE_SPI_ETHERNET is not set -# CONFIG_ETH_USE_OPENETH is not set -# end of Ethernet - -# -# Event Loop Library -# -# CONFIG_ESP_EVENT_LOOP_PROFILING is not set -CONFIG_ESP_EVENT_POST_FROM_ISR=y -CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y -# end of Event Loop Library - -# -# GDB Stub -# -CONFIG_ESP_GDBSTUB_ENABLED=y -# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set -CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y -CONFIG_ESP_GDBSTUB_MAX_TASKS=32 -# end of GDB Stub - -# -# ESP HID -# -CONFIG_ESPHID_TASK_SIZE_BT=2048 -CONFIG_ESPHID_TASK_SIZE_BLE=4096 -# end of ESP HID - -# -# ESP HTTP client -# -CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y -# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set -# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set -# CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set -CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 -# end of ESP HTTP client - -# -# HTTP Server -# -CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 -CONFIG_HTTPD_MAX_URI_LEN=512 -CONFIG_HTTPD_ERR_RESP_NO_DELAY=y -CONFIG_HTTPD_PURGE_BUF_LEN=32 -# CONFIG_HTTPD_LOG_PURGE_DATA is not set -# CONFIG_HTTPD_WS_SUPPORT is not set -# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set -CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 -# end of HTTP Server - -# -# ESP HTTPS OTA -# -# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set -# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set -CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 -# end of ESP HTTPS OTA - -# -# ESP HTTPS server -# -# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set -CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 -# end of ESP HTTPS server - -# -# Hardware Settings -# - -# -# Chip revision -# -CONFIG_ESP32_REV_MIN_0=y -# CONFIG_ESP32_REV_MIN_1 is not set -# CONFIG_ESP32_REV_MIN_1_1 is not set -# CONFIG_ESP32_REV_MIN_2 is not set -# CONFIG_ESP32_REV_MIN_3 is not set -# CONFIG_ESP32_REV_MIN_3_1 is not set -CONFIG_ESP32_REV_MIN=0 -CONFIG_ESP32_REV_MIN_FULL=0 -CONFIG_ESP_REV_MIN_FULL=0 - -# -# Maximum Supported ESP32 Revision (Rev v3.99) -# -CONFIG_ESP32_REV_MAX_FULL=399 -CONFIG_ESP_REV_MAX_FULL=399 -CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL=0 -CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL=99 - -# -# Maximum Supported ESP32 eFuse Block Revision (eFuse Block Rev v0.99) -# -# end of Chip revision - -# -# MAC Config -# -CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y -CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_FOUR=y -CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 -# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set -CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y -CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 -# CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set -# CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set -# end of MAC Config - -# -# Sleep Config -# -# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set -CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y -# CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set -CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y -# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set -CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 -# CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set -# CONFIG_ESP_SLEEP_DEBUG is not set -CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y -# end of Sleep Config - -# -# RTC Clock Config -# -CONFIG_RTC_CLK_SRC_INT_RC=y -# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set -# CONFIG_RTC_CLK_SRC_EXT_OSC is not set -# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set -CONFIG_RTC_CLK_CAL_CYCLES=1024 -# end of RTC Clock Config - -# -# Peripheral Control -# -CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y -# end of Peripheral Control - -# -# Main XTAL Config -# -# CONFIG_XTAL_FREQ_26 is not set -# CONFIG_XTAL_FREQ_32 is not set -CONFIG_XTAL_FREQ_40=y -# CONFIG_XTAL_FREQ_AUTO is not set -CONFIG_XTAL_FREQ=40 -# end of Main XTAL Config - -CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y -# end of Hardware Settings - -# -# ESP-Driver:LCD Controller Configurations -# -# CONFIG_LCD_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:LCD Controller Configurations - -# -# ESP-MM: Memory Management Configurations -# -# end of ESP-MM: Memory Management Configurations - -# -# ESP NETIF Adapter -# -CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 -# CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set -CONFIG_ESP_NETIF_TCPIP_LWIP=y -# CONFIG_ESP_NETIF_LOOPBACK is not set -CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y -CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y -# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set -# CONFIG_ESP_NETIF_L2_TAP is not set -# CONFIG_ESP_NETIF_BRIDGE_EN is not set -# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set -# end of ESP NETIF Adapter - -# -# Partition API Configuration -# -# end of Partition API Configuration - -# -# PHY -# -CONFIG_ESP_PHY_ENABLED=y -CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y -# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set -CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 -CONFIG_ESP_PHY_MAX_TX_POWER=20 -# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set -# CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set -CONFIG_ESP_PHY_RF_CAL_PARTIAL=y -# CONFIG_ESP_PHY_RF_CAL_NONE is not set -# CONFIG_ESP_PHY_RF_CAL_FULL is not set -CONFIG_ESP_PHY_CALIBRATION_MODE=0 -# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set -# CONFIG_ESP_PHY_RECORD_USED_TIME is not set -# end of PHY - -# -# Power Management -# -# CONFIG_PM_ENABLE is not set -# CONFIG_PM_SLP_IRAM_OPT is not set -# end of Power Management - -# -# ESP PSRAM -# -# CONFIG_SPIRAM is not set -# end of ESP PSRAM - -# -# ESP Ringbuf -# -# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set -# end of ESP Ringbuf - -# -# ESP Security Specific -# -# end of ESP Security Specific - -# -# ESP System Settings -# -# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set -CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y -# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set -CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 - -# -# Memory -# -# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set - -# -# Non-backward compatible options -# -# CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set -# end of Non-backward compatible options -# end of Memory - -# -# Trace memory -# -# CONFIG_ESP32_TRAX is not set -CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 -# end of Trace memory - -# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set -CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y -# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set -# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set -CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 - -# -# Memory protection -# -# end of Memory protection - -CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 -CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y -# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set -# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 -CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 -CONFIG_ESP_CONSOLE_UART_DEFAULT=y -# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set -# CONFIG_ESP_CONSOLE_NONE is not set -CONFIG_ESP_CONSOLE_UART=y -CONFIG_ESP_CONSOLE_UART_NUM=0 -CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0 -CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 -CONFIG_ESP_INT_WDT=y -CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 -CONFIG_ESP_INT_WDT_CHECK_CPU1=y -CONFIG_ESP_TASK_WDT_EN=y -CONFIG_ESP_TASK_WDT_INIT=y -# CONFIG_ESP_TASK_WDT_PANIC is not set -CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 -CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y -CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# CONFIG_ESP_PANIC_HANDLER_IRAM is not set -# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set -CONFIG_ESP_DEBUG_OCDAWARE=y -CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y - -# -# Brownout Detector -# -CONFIG_ESP_BROWNOUT_DET=y -CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7 is not set -CONFIG_ESP_BROWNOUT_DET_LVL=0 -# end of Brownout Detector - -# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set -CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y -# end of ESP System Settings - -# -# IPC (Inter-Processor Call) -# -CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 -CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y -CONFIG_ESP_IPC_ISR_ENABLE=y -# end of IPC (Inter-Processor Call) - -# -# ESP Timer (High Resolution Timer) -# -# CONFIG_ESP_TIMER_PROFILING is not set -CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y -CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y -CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 -CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 -# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set -CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 -CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y -CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y -# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set -CONFIG_ESP_TIMER_IMPL_TG0_LAC=y -# end of ESP Timer (High Resolution Timer) - -# -# Wi-Fi -# -CONFIG_ESP_WIFI_ENABLED=y -CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 -CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 -# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set -CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y -CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 -CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32 -CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y -# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set -CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 -CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 -# CONFIG_ESP_WIFI_CSI_ENABLED is not set -CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y -CONFIG_ESP_WIFI_TX_BA_WIN=6 -CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y -CONFIG_ESP_WIFI_RX_BA_WIN=6 -CONFIG_ESP_WIFI_NVS_ENABLED=y -CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y -# CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set -CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 -CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 -# CONFIG_ESP_WIFI_IRAM_OPT is not set -# CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set -# CONFIG_ESP_WIFI_RX_IRAM_OPT is not set -CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y -CONFIG_ESP_WIFI_ENABLE_SAE_PK=y -CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y -CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y -# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set -CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 -CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 -CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 -CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y -CONFIG_ESP_WIFI_GMAC_SUPPORT=y -CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y -# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set -CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 -# CONFIG_ESP_WIFI_NAN_ENABLE is not set -CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y -CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y -# CONFIG_ESP_WIFI_WAPI_PSK is not set -# CONFIG_ESP_WIFI_11KV_SUPPORT is not set -# CONFIG_ESP_WIFI_MBO_SUPPORT is not set -# CONFIG_ESP_WIFI_DPP_SUPPORT is not set -# CONFIG_ESP_WIFI_11R_SUPPORT is not set -# CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set - -# -# WPS Configuration Options -# -# CONFIG_ESP_WIFI_WPS_STRICT is not set -# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set -# end of WPS Configuration Options - -# CONFIG_ESP_WIFI_DEBUG_PRINT is not set -# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set -CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y -# CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set -# end of Wi-Fi - -# -# Core dump -# -# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set -# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set -CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y -# end of Core dump - -# -# FAT Filesystem support -# -CONFIG_FATFS_VOLUME_COUNT=2 -CONFIG_FATFS_LFN_NONE=y -# CONFIG_FATFS_LFN_HEAP is not set -# CONFIG_FATFS_LFN_STACK is not set -# CONFIG_FATFS_SECTOR_512 is not set -CONFIG_FATFS_SECTOR_4096=y -# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set -CONFIG_FATFS_CODEPAGE_437=y -# CONFIG_FATFS_CODEPAGE_720 is not set -# CONFIG_FATFS_CODEPAGE_737 is not set -# CONFIG_FATFS_CODEPAGE_771 is not set -# CONFIG_FATFS_CODEPAGE_775 is not set -# CONFIG_FATFS_CODEPAGE_850 is not set -# CONFIG_FATFS_CODEPAGE_852 is not set -# CONFIG_FATFS_CODEPAGE_855 is not set -# CONFIG_FATFS_CODEPAGE_857 is not set -# CONFIG_FATFS_CODEPAGE_860 is not set -# CONFIG_FATFS_CODEPAGE_861 is not set -# CONFIG_FATFS_CODEPAGE_862 is not set -# CONFIG_FATFS_CODEPAGE_863 is not set -# CONFIG_FATFS_CODEPAGE_864 is not set -# CONFIG_FATFS_CODEPAGE_865 is not set -# CONFIG_FATFS_CODEPAGE_866 is not set -# CONFIG_FATFS_CODEPAGE_869 is not set -# CONFIG_FATFS_CODEPAGE_932 is not set -# CONFIG_FATFS_CODEPAGE_936 is not set -# CONFIG_FATFS_CODEPAGE_949 is not set -# CONFIG_FATFS_CODEPAGE_950 is not set -CONFIG_FATFS_CODEPAGE=437 -CONFIG_FATFS_FS_LOCK=0 -CONFIG_FATFS_TIMEOUT_MS=10000 -CONFIG_FATFS_PER_FILE_CACHE=y -# CONFIG_FATFS_USE_FASTSEEK is not set -CONFIG_FATFS_USE_STRFUNC_NONE=y -# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set -# CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set -CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 -# CONFIG_FATFS_IMMEDIATE_FSYNC is not set -# CONFIG_FATFS_USE_LABEL is not set -CONFIG_FATFS_LINK_LOCK=y -# end of FAT Filesystem support - -# -# FreeRTOS -# - -# -# Kernel -# -# CONFIG_FREERTOS_SMP is not set -# CONFIG_FREERTOS_UNICORE is not set -CONFIG_FREERTOS_HZ=1000 -# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set -# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set -CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y -CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 -CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 -# CONFIG_FREERTOS_USE_IDLE_HOOK is not set -# CONFIG_FREERTOS_USE_TICK_HOOK is not set -CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 -# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set -CONFIG_FREERTOS_USE_TIMERS=y -CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" -# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set -# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set -CONFIG_FREERTOS_TIMER_TASK_NO_AFFINITY=y -CONFIG_FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY=0x7FFFFFFF -CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 -CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 -CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 -CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 -CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 -# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set -# CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set -# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set -# CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set -# end of Kernel - -# -# Port -# -# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set -CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y -# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set -# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set -CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y -CONFIG_FREERTOS_ISR_STACKSIZE=1536 -CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y -# CONFIG_FREERTOS_FPU_IN_ISR is not set -CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y -CONFIG_FREERTOS_CORETIMER_0=y -# CONFIG_FREERTOS_CORETIMER_1 is not set -CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y -# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set -# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set -# end of Port - -# -# Extra -# -# end of Extra - -CONFIG_FREERTOS_PORT=y -CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF -CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y -CONFIG_FREERTOS_DEBUG_OCDAWARE=y -CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y -CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y -CONFIG_FREERTOS_NUMBER_OF_CORES=2 -# end of FreeRTOS - -# -# Hardware Abstraction Layer (HAL) and Low Level (LL) -# -CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y -# CONFIG_HAL_ASSERTION_DISABLE is not set -# CONFIG_HAL_ASSERTION_SILENT is not set -# CONFIG_HAL_ASSERTION_ENABLE is not set -CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 -CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y -CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y -# end of Hardware Abstraction Layer (HAL) and Low Level (LL) - -# -# Heap memory debugging -# -CONFIG_HEAP_POISONING_DISABLED=y -# CONFIG_HEAP_POISONING_LIGHT is not set -# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set -CONFIG_HEAP_TRACING_OFF=y -# CONFIG_HEAP_TRACING_STANDALONE is not set -# CONFIG_HEAP_TRACING_TOHOST is not set -# CONFIG_HEAP_USE_HOOKS is not set -# CONFIG_HEAP_TASK_TRACKING is not set -# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set -# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set -# end of Heap memory debugging - -# -# Log -# - -# -# Log Level -# -CONFIG_LOG_DEFAULT_LEVEL_NONE=y -# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set -# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set -# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set -# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set -# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_LOG_DEFAULT_LEVEL=0 -CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y -# CONFIG_LOG_MAXIMUM_LEVEL_ERROR is not set -# CONFIG_LOG_MAXIMUM_LEVEL_WARN is not set -# CONFIG_LOG_MAXIMUM_LEVEL_INFO is not set -# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set -# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set -CONFIG_LOG_MAXIMUM_LEVEL=0 - -# -# Level Settings -# -# CONFIG_LOG_MASTER_LEVEL is not set -CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y -# CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set -# CONFIG_LOG_TAG_LEVEL_IMPL_LINKED_LIST is not set -CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_AND_LINKED_LIST=y -# CONFIG_LOG_TAG_LEVEL_CACHE_ARRAY is not set -CONFIG_LOG_TAG_LEVEL_CACHE_BINARY_MIN_HEAP=y -CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 -# end of Level Settings -# end of Log Level - -# -# Format -# -# CONFIG_LOG_COLORS is not set -CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y -# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set -# end of Format -# end of Log - -# -# LWIP -# -CONFIG_LWIP_ENABLE=y -CONFIG_LWIP_LOCAL_HOSTNAME="espressif" -# CONFIG_LWIP_NETIF_API is not set -CONFIG_LWIP_TCPIP_TASK_PRIO=18 -# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set -# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -# CONFIG_LWIP_L2_TO_L3_COPY is not set -# CONFIG_LWIP_IRAM_OPTIMIZATION is not set -# CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set -CONFIG_LWIP_TIMERS_ONDEMAND=y -CONFIG_LWIP_ND6=y -# CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set -CONFIG_LWIP_MAX_SOCKETS=10 -# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set -# CONFIG_LWIP_SO_LINGER is not set -CONFIG_LWIP_SO_REUSE=y -CONFIG_LWIP_SO_REUSE_RXTOALL=y -CONFIG_LWIP_SO_RCVBUF=y -# CONFIG_LWIP_NETBUF_RECVINFO is not set -CONFIG_LWIP_IP_DEFAULT_TTL=64 -CONFIG_LWIP_IP4_FRAG=y -CONFIG_LWIP_IP6_FRAG=y -# CONFIG_LWIP_IP4_REASSEMBLY is not set -# CONFIG_LWIP_IP6_REASSEMBLY is not set -CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 -# CONFIG_LWIP_IP_FORWARD is not set -# CONFIG_LWIP_STATS is not set -CONFIG_LWIP_ESP_GRATUITOUS_ARP=y -CONFIG_LWIP_GARP_TMR_INTERVAL=60 -CONFIG_LWIP_ESP_MLDV6_REPORT=y -CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 -CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 -CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y -# CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set -# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set -# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set -CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y -# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set -CONFIG_LWIP_DHCP_OPTIONS_LEN=68 -CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 -CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 - -# -# DHCP server -# -CONFIG_LWIP_DHCPS=y -CONFIG_LWIP_DHCPS_LEASE_UNIT=60 -CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 -CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y -CONFIG_LWIP_DHCPS_ADD_DNS=y -# end of DHCP server - -# CONFIG_LWIP_AUTOIP is not set -CONFIG_LWIP_IPV4=y -CONFIG_LWIP_IPV6=y -# CONFIG_LWIP_IPV6_AUTOCONFIG is not set -CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 -# CONFIG_LWIP_IPV6_FORWARD is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5760 -CONFIG_LWIP_TCP_WND_DEFAULT=5760 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 -CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP - -# -# UDP -# -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# end of UDP - -# -# Checksums -# -# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set -# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set -CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y -# end of Checksums - -CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 -CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y -# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set -# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set -CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 -CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 -CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 -CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 -# CONFIG_LWIP_PPP_SUPPORT is not set -# CONFIG_LWIP_SLIP_SUPPORT is not set - -# -# ICMP -# -CONFIG_LWIP_ICMP=y -# CONFIG_LWIP_MULTICAST_PING is not set -# CONFIG_LWIP_BROADCAST_PING is not set -# end of ICMP - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API - -# -# SNTP -# -CONFIG_LWIP_SNTP_MAX_SERVERS=1 -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set -CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 -CONFIG_LWIP_SNTP_STARTUP_DELAY=y -CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 -# end of SNTP - -# -# DNS -# -CONFIG_LWIP_DNS_MAX_HOST_IP=1 -CONFIG_LWIP_DNS_MAX_SERVERS=3 -# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set -# CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set -# end of DNS - -CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 -CONFIG_LWIP_ESP_LWIP_ASSERT=y - -# -# Hooks -# -# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set -CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y -# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set -CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y -# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set -# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set -CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y -# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set -# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set -CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_NONE=y -# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_DEFAULT is not set -# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_CUSTOM is not set -CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y -# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set -# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set -CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_NONE=y -# CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_CUSTOM is not set -# CONFIG_LWIP_HOOK_IP6_INPUT_NONE is not set -CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y -# CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set -# end of Hooks - -# CONFIG_LWIP_DEBUG is not set -# end of LWIP - -# -# mbedTLS -# -CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y -# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set -# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set -CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y -CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 -CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 -# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set -# CONFIG_MBEDTLS_DEBUG is not set - -# -# mbedTLS v3.x related -# -# CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set -# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set -# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set -# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set -CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y -CONFIG_MBEDTLS_PKCS7_C=y -# end of mbedTLS v3.x related - -# -# Certificate Bundle -# -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set -# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 -# end of Certificate Bundle - -# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set -CONFIG_MBEDTLS_CMAC_C=y -CONFIG_MBEDTLS_HARDWARE_AES=y -CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y -CONFIG_MBEDTLS_HARDWARE_MPI=y -# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set -CONFIG_MBEDTLS_HARDWARE_SHA=y -CONFIG_MBEDTLS_ROM_MD5=y -# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set -# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set -CONFIG_MBEDTLS_HAVE_TIME=y -# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set -# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set -CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y -CONFIG_MBEDTLS_SHA512_C=y -# CONFIG_MBEDTLS_SHA3_C is not set -CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y -# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set -# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set -# CONFIG_MBEDTLS_TLS_DISABLED is not set -CONFIG_MBEDTLS_TLS_SERVER=y -CONFIG_MBEDTLS_TLS_CLIENT=y -CONFIG_MBEDTLS_TLS_ENABLED=y - -# -# TLS Key Exchange Methods -# -CONFIG_MBEDTLS_PSK_MODES=y -CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_PSK=y -CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_PSK=y -CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y -# end of TLS Key Exchange Methods - -CONFIG_MBEDTLS_SSL_RENEGOTIATION=y -CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y -# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set -# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set -CONFIG_MBEDTLS_SSL_ALPN=y -CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y -CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y - -# -# Symmetric Ciphers -# -CONFIG_MBEDTLS_AES_C=y -# CONFIG_MBEDTLS_CAMELLIA_C is not set -# CONFIG_MBEDTLS_DES_C is not set -# CONFIG_MBEDTLS_BLOWFISH_C is not set -# CONFIG_MBEDTLS_XTEA_C is not set -CONFIG_MBEDTLS_CCM_C=y -CONFIG_MBEDTLS_GCM_C=y -# CONFIG_MBEDTLS_NIST_KW_C is not set -# end of Symmetric Ciphers - -# CONFIG_MBEDTLS_RIPEMD160_C is not set - -# -# Certificates -# -CONFIG_MBEDTLS_PEM_PARSE_C=y -CONFIG_MBEDTLS_PEM_WRITE_C=y -CONFIG_MBEDTLS_X509_CRL_PARSE_C=y -CONFIG_MBEDTLS_X509_CSR_PARSE_C=y -# end of Certificates - -CONFIG_MBEDTLS_ECP_C=y -CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y -CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y -# CONFIG_MBEDTLS_DHM_C is not set -CONFIG_MBEDTLS_ECDH_C=y -CONFIG_MBEDTLS_ECDSA_C=y -# CONFIG_MBEDTLS_ECJPAKE_C is not set -CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y -CONFIG_MBEDTLS_ECP_NIST_OPTIM=y -# CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set -# CONFIG_MBEDTLS_POLY1305_C is not set -# CONFIG_MBEDTLS_CHACHA20_C is not set -# CONFIG_MBEDTLS_HKDF_C is not set -# CONFIG_MBEDTLS_THREADING_C is not set -CONFIG_MBEDTLS_ERROR_STRINGS=y -CONFIG_MBEDTLS_FS_IO=y -# end of mbedTLS - -# -# ESP-MQTT Configurations -# -# CONFIG_MQTT_PROTOCOL_311 is not set -# CONFIG_MQTT_PROTOCOL_5 is not set -# CONFIG_MQTT_TRANSPORT_SSL is not set -# CONFIG_MQTT_TRANSPORT_WEBSOCKET is not set -# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set -# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set -# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set -# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set -# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set -# CONFIG_MQTT_CUSTOM_OUTBOX is not set -# end of ESP-MQTT Configurations - -# -# Newlib -# -CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set -CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y -# CONFIG_NEWLIB_NANO_FORMAT is not set -CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y -# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set -# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set -# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set -# end of Newlib - -# -# NVS -# -# CONFIG_NVS_ASSERT_ERROR_CHECK is not set -# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set -# end of NVS - -# -# OpenThread -# -# CONFIG_OPENTHREAD_ENABLED is not set - -# -# OpenThread Spinel -# -# CONFIG_OPENTHREAD_SPINEL_ONLY is not set -# end of OpenThread Spinel -# end of OpenThread - -# -# Protocomm -# -CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y -CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y -CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y -CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_PATCH_VERSION=y -# end of Protocomm - -# -# PThreads -# -CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 -CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 -CONFIG_PTHREAD_STACK_MIN=768 -CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y -# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set -# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set -CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 -CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" -# end of PThreads - -# -# MMU Config -# -CONFIG_MMU_PAGE_SIZE_64KB=y -CONFIG_MMU_PAGE_MODE="64KB" -CONFIG_MMU_PAGE_SIZE=0x10000 -# end of MMU Config - -# -# Main Flash configuration -# - -# -# SPI Flash behavior when brownout -# -CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y -CONFIG_SPI_FLASH_BROWNOUT_RESET=y -# end of SPI Flash behavior when brownout - -# -# Optional and Experimental Features (READ DOCS FIRST) -# - -# -# Features here require specific hardware (READ DOCS FIRST!) -# -CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 -# CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set -# end of Optional and Experimental Features (READ DOCS FIRST) -# end of Main Flash configuration - -# -# SPI Flash driver -# -# CONFIG_SPI_FLASH_VERIFY_WRITE is not set -# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set -CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y -CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y -# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set -# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set -# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set -# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set -CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y -CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 -CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 -CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 -# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set -# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set -# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set - -# -# Auto-detect flash chips -# -CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y -CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y -CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y -CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y -CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y -CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y -# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set -# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set -# end of Auto-detect flash chips - -CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y -# end of SPI Flash driver - -# -# SPIFFS Configuration -# -CONFIG_SPIFFS_MAX_PARTITIONS=3 - -# -# SPIFFS Cache Configuration -# -CONFIG_SPIFFS_CACHE=y -CONFIG_SPIFFS_CACHE_WR=y -# CONFIG_SPIFFS_CACHE_STATS is not set -# end of SPIFFS Cache Configuration - -CONFIG_SPIFFS_PAGE_CHECK=y -CONFIG_SPIFFS_GC_MAX_RUNS=10 -# CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 -# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set -CONFIG_SPIFFS_USE_MAGIC=y -CONFIG_SPIFFS_USE_MAGIC_LENGTH=y -CONFIG_SPIFFS_META_LENGTH=4 -CONFIG_SPIFFS_USE_MTIME=y - -# -# Debug Configuration -# -# CONFIG_SPIFFS_DBG is not set -# CONFIG_SPIFFS_API_DBG is not set -# CONFIG_SPIFFS_GC_DBG is not set -# CONFIG_SPIFFS_CACHE_DBG is not set -# CONFIG_SPIFFS_CHECK_DBG is not set -# CONFIG_SPIFFS_TEST_VISUALISATION is not set -# end of Debug Configuration -# end of SPIFFS Configuration - -# -# TCP Transport -# - -# -# Websocket -# -CONFIG_WS_TRANSPORT=y -CONFIG_WS_BUFFER_SIZE=1024 -# CONFIG_WS_DYNAMIC_BUFFER is not set -# end of Websocket -# end of TCP Transport - -# -# Ultra Low Power (ULP) Co-processor -# -# CONFIG_ULP_COPROC_ENABLED is not set - -# -# ULP Debugging Options -# -# end of ULP Debugging Options -# end of Ultra Low Power (ULP) Co-processor - -# -# Unity unit testing library -# -CONFIG_UNITY_ENABLE_FLOAT=y -CONFIG_UNITY_ENABLE_DOUBLE=y -# CONFIG_UNITY_ENABLE_64BIT is not set -# CONFIG_UNITY_ENABLE_COLOR is not set -CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y -# CONFIG_UNITY_ENABLE_FIXTURE is not set -# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set -# end of Unity unit testing library - -# -# Virtual file system -# -CONFIG_VFS_SUPPORT_IO=y -CONFIG_VFS_SUPPORT_DIR=y -CONFIG_VFS_SUPPORT_SELECT=y -CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y -# CONFIG_VFS_SELECT_IN_RAM is not set -CONFIG_VFS_SUPPORT_TERMIOS=y -CONFIG_VFS_MAX_COUNT=8 - -# -# Host File System I/O (Semihosting) -# -CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -# end of Host File System I/O (Semihosting) - -CONFIG_VFS_INITIALIZE_DEV_NULL=y -# end of Virtual file system - -# -# Wear Levelling -# -# CONFIG_WL_SECTOR_SIZE_512 is not set -CONFIG_WL_SECTOR_SIZE_4096=y -CONFIG_WL_SECTOR_SIZE=4096 -# end of Wear Levelling - -# -# Wi-Fi Provisioning Manager -# -CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 -CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 -# CONFIG_WIFI_PROV_BLE_BONDING is not set -CONFIG_WIFI_PROV_BLE_SEC_CONN=y -# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set -# CONFIG_WIFI_PROV_BLE_NOTIFY is not set -# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set -CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y -# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set -# end of Wi-Fi Provisioning Manager - -# -# Zigbee -# -# CONFIG_ZB_ENABLED is not set -# end of Zigbee - -# -# mDNS -# -CONFIG_MDNS_MAX_INTERFACES=3 -CONFIG_MDNS_MAX_SERVICES=10 -CONFIG_MDNS_TASK_PRIORITY=1 -CONFIG_MDNS_ACTION_QUEUE_LEN=16 -CONFIG_MDNS_TASK_STACK_SIZE=4096 -# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_MDNS_TASK_AFFINITY_CPU0=y -# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set -CONFIG_MDNS_TASK_AFFINITY=0x0 - -# -# MDNS Memory Configuration -# -CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y -CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y -# CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set -# end of MDNS Memory Configuration - -CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 -CONFIG_MDNS_TIMER_PERIOD_MS=100 -# CONFIG_MDNS_NETWORKING_SOCKET is not set -# CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set -# CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set -CONFIG_MDNS_ENABLE_CONSOLE_CLI=y -# CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set -CONFIG_MDNS_MULTIPLE_INSTANCE=y - -# -# MDNS Predefined interfaces -# -CONFIG_MDNS_PREDEF_NETIF_STA=y -CONFIG_MDNS_PREDEF_NETIF_AP=y -# end of MDNS Predefined interfaces -# end of mDNS - -# -# Network Provisioning Manager -# -CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y -CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 -CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 -# CONFIG_NETWORK_PROV_BLE_BONDING is not set -CONFIG_NETWORK_PROV_BLE_SEC_CONN=y -# CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set -# CONFIG_NETWORK_PROV_KEEP_BLE_ON_AFTER_PROV is not set -CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y -# CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set -# end of Network Provisioning Manager - -# -# LittleFS -# -# CONFIG_LITTLEFS_SDMMC_SUPPORT is not set -CONFIG_LITTLEFS_MAX_PARTITIONS=3 -CONFIG_LITTLEFS_PAGE_SIZE=256 -CONFIG_LITTLEFS_OBJ_NAME_LEN=64 -CONFIG_LITTLEFS_READ_SIZE=128 -CONFIG_LITTLEFS_WRITE_SIZE=128 -CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 -CONFIG_LITTLEFS_CACHE_SIZE=512 -CONFIG_LITTLEFS_BLOCK_CYCLES=512 -CONFIG_LITTLEFS_USE_MTIME=y -# CONFIG_LITTLEFS_USE_ONLY_HASH is not set -# CONFIG_LITTLEFS_HUMAN_READABLE is not set -CONFIG_LITTLEFS_MTIME_USE_SECONDS=y -# CONFIG_LITTLEFS_MTIME_USE_NONCE is not set -# CONFIG_LITTLEFS_SPIFFS_COMPAT is not set -# CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set -# CONFIG_LITTLEFS_FCNTL_GET_PATH is not set -# CONFIG_LITTLEFS_MULTIVERSION is not set -# CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set -CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y -# CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set -CONFIG_LITTLEFS_ASSERTS=y -# CONFIG_LITTLEFS_MMAP_PARTITION is not set -# end of LittleFS -# end of Component config - -# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set - -# Deprecated options for backward compatibility -# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set -# CONFIG_NO_BLOBS is not set -# CONFIG_ESP32_NO_BLOBS is not set -# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set -# CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set -CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y -# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set -CONFIG_LOG_BOOTLOADER_LEVEL=3 -# CONFIG_APP_ROLLBACK_ENABLE is not set -# CONFIG_FLASH_ENCRYPTION_ENABLED is not set -# CONFIG_FLASHMODE_QIO is not set -# CONFIG_FLASHMODE_QOUT is not set -CONFIG_FLASHMODE_DIO=y -# CONFIG_FLASHMODE_DOUT is not set -CONFIG_MONITOR_BAUD=115200 -# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set -# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set -# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set -CONFIG_OPTIMIZATION_LEVEL_RELEASE=y -CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y -CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y -# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set -# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set -CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 -# CONFIG_CXX_EXCEPTIONS is not set -CONFIG_STACK_CHECK_NONE=y -# CONFIG_STACK_CHECK_NORM is not set -# CONFIG_STACK_CHECK_STRONG is not set -# CONFIG_STACK_CHECK_ALL is not set -# CONFIG_WARN_WRITE_STRINGS is not set -# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set -CONFIG_ESP32_APPTRACE_DEST_NONE=y -CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y -# CONFIG_BLUEDROID_ENABLED is not set -CONFIG_NIMBLE_ENABLED=y -CONFIG_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y -# CONFIG_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set -CONFIG_NIMBLE_MAX_CONNECTIONS=7 -CONFIG_NIMBLE_MAX_BONDS=1 -CONFIG_NIMBLE_MAX_CCCDS=1 -CONFIG_NIMBLE_L2CAP_COC_MAX_NUM=0 -CONFIG_NIMBLE_PINNED_TO_CORE_0=y -# CONFIG_NIMBLE_PINNED_TO_CORE_1 is not set -CONFIG_NIMBLE_PINNED_TO_CORE=0 -CONFIG_NIMBLE_TASK_STACK_SIZE=4096 -CONFIG_BT_NIMBLE_TASK_STACK_SIZE=4096 -CONFIG_NIMBLE_ROLE_CENTRAL=y -CONFIG_NIMBLE_ROLE_PERIPHERAL=y -CONFIG_NIMBLE_ROLE_BROADCASTER=y -CONFIG_NIMBLE_ROLE_OBSERVER=y -# CONFIG_NIMBLE_NVS_PERSIST is not set -# CONFIG_NIMBLE_DEBUG is not set -CONFIG_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" -CONFIG_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 -CONFIG_NIMBLE_ATT_PREFERRED_MTU=256 -CONFIG_NIMBLE_SVC_GAP_APPEARANCE=0 -CONFIG_BT_NIMBLE_MSYS1_BLOCK_COUNT=12 -CONFIG_BT_NIMBLE_ACL_BUF_COUNT=24 -CONFIG_BT_NIMBLE_ACL_BUF_SIZE=255 -CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70 -CONFIG_BT_NIMBLE_HCI_EVT_HI_BUF_COUNT=30 -CONFIG_BT_NIMBLE_HCI_EVT_LO_BUF_COUNT=8 -CONFIG_NIMBLE_HS_FLOW_CTRL=y -CONFIG_NIMBLE_HS_FLOW_CTRL_ITVL=1000 -CONFIG_NIMBLE_HS_FLOW_CTRL_THRESH=2 -CONFIG_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y -CONFIG_NIMBLE_RPA_TIMEOUT=900 -# CONFIG_NIMBLE_MESH is not set -CONFIG_NIMBLE_CRYPTO_STACK_MBEDTLS=y -CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y -# CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY is not set -# CONFIG_BTDM_CONTROLLER_MODE_BTDM is not set -CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=3 -CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=3 -CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0 -CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 -CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 -CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI=y -# CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4 is not set -CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=y -CONFIG_BLE_SCAN_DUPLICATE=y -CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y -# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA is not set -# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR is not set -CONFIG_SCAN_DUPLICATE_TYPE=0 -CONFIG_DUPLICATE_SCAN_CACHE_SIZE=100 -# CONFIG_BLE_MESH_SCAN_DUPLICATE_EN is not set -CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y -CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED=y -CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM=100 -CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 -CONFIG_ADC2_DISABLE_DAC=y -CONFIG_SW_COEXIST_ENABLE=y -CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y -CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y -# CONFIG_MCPWM_ISR_IN_IRAM is not set -# CONFIG_EVENT_LOOP_PROFILING is not set -CONFIG_POST_EVENTS_FROM_ISR=y -CONFIG_POST_EVENTS_FROM_IRAM_ISR=y -CONFIG_GDBSTUB_SUPPORT_TASKS=y -CONFIG_GDBSTUB_MAX_TASKS=32 -# CONFIG_OTA_ALLOW_HTTP is not set -# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set -CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y -CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 -# CONFIG_ESP_SYSTEM_PD_FLASH is not set -CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 -CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 -CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y -CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y -# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set -# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set -# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set -# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set -# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set -# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set -CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 -# CONFIG_ESP32_XTAL_FREQ_26 is not set -CONFIG_ESP32_XTAL_FREQ_40=y -# CONFIG_ESP32_XTAL_FREQ_AUTO is not set -CONFIG_ESP32_XTAL_FREQ=40 -CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y -# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set -CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 -CONFIG_ESP32_PHY_MAX_TX_POWER=20 -# CONFIG_REDUCE_PHY_TX_POWER is not set -# CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set -# CONFIG_SPIRAM_SUPPORT is not set -# CONFIG_ESP32_SPIRAM_SUPPORT is not set -# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set -CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y -# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set -CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160 -CONFIG_TRACEMEM_RESERVE_DRAM=0x0 -# CONFIG_ESP32_PANIC_PRINT_HALT is not set -CONFIG_ESP32_PANIC_PRINT_REBOOT=y -# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set -# CONFIG_ESP32_PANIC_GDBSTUB is not set -CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_MAIN_TASK_STACK_SIZE=3584 -CONFIG_CONSOLE_UART_DEFAULT=y -# CONFIG_CONSOLE_UART_CUSTOM is not set -# CONFIG_CONSOLE_UART_NONE is not set -# CONFIG_ESP_CONSOLE_UART_NONE is not set -CONFIG_CONSOLE_UART=y -CONFIG_CONSOLE_UART_NUM=0 -CONFIG_CONSOLE_UART_BAUDRATE=115200 -CONFIG_INT_WDT=y -CONFIG_INT_WDT_TIMEOUT_MS=300 -CONFIG_INT_WDT_CHECK_CPU1=y -CONFIG_TASK_WDT=y -CONFIG_ESP_TASK_WDT=y -# CONFIG_TASK_WDT_PANIC is not set -CONFIG_TASK_WDT_TIMEOUT_S=5 -CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y -CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set -CONFIG_ESP32_DEBUG_OCDAWARE=y -CONFIG_BROWNOUT_DET=y -CONFIG_ESP32_BROWNOUT_DET=y -CONFIG_BROWNOUT_DET_LVL_SEL_0=y -CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y -# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set -CONFIG_BROWNOUT_DET_LVL=0 -CONFIG_ESP32_BROWNOUT_DET_LVL=0 -# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set -CONFIG_IPC_TASK_STACK_SIZE=1024 -CONFIG_TIMER_TASK_STACK_SIZE=3584 -CONFIG_ESP32_WIFI_ENABLED=y -CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 -CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 -# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set -CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 -CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 -# CONFIG_ESP32_WIFI_CSI_ENABLED is not set -CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y -CONFIG_ESP32_WIFI_TX_BA_WIN=6 -CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y -CONFIG_ESP32_WIFI_RX_BA_WIN=6 -CONFIG_ESP32_WIFI_NVS_ENABLED=y -CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y -# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set -CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 -CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 -# CONFIG_ESP32_WIFI_IRAM_OPT is not set -# CONFIG_ESP32_WIFI_RX_IRAM_OPT is not set -CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y -CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y -CONFIG_WPA_MBEDTLS_CRYPTO=y -CONFIG_WPA_MBEDTLS_TLS_CLIENT=y -# CONFIG_WPA_WAPI_PSK is not set -# CONFIG_WPA_11KV_SUPPORT is not set -# CONFIG_WPA_MBO_SUPPORT is not set -# CONFIG_WPA_DPP_SUPPORT is not set -# CONFIG_WPA_11R_SUPPORT is not set -# CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set -# CONFIG_WPA_WPS_STRICT is not set -# CONFIG_WPA_DEBUG_PRINT is not set -# CONFIG_WPA_TESTING_OPTIONS is not set -# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set -# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set -CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y -CONFIG_TIMER_TASK_PRIORITY=1 -CONFIG_TIMER_TASK_STACK_DEPTH=2048 -CONFIG_TIMER_QUEUE_LENGTH=10 -# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set -# CONFIG_HAL_ASSERTION_SILIENT is not set -# CONFIG_L2_TO_L3_COPY is not set -CONFIG_ESP_GRATUITOUS_ARP=y -CONFIG_GARP_TMR_INTERVAL=60 -CONFIG_TCPIP_RECVMBOX_SIZE=32 -CONFIG_TCP_MAXRTX=12 -CONFIG_TCP_SYNMAXRTX=12 -CONFIG_TCP_MSS=1440 -CONFIG_TCP_MSL=60000 -CONFIG_TCP_SND_BUF_DEFAULT=5760 -CONFIG_TCP_WND_DEFAULT=5760 -CONFIG_TCP_RECVMBOX_SIZE=6 -CONFIG_TCP_QUEUE_OOSEQ=y -CONFIG_TCP_OVERSIZE_MSS=y -# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_TCP_OVERSIZE_DISABLE is not set -CONFIG_UDP_RECVMBOX_SIZE=6 -CONFIG_TCPIP_TASK_STACK_SIZE=3072 -CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y -# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set -# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set -CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF -# CONFIG_PPP_SUPPORT is not set -CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y -CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y -# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set -# CONFIG_ESP32_TIME_SYSCALL_USE_HRT is not set -# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set -# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set -CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 -CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 -CONFIG_ESP32_PTHREAD_STACK_MIN=768 -CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y -# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set -# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set -CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 -CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" -CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y -# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set -# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set -# CONFIG_ESP32_ULP_COPROC_ENABLED is not set -CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y -CONFIG_SUPPORT_TERMIOS=y -CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -# End of deprecated options diff --git a/sdkconfig.release.old b/sdkconfig.release.old deleted file mode 100644 index 8017e96b..00000000 --- a/sdkconfig.release.old +++ /dev/null @@ -1,2197 +0,0 @@ -# -# Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) 5.3.2 Project Configuration -# -CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined" -CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined" -CONFIG_SOC_DPORT_WORKAROUND="Not determined" -CONFIG_SOC_CAPS_ECO_VER_MAX=301 -CONFIG_SOC_ADC_SUPPORTED=y -CONFIG_SOC_DAC_SUPPORTED=y -CONFIG_SOC_UART_SUPPORTED=y -CONFIG_SOC_MCPWM_SUPPORTED=y -CONFIG_SOC_GPTIMER_SUPPORTED=y -CONFIG_SOC_SDMMC_HOST_SUPPORTED=y -CONFIG_SOC_BT_SUPPORTED=y -CONFIG_SOC_PCNT_SUPPORTED=y -CONFIG_SOC_PHY_SUPPORTED=y -CONFIG_SOC_WIFI_SUPPORTED=y -CONFIG_SOC_SDIO_SLAVE_SUPPORTED=y -CONFIG_SOC_TWAI_SUPPORTED=y -CONFIG_SOC_EFUSE_SUPPORTED=y -CONFIG_SOC_EMAC_SUPPORTED=y -CONFIG_SOC_ULP_SUPPORTED=y -CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y -CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y -CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y -CONFIG_SOC_RTC_MEM_SUPPORTED=y -CONFIG_SOC_I2S_SUPPORTED=y -CONFIG_SOC_RMT_SUPPORTED=y -CONFIG_SOC_SDM_SUPPORTED=y -CONFIG_SOC_GPSPI_SUPPORTED=y -CONFIG_SOC_LEDC_SUPPORTED=y -CONFIG_SOC_I2C_SUPPORTED=y -CONFIG_SOC_SUPPORT_COEXISTENCE=y -CONFIG_SOC_AES_SUPPORTED=y -CONFIG_SOC_MPI_SUPPORTED=y -CONFIG_SOC_SHA_SUPPORTED=y -CONFIG_SOC_FLASH_ENC_SUPPORTED=y -CONFIG_SOC_SECURE_BOOT_SUPPORTED=y -CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y -CONFIG_SOC_BOD_SUPPORTED=y -CONFIG_SOC_ULP_FSM_SUPPORTED=y -CONFIG_SOC_CLK_TREE_SUPPORTED=y -CONFIG_SOC_MPU_SUPPORTED=y -CONFIG_SOC_WDT_SUPPORTED=y -CONFIG_SOC_SPI_FLASH_SUPPORTED=y -CONFIG_SOC_RNG_SUPPORTED=y -CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y -CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y -CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y -CONFIG_SOC_PM_SUPPORTED=y -CONFIG_SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL=5 -CONFIG_SOC_XTAL_SUPPORT_26M=y -CONFIG_SOC_XTAL_SUPPORT_40M=y -CONFIG_SOC_XTAL_SUPPORT_AUTO_DETECT=y -CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y -CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y -CONFIG_SOC_ADC_DMA_SUPPORTED=y -CONFIG_SOC_ADC_PERIPH_NUM=2 -CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 -CONFIG_SOC_ADC_ATTEN_NUM=4 -CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 -CONFIG_SOC_ADC_PATT_LEN_MAX=16 -CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=9 -CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 -CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 -CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=4 -CONFIG_SOC_ADC_DIGI_MONITOR_NUM=0 -CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=2 -CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=20 -CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=9 -CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=12 -CONFIG_SOC_ADC_SHARED_POWER=y -CONFIG_SOC_SHARED_IDCACHE_SUPPORTED=y -CONFIG_SOC_IDCACHE_PER_CORE=y -CONFIG_SOC_CPU_CORES_NUM=2 -CONFIG_SOC_CPU_INTR_NUM=32 -CONFIG_SOC_CPU_HAS_FPU=y -CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y -CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 -CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 -CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 -CONFIG_SOC_DAC_CHAN_NUM=2 -CONFIG_SOC_DAC_RESOLUTION=8 -CONFIG_SOC_DAC_DMA_16BIT_ALIGN=y -CONFIG_SOC_GPIO_PORT=1 -CONFIG_SOC_GPIO_PIN_COUNT=40 -CONFIG_SOC_GPIO_VALID_GPIO_MASK=0xFFFFFFFFFF -CONFIG_SOC_GPIO_IN_RANGE_MAX=39 -CONFIG_SOC_GPIO_OUT_RANGE_MAX=33 -CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0xEF0FEA -CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y -CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3 -CONFIG_SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP=y -CONFIG_SOC_I2C_NUM=2 -CONFIG_SOC_HP_I2C_NUM=2 -CONFIG_SOC_I2C_FIFO_LEN=32 -CONFIG_SOC_I2C_CMD_REG_NUM=16 -CONFIG_SOC_I2C_SUPPORT_SLAVE=y -CONFIG_SOC_I2C_SUPPORT_APB=y -CONFIG_SOC_I2C_STOP_INDEPENDENT=y -CONFIG_SOC_I2S_NUM=2 -CONFIG_SOC_I2S_HW_VERSION_1=y -CONFIG_SOC_I2S_SUPPORTS_APLL=y -CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y -CONFIG_SOC_I2S_SUPPORTS_PDM=y -CONFIG_SOC_I2S_SUPPORTS_PDM_TX=y -CONFIG_SOC_I2S_PDM_MAX_TX_LINES=1 -CONFIG_SOC_I2S_SUPPORTS_PDM_RX=y -CONFIG_SOC_I2S_PDM_MAX_RX_LINES=1 -CONFIG_SOC_I2S_SUPPORTS_ADC_DAC=y -CONFIG_SOC_I2S_SUPPORTS_ADC=y -CONFIG_SOC_I2S_SUPPORTS_DAC=y -CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y -CONFIG_SOC_I2S_MAX_DATA_WIDTH=24 -CONFIG_SOC_I2S_TRANS_SIZE_ALIGN_WORD=y -CONFIG_SOC_I2S_LCD_I80_VARIANT=y -CONFIG_SOC_LCD_I80_SUPPORTED=y -CONFIG_SOC_LCD_I80_BUSES=2 -CONFIG_SOC_LCD_I80_BUS_WIDTH=24 -CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y -CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y -CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y -CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y -CONFIG_SOC_LEDC_CHANNEL_NUM=8 -CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=20 -CONFIG_SOC_MCPWM_GROUPS=2 -CONFIG_SOC_MCPWM_TIMERS_PER_GROUP=3 -CONFIG_SOC_MCPWM_OPERATORS_PER_GROUP=3 -CONFIG_SOC_MCPWM_COMPARATORS_PER_OPERATOR=2 -CONFIG_SOC_MCPWM_GENERATORS_PER_OPERATOR=2 -CONFIG_SOC_MCPWM_TRIGGERS_PER_OPERATOR=2 -CONFIG_SOC_MCPWM_GPIO_FAULTS_PER_GROUP=3 -CONFIG_SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP=y -CONFIG_SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER=3 -CONFIG_SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP=3 -CONFIG_SOC_MMU_PERIPH_NUM=2 -CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=3 -CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 -CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 -CONFIG_SOC_PCNT_GROUPS=1 -CONFIG_SOC_PCNT_UNITS_PER_GROUP=8 -CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 -CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 -CONFIG_SOC_RMT_GROUPS=1 -CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=8 -CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=8 -CONFIG_SOC_RMT_CHANNELS_PER_GROUP=8 -CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 -CONFIG_SOC_RMT_SUPPORT_REF_TICK=y -CONFIG_SOC_RMT_SUPPORT_APB=y -CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y -CONFIG_SOC_RTCIO_PIN_COUNT=18 -CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y -CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y -CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y -CONFIG_SOC_SDM_GROUPS=1 -CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 -CONFIG_SOC_SDM_CLK_SUPPORT_APB=y -CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y -CONFIG_SOC_SPI_AS_CS_SUPPORTED=y -CONFIG_SOC_SPI_PERIPH_NUM=3 -CONFIG_SOC_SPI_DMA_CHAN_NUM=2 -CONFIG_SOC_SPI_MAX_CS_NUM=3 -CONFIG_SOC_SPI_SUPPORT_CLK_APB=y -CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=64 -CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 -CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y -CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y -CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y -CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y -CONFIG_SOC_TIMER_GROUPS=2 -CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 -CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 -CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 -CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y -CONFIG_SOC_TOUCH_SENSOR_VERSION=1 -CONFIG_SOC_TOUCH_SENSOR_NUM=10 -CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1 -CONFIG_SOC_TWAI_CONTROLLER_NUM=1 -CONFIG_SOC_TWAI_BRP_MIN=2 -CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y -CONFIG_SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT=y -CONFIG_SOC_UART_NUM=3 -CONFIG_SOC_UART_HP_NUM=3 -CONFIG_SOC_UART_SUPPORT_APB_CLK=y -CONFIG_SOC_UART_SUPPORT_REF_TICK=y -CONFIG_SOC_UART_FIFO_LEN=128 -CONFIG_SOC_UART_BITRATE_MAX=5000000 -CONFIG_SOC_SPIRAM_SUPPORTED=y -CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y -CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG=y -CONFIG_SOC_SHA_ENDIANNESS_BE=y -CONFIG_SOC_SHA_SUPPORT_SHA1=y -CONFIG_SOC_SHA_SUPPORT_SHA256=y -CONFIG_SOC_SHA_SUPPORT_SHA384=y -CONFIG_SOC_SHA_SUPPORT_SHA512=y -CONFIG_SOC_MPI_MEM_BLOCKS_NUM=4 -CONFIG_SOC_MPI_OPERATIONS_NUM=y -CONFIG_SOC_RSA_MAX_BIT_LEN=4096 -CONFIG_SOC_AES_SUPPORT_AES_128=y -CONFIG_SOC_AES_SUPPORT_AES_192=y -CONFIG_SOC_AES_SUPPORT_AES_256=y -CONFIG_SOC_SECURE_BOOT_V1=y -CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=y -CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=32 -CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 -CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y -CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y -CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y -CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y -CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y -CONFIG_SOC_PM_SUPPORT_MODEM_PD=y -CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y -CONFIG_SOC_CLK_APLL_SUPPORTED=y -CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y -CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y -CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y -CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y -CONFIG_SOC_SDMMC_USE_IOMUX=y -CONFIG_SOC_SDMMC_NUM_SLOTS=2 -CONFIG_SOC_WIFI_WAPI_SUPPORT=y -CONFIG_SOC_WIFI_CSI_SUPPORT=y -CONFIG_SOC_WIFI_MESH_SUPPORT=y -CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y -CONFIG_SOC_WIFI_NAN_SUPPORT=y -CONFIG_SOC_BLE_SUPPORTED=y -CONFIG_SOC_BLE_MESH_SUPPORTED=y -CONFIG_SOC_BT_CLASSIC_SUPPORTED=y -CONFIG_SOC_BLUFI_SUPPORTED=y -CONFIG_SOC_BT_H2C_ENC_KEY_CTRL_ENH_VSC_SUPPORTED=y -CONFIG_SOC_ULP_HAS_ADC=y -CONFIG_SOC_PHY_COMBO_MODULE=y -CONFIG_SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK=y -CONFIG_IDF_CMAKE=y -CONFIG_IDF_TOOLCHAIN="gcc" -CONFIG_IDF_TARGET_ARCH_XTENSA=y -CONFIG_IDF_TARGET_ARCH="xtensa" -CONFIG_IDF_TARGET="esp32" -CONFIG_IDF_INIT_VERSION="5.4.1" -CONFIG_IDF_TARGET_ESP32=y -CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 - -# -# Build type -# -CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y -# CONFIG_APP_BUILD_TYPE_RAM is not set -CONFIG_APP_BUILD_GENERATE_BINARIES=y -CONFIG_APP_BUILD_BOOTLOADER=y -CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y -# CONFIG_APP_REPRODUCIBLE_BUILD is not set -# CONFIG_APP_NO_BLOBS is not set -# CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set -# CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set -# end of Build type - -# -# Bootloader config -# - -# -# Bootloader manager -# -CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y -CONFIG_BOOTLOADER_PROJECT_VER=1 -# end of Bootloader manager - -CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 -CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set -CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y -# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set -CONFIG_BOOTLOADER_LOG_LEVEL=3 - -# -# Serial Flash Configurations -# -# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set -CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y -# end of Serial Flash Configurations - -# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set -CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y -# CONFIG_BOOTLOADER_FACTORY_RESET is not set -# CONFIG_BOOTLOADER_APP_TEST is not set -CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y -CONFIG_BOOTLOADER_WDT_ENABLE=y -# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set -CONFIG_BOOTLOADER_WDT_TIME_MS=9000 -# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set -CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 -# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set -# end of Bootloader config - -# -# Security features -# -CONFIG_SECURE_BOOT_V1_SUPPORTED=y -# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set -# CONFIG_SECURE_BOOT is not set -# CONFIG_SECURE_FLASH_ENC_ENABLED is not set -# end of Security features - -# -# Application manager -# -CONFIG_APP_COMPILE_TIME_DATE=y -# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set -# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set -# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set -CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 -# end of Application manager - -CONFIG_ESP_ROM_HAS_CRC_LE=y -CONFIG_ESP_ROM_HAS_CRC_BE=y -CONFIG_ESP_ROM_HAS_MZ_CRC32=y -CONFIG_ESP_ROM_HAS_JPEG_DECODE=y -CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y -CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y -CONFIG_ESP_ROM_HAS_NEWLIB=y -CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y -CONFIG_ESP_ROM_HAS_NEWLIB_32BIT_TIME=y -CONFIG_ESP_ROM_HAS_SW_FLOAT=y -CONFIG_ESP_ROM_USB_OTG_NUM=-1 -CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1 -CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y - -# -# Serial flasher config -# -# CONFIG_ESPTOOLPY_NO_STUB is not set -# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set -# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set -CONFIG_ESPTOOLPY_FLASHMODE_DIO=y -# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set -CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y -CONFIG_ESPTOOLPY_FLASHMODE="dio" -# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set -CONFIG_ESPTOOLPY_FLASHFREQ_40M=y -# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set -CONFIG_ESPTOOLPY_FLASHFREQ="40m" -# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y -# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="2MB" -# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set -CONFIG_ESPTOOLPY_BEFORE_RESET=y -# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set -CONFIG_ESPTOOLPY_BEFORE="default_reset" -CONFIG_ESPTOOLPY_AFTER_RESET=y -# CONFIG_ESPTOOLPY_AFTER_NORESET is not set -CONFIG_ESPTOOLPY_AFTER="hard_reset" -CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 -# end of Serial flasher config - -# -# Partition Table -# -CONFIG_PARTITION_TABLE_SINGLE_APP=y -# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set -# CONFIG_PARTITION_TABLE_TWO_OTA is not set -# CONFIG_PARTITION_TABLE_CUSTOM is not set -CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" -CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" -CONFIG_PARTITION_TABLE_OFFSET=0x8000 -CONFIG_PARTITION_TABLE_MD5=y -# end of Partition Table - -# -# Arduino Configuration -# -CONFIG_ARDUINO_VARIANT="esp32" -CONFIG_ENABLE_ARDUINO_DEPENDS=y -# CONFIG_AUTOSTART_ARDUINO is not set -# CONFIG_ARDUINO_RUN_CORE0 is not set -CONFIG_ARDUINO_RUN_CORE1=y -# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_RUNNING_CORE=1 -CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 -# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set -CONFIG_ARDUINO_EVENT_RUN_CORE1=y -# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 -# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set -# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set -CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y -CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 -CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=2048 -CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 -CONFIG_ARDUINO_UDP_RUN_CORE0=y -# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set -# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_UDP_RUNNING_CORE=0 -CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 -# CONFIG_ARDUINO_ISR_IRAM is not set -# CONFIG_DISABLE_HAL_LOCKS is not set - -# -# Debug Log Configuration -# -CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE=y -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=0 -# CONFIG_ARDUHAL_LOG_COLORS is not set -# CONFIG_ARDUHAL_ESP_LOG is not set -# end of Debug Log Configuration - -# CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set -CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS=y -CONFIG_ARDUHAL_PARTITION_SCHEME="min_spiffs" -CONFIG_ARDUINO_SELECTIVE_COMPILATION=y -CONFIG_ARDUINO_SELECTIVE_SPI=y -CONFIG_ARDUINO_SELECTIVE_Wire=y -CONFIG_ARDUINO_SELECTIVE_ESP_SR=y -CONFIG_ARDUINO_SELECTIVE_EEPROM=y -# CONFIG_ARDUINO_SELECTIVE_Preferences is not set -# CONFIG_ARDUINO_SELECTIVE_Ticker is not set -CONFIG_ARDUINO_SELECTIVE_Update=y -# CONFIG_ARDUINO_SELECTIVE_Zigbee is not set -CONFIG_ARDUINO_SELECTIVE_FS=y -# CONFIG_ARDUINO_SELECTIVE_SD is not set -# CONFIG_ARDUINO_SELECTIVE_SD_MMC is not set -# CONFIG_ARDUINO_SELECTIVE_SPIFFS is not set -# CONFIG_ARDUINO_SELECTIVE_FFat is not set -CONFIG_ARDUINO_SELECTIVE_LittleFS=y -CONFIG_ARDUINO_SELECTIVE_Network=y -# CONFIG_ARDUINO_SELECTIVE_Ethernet is not set -CONFIG_ARDUINO_SELECTIVE_PPP=y -CONFIG_ARDUINO_SELECTIVE_ArduinoOTA=y -CONFIG_ARDUINO_SELECTIVE_AsyncUDP=y -CONFIG_ARDUINO_SELECTIVE_DNSServer=y -CONFIG_ARDUINO_SELECTIVE_ESPmDNS=y -CONFIG_ARDUINO_SELECTIVE_HTTPClient=y -# CONFIG_ARDUINO_SELECTIVE_Matter is not set -# CONFIG_ARDUINO_SELECTIVE_NetBIOS is not set -CONFIG_ARDUINO_SELECTIVE_WebServer=y -CONFIG_ARDUINO_SELECTIVE_WiFi=y -CONFIG_ARDUINO_SELECTIVE_NetworkClientSecure=y -CONFIG_ARDUINO_SELECTIVE_WiFiProv=y -CONFIG_ARDUINO_SELECTIVE_BLE=y -# CONFIG_ARDUINO_SELECTIVE_BluetoothSerial is not set -CONFIG_ARDUINO_SELECTIVE_SimpleBLE=y -# CONFIG_ARDUINO_SELECTIVE_RainMaker is not set -# CONFIG_ARDUINO_SELECTIVE_OpenThread is not set -# CONFIG_ARDUINO_SELECTIVE_Insights is not set -# end of Arduino Configuration - -# -# Compiler options -# -CONFIG_COMPILER_OPTIMIZATION_DEBUG=y -# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set -# CONFIG_COMPILER_OPTIMIZATION_PERF is not set -# CONFIG_COMPILER_OPTIMIZATION_NONE is not set -CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y -# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set -# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set -CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y -CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 -# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set -CONFIG_COMPILER_HIDE_PATHS_MACROS=y -# CONFIG_COMPILER_CXX_EXCEPTIONS is not set -# CONFIG_COMPILER_CXX_RTTI is not set -CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y -# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set -# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set -# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set -# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set -# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set -# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set -# CONFIG_COMPILER_DUMP_RTL_FILES is not set -CONFIG_COMPILER_RT_LIB_GCCLIB=y -CONFIG_COMPILER_RT_LIB_NAME="gcc" -CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y -# CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set -# end of Compiler options - -# -# Component config -# - -# -# Application Level Tracing -# -# CONFIG_APPTRACE_DEST_JTAG is not set -CONFIG_APPTRACE_DEST_NONE=y -# CONFIG_APPTRACE_DEST_UART1 is not set -# CONFIG_APPTRACE_DEST_UART2 is not set -CONFIG_APPTRACE_DEST_UART_NONE=y -CONFIG_APPTRACE_UART_TASK_PRIO=1 -CONFIG_APPTRACE_LOCK_ENABLE=y -# end of Application Level Tracing - -# -# Bluetooth -# -CONFIG_BT_ENABLED=y -# CONFIG_BT_BLUEDROID_ENABLED is not set -CONFIG_BT_NIMBLE_ENABLED=y -# CONFIG_BT_CONTROLLER_ONLY is not set -CONFIG_BT_CONTROLLER_ENABLED=y -# CONFIG_BT_CONTROLLER_DISABLED is not set - -# -# NimBLE Options -# -CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y -# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set -# CONFIG_BT_NIMBLE_LOG_LEVEL_NONE is not set -# CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR is not set -# CONFIG_BT_NIMBLE_LOG_LEVEL_WARNING is not set -CONFIG_BT_NIMBLE_LOG_LEVEL_INFO=y -# CONFIG_BT_NIMBLE_LOG_LEVEL_DEBUG is not set -CONFIG_BT_NIMBLE_LOG_LEVEL=1 -CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 -CONFIG_BT_NIMBLE_MAX_BONDS=1 -CONFIG_BT_NIMBLE_MAX_CCCDS=1 -CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM=0 -CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y -# CONFIG_BT_NIMBLE_PINNED_TO_CORE_1 is not set -CONFIG_BT_NIMBLE_PINNED_TO_CORE=0 -CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=4096 -CONFIG_BT_NIMBLE_ROLE_CENTRAL=y -CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y -CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y -CONFIG_BT_NIMBLE_ROLE_OBSERVER=y -# CONFIG_BT_NIMBLE_NVS_PERSIST is not set -# CONFIG_BT_NIMBLE_SMP_ID_RESET is not set -# CONFIG_BT_NIMBLE_SECURITY_ENABLE is not set -# CONFIG_BT_NIMBLE_DEBUG is not set -# CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set -CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" -CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 -CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=256 -CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE=0 - -# -# Memory Settings -# -CONFIG_BT_NIMBLE_MSYS_1_BLOCK_COUNT=12 -CONFIG_BT_NIMBLE_MSYS_1_BLOCK_SIZE=256 -CONFIG_BT_NIMBLE_MSYS_2_BLOCK_COUNT=24 -CONFIG_BT_NIMBLE_MSYS_2_BLOCK_SIZE=320 -CONFIG_BT_NIMBLE_TRANSPORT_ACL_FROM_LL_COUNT=24 -CONFIG_BT_NIMBLE_TRANSPORT_ACL_SIZE=255 -CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70 -CONFIG_BT_NIMBLE_TRANSPORT_EVT_COUNT=30 -CONFIG_BT_NIMBLE_TRANSPORT_EVT_DISCARD_COUNT=8 -CONFIG_BT_NIMBLE_L2CAP_COC_SDU_BUFF_COUNT=1 -# end of Memory Settings - -CONFIG_BT_NIMBLE_GATT_MAX_PROCS=4 -CONFIG_BT_NIMBLE_HS_FLOW_CTRL=y -CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 -CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 -CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y -CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 -# CONFIG_BT_NIMBLE_MESH is not set -CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y -CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 -# CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set -# CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set -CONFIG_BT_NIMBLE_WHITELIST_SIZE=1 -# CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set -# CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set -CONFIG_BT_NIMBLE_USE_ESP_TIMER=y -CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y -# CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set - -# -# GAP Service -# - -# -# GAP Appearance write permissions -# -# CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set -# end of GAP Appearance write permissions - -CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM=0 -CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ENC=0 -CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHN=0 -CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHR=0 -CONFIG_BT_NIMBLE_SVC_GAP_CAR_CHAR_NOT_SUPP=y -# CONFIG_BT_NIMBLE_SVC_GAP_CAR_NOT_SUPP is not set -# CONFIG_BT_NIMBLE_SVC_GAP_CAR_SUPP is not set -CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 - -# -# GAP device name write permissions -# -# CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set -# end of GAP device name write permissions - -CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM=0 -CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_ENC=0 -CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHEN=0 -CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHOR=0 -CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 -CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 -CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 -CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 -# CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL is not set -# end of GAP Service - -# -# BLE Services -# -# CONFIG_BT_NIMBLE_HID_SERVICE is not set -# CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY is not set - -# -# Device Information Service -# -# CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME is not set -# CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER is not set -# CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION is not set -# CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION is not set -# CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION is not set -# CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID is not set -# CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID is not set -# CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED is not set -# end of Device Information Service -# end of BLE Services - -# CONFIG_BT_NIMBLE_VS_SUPPORT is not set -# CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set -# CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set -# CONFIG_BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN is not set -# CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set - -# -# Host-controller Transport -# -CONFIG_UART_HW_FLOWCTRL_DISABLE=y -# CONFIG_UART_HW_FLOWCTRL_CTS_RTS is not set -CONFIG_BT_NIMBLE_HCI_UART_FLOW_CTRL=0 -CONFIG_BT_NIMBLE_HCI_UART_RTS_PIN=19 -CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 -# end of Host-controller Transport - -CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 -# CONFIG_BT_NIMBLE_SUBRATE is not set -# end of NimBLE Options - -# -# Controller Options -# -CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y -# CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set -# CONFIG_BTDM_CTRL_MODE_BTDM is not set -CONFIG_BTDM_CTRL_BLE_MAX_CONN=3 -CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 -CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 -CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 -CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=3 -CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 -CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 -CONFIG_BTDM_CTRL_PINNED_TO_CORE_0=y -# CONFIG_BTDM_CTRL_PINNED_TO_CORE_1 is not set -CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 -CONFIG_BTDM_CTRL_HCI_MODE_VHCI=y -# CONFIG_BTDM_CTRL_HCI_MODE_UART_H4 is not set - -# -# MODEM SLEEP Options -# -CONFIG_BTDM_CTRL_MODEM_SLEEP=y -CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG=y -# CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_EVED is not set -CONFIG_BTDM_CTRL_LPCLK_SEL_MAIN_XTAL=y -# end of MODEM SLEEP Options - -CONFIG_BTDM_BLE_DEFAULT_SCA_250PPM=y -CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 -CONFIG_BTDM_BLE_SCAN_DUPL=y -CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y -# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA is not set -# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE is not set -CONFIG_BTDM_SCAN_DUPL_TYPE=0 -CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 -CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 -# CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set -CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y -# CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set -# CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set -CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y -CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 -CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 - -# -# BLE disconnect when instant passed -# -# CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set -# CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set -# end of BLE disconnect when instant passed - -CONFIG_BTDM_RESERVE_DRAM=0xdb5c -CONFIG_BTDM_CTRL_HLI=y -# end of Controller Options - -# -# Common Options -# -CONFIG_BT_ALARM_MAX_NUM=50 -# end of Common Options - -# CONFIG_BT_HCI_LOG_DEBUG_EN is not set -# end of Bluetooth - -# CONFIG_BLE_MESH is not set - -# -# Console Library -# -# CONFIG_CONSOLE_SORTED_HELP is not set -# end of Console Library - -# -# Driver Configurations -# - -# -# TWAI Configuration -# -# CONFIG_TWAI_ISR_IN_IRAM is not set -CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y -CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y -CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID=y -CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT=y -CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y -# end of TWAI Configuration - -# -# Legacy ADC Driver Configuration -# -CONFIG_ADC_DISABLE_DAC=y -# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set - -# -# Legacy ADC Calibration Configuration -# -CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y -CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y -CONFIG_ADC_CAL_LUT_ENABLE=y -# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set -# end of Legacy ADC Calibration Configuration -# end of Legacy ADC Driver Configuration - -# -# Legacy DAC Driver Configurations -# -# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set -# end of Legacy DAC Driver Configurations - -# -# Legacy MCPWM Driver Configurations -# -# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set -# end of Legacy MCPWM Driver Configurations - -# -# Legacy Timer Group Driver Configurations -# -# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set -# end of Legacy Timer Group Driver Configurations - -# -# Legacy RMT Driver Configurations -# -# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set -# end of Legacy RMT Driver Configurations - -# -# Legacy I2S Driver Configurations -# -# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set -# end of Legacy I2S Driver Configurations - -# -# Legacy PCNT Driver Configurations -# -# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set -# end of Legacy PCNT Driver Configurations - -# -# Legacy SDM Driver Configurations -# -# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set -# end of Legacy SDM Driver Configurations -# end of Driver Configurations - -# -# eFuse Bit Manager -# -# CONFIG_EFUSE_CUSTOM_TABLE is not set -# CONFIG_EFUSE_VIRTUAL is not set -# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set -CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y -# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set -CONFIG_EFUSE_MAX_BLK_LEN=192 -# end of eFuse Bit Manager - -# -# ESP-TLS -# -CONFIG_ESP_TLS_USING_MBEDTLS=y -# CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set -# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set -# CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set -# CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set -# CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set -# CONFIG_ESP_TLS_PSK_VERIFICATION is not set -# CONFIG_ESP_TLS_INSECURE is not set -# end of ESP-TLS - -# -# ADC and ADC Calibration -# -# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set -# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set - -# -# ADC Calibration Configurations -# -CONFIG_ADC_CALI_EFUSE_TP_ENABLE=y -CONFIG_ADC_CALI_EFUSE_VREF_ENABLE=y -CONFIG_ADC_CALI_LUT_ENABLE=y -# end of ADC Calibration Configurations - -CONFIG_ADC_DISABLE_DAC_OUTPUT=y -# CONFIG_ADC_ENABLE_DEBUG_LOG is not set -# end of ADC and ADC Calibration - -# -# Wireless Coexistence -# -CONFIG_ESP_COEX_ENABLED=y -CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y -# CONFIG_ESP_COEX_POWER_MANAGEMENT is not set -# CONFIG_ESP_COEX_GPIO_DEBUG is not set -# end of Wireless Coexistence - -# -# Common ESP-related -# -CONFIG_ESP_ERR_TO_NAME_LOOKUP=y -# end of Common ESP-related - -# -# ESP-Driver:DAC Configurations -# -# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set -# CONFIG_DAC_ISR_IRAM_SAFE is not set -# CONFIG_DAC_ENABLE_DEBUG_LOG is not set -CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y -# end of ESP-Driver:DAC Configurations - -# -# ESP-Driver:GPIO Configurations -# -# CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set -# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set -# end of ESP-Driver:GPIO Configurations - -# -# ESP-Driver:GPTimer Configurations -# -CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y -# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set -# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set -# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:GPTimer Configurations - -# -# ESP-Driver:I2C Configurations -# -# CONFIG_I2C_ISR_IRAM_SAFE is not set -# CONFIG_I2C_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:I2C Configurations - -# -# ESP-Driver:I2S Configurations -# -# CONFIG_I2S_ISR_IRAM_SAFE is not set -# CONFIG_I2S_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:I2S Configurations - -# -# ESP-Driver:LEDC Configurations -# -# CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set -# end of ESP-Driver:LEDC Configurations - -# -# ESP-Driver:MCPWM Configurations -# -# CONFIG_MCPWM_ISR_IRAM_SAFE is not set -# CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set -# CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:MCPWM Configurations - -# -# ESP-Driver:PCNT Configurations -# -# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set -# CONFIG_PCNT_ISR_IRAM_SAFE is not set -# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:PCNT Configurations - -# -# ESP-Driver:RMT Configurations -# -# CONFIG_RMT_ISR_IRAM_SAFE is not set -# CONFIG_RMT_RECV_FUNC_IN_IRAM is not set -# CONFIG_RMT_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:RMT Configurations - -# -# ESP-Driver:Sigma Delta Modulator Configurations -# -# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set -# CONFIG_SDM_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:Sigma Delta Modulator Configurations - -# -# ESP-Driver:SPI Configurations -# -# CONFIG_SPI_MASTER_IN_IRAM is not set -CONFIG_SPI_MASTER_ISR_IN_IRAM=y -# CONFIG_SPI_SLAVE_IN_IRAM is not set -CONFIG_SPI_SLAVE_ISR_IN_IRAM=y -# end of ESP-Driver:SPI Configurations - -# -# ESP-Driver:Touch Sensor Configurations -# -# CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set -# CONFIG_TOUCH_ISR_IRAM_SAFE is not set -# CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:Touch Sensor Configurations - -# -# ESP-Driver:UART Configurations -# -# CONFIG_UART_ISR_IN_IRAM is not set -# end of ESP-Driver:UART Configurations - -# -# Ethernet -# -# CONFIG_ETH_USE_ESP32_EMAC is not set -# CONFIG_ETH_USE_SPI_ETHERNET is not set -# CONFIG_ETH_USE_OPENETH is not set -# end of Ethernet - -# -# Event Loop Library -# -# CONFIG_ESP_EVENT_LOOP_PROFILING is not set -CONFIG_ESP_EVENT_POST_FROM_ISR=y -CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y -# end of Event Loop Library - -# -# GDB Stub -# -CONFIG_ESP_GDBSTUB_ENABLED=y -# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set -CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y -CONFIG_ESP_GDBSTUB_MAX_TASKS=32 -# end of GDB Stub - -# -# ESP HTTP client -# -CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y -# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set -# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set -# CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set -# end of ESP HTTP client - -# -# HTTP Server -# -CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 -CONFIG_HTTPD_MAX_URI_LEN=512 -CONFIG_HTTPD_ERR_RESP_NO_DELAY=y -CONFIG_HTTPD_PURGE_BUF_LEN=32 -# CONFIG_HTTPD_LOG_PURGE_DATA is not set -# CONFIG_HTTPD_WS_SUPPORT is not set -# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set -# end of HTTP Server - -# -# ESP HTTPS OTA -# -# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set -# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set -# end of ESP HTTPS OTA - -# -# ESP HTTPS server -# -# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set -# end of ESP HTTPS server - -# -# Hardware Settings -# - -# -# Chip revision -# -CONFIG_ESP32_REV_MIN_0=y -# CONFIG_ESP32_REV_MIN_1 is not set -# CONFIG_ESP32_REV_MIN_1_1 is not set -# CONFIG_ESP32_REV_MIN_2 is not set -# CONFIG_ESP32_REV_MIN_3 is not set -# CONFIG_ESP32_REV_MIN_3_1 is not set -CONFIG_ESP32_REV_MIN=0 -CONFIG_ESP32_REV_MIN_FULL=0 -CONFIG_ESP_REV_MIN_FULL=0 - -# -# Maximum Supported ESP32 Revision (Rev v3.99) -# -CONFIG_ESP32_REV_MAX_FULL=399 -CONFIG_ESP_REV_MAX_FULL=399 -CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL=0 -CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL=99 - -# -# Maximum Supported ESP32 eFuse Block Revision (eFuse Block Rev v0.99) -# -# end of Chip revision - -# -# MAC Config -# -CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y -CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_FOUR=y -CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 -# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set -CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y -CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 -# CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set -# CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set -# end of MAC Config - -# -# Sleep Config -# -# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set -CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y -# CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set -CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y -# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set -CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 -# CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set -# CONFIG_ESP_SLEEP_DEBUG is not set -CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y -# end of Sleep Config - -# -# RTC Clock Config -# -CONFIG_RTC_CLK_SRC_INT_RC=y -# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set -# CONFIG_RTC_CLK_SRC_EXT_OSC is not set -# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set -CONFIG_RTC_CLK_CAL_CYCLES=1024 -# end of RTC Clock Config - -# -# Peripheral Control -# -CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y -# end of Peripheral Control - -# -# Main XTAL Config -# -# CONFIG_XTAL_FREQ_26 is not set -CONFIG_XTAL_FREQ_40=y -# CONFIG_XTAL_FREQ_AUTO is not set -CONFIG_XTAL_FREQ=40 -# end of Main XTAL Config - -CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y -# end of Hardware Settings - -# -# LCD and Touch Panel -# - -# -# LCD Touch Drivers are maintained in the IDF Component Registry -# - -# -# LCD Peripheral Configuration -# -# CONFIG_LCD_ENABLE_DEBUG_LOG is not set -# end of LCD Peripheral Configuration -# end of LCD and Touch Panel - -# -# ESP NETIF Adapter -# -CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 -CONFIG_ESP_NETIF_TCPIP_LWIP=y -# CONFIG_ESP_NETIF_LOOPBACK is not set -CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y -# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set -# CONFIG_ESP_NETIF_L2_TAP is not set -# CONFIG_ESP_NETIF_BRIDGE_EN is not set -# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set -# end of ESP NETIF Adapter - -# -# Partition API Configuration -# -# end of Partition API Configuration - -# -# PHY -# -CONFIG_ESP_PHY_ENABLED=y -CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y -# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set -CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 -CONFIG_ESP_PHY_MAX_TX_POWER=20 -# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set -# CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set -CONFIG_ESP_PHY_RF_CAL_PARTIAL=y -# CONFIG_ESP_PHY_RF_CAL_NONE is not set -# CONFIG_ESP_PHY_RF_CAL_FULL is not set -CONFIG_ESP_PHY_CALIBRATION_MODE=0 -# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set -# end of PHY - -# -# Power Management -# -# CONFIG_PM_ENABLE is not set -# CONFIG_PM_SLP_IRAM_OPT is not set -# end of Power Management - -# -# ESP PSRAM -# -# CONFIG_SPIRAM is not set -# end of ESP PSRAM - -# -# ESP Ringbuf -# -# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set -# end of ESP Ringbuf - -# -# ESP System Settings -# -# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set -CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y -# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set -CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 - -# -# Memory -# -# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set - -# -# Non-backward compatible options -# -# CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set -# end of Non-backward compatible options -# end of Memory - -# -# Trace memory -# -# CONFIG_ESP32_TRAX is not set -CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 -# end of Trace memory - -# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set -CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y -# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set -# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set -CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 - -# -# Memory protection -# -# end of Memory protection - -CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 -CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y -# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set -# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 -CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 -CONFIG_ESP_CONSOLE_UART_DEFAULT=y -# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set -# CONFIG_ESP_CONSOLE_NONE is not set -CONFIG_ESP_CONSOLE_UART=y -CONFIG_ESP_CONSOLE_UART_NUM=0 -CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0 -CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 -CONFIG_ESP_INT_WDT=y -CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 -CONFIG_ESP_INT_WDT_CHECK_CPU1=y -CONFIG_ESP_TASK_WDT_EN=y -CONFIG_ESP_TASK_WDT_INIT=y -# CONFIG_ESP_TASK_WDT_PANIC is not set -CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 -CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y -CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# CONFIG_ESP_PANIC_HANDLER_IRAM is not set -# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set -CONFIG_ESP_DEBUG_OCDAWARE=y -CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y - -# -# Brownout Detector -# -CONFIG_ESP_BROWNOUT_DET=y -CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7 is not set -CONFIG_ESP_BROWNOUT_DET_LVL=0 -# end of Brownout Detector - -# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set -CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y -# end of ESP System Settings - -# -# IPC (Inter-Processor Call) -# -CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 -CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y -CONFIG_ESP_IPC_ISR_ENABLE=y -# end of IPC (Inter-Processor Call) - -# -# ESP Timer (High Resolution Timer) -# -# CONFIG_ESP_TIMER_PROFILING is not set -CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y -CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y -CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 -CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 -# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set -CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 -CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y -CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y -# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set -CONFIG_ESP_TIMER_IMPL_TG0_LAC=y -# end of ESP Timer (High Resolution Timer) - -# -# Wi-Fi -# -CONFIG_ESP_WIFI_ENABLED=y -CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 -CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 -# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set -CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y -CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 -CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32 -CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y -# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set -CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 -CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 -# CONFIG_ESP_WIFI_CSI_ENABLED is not set -CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y -CONFIG_ESP_WIFI_TX_BA_WIN=6 -CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y -CONFIG_ESP_WIFI_RX_BA_WIN=6 -CONFIG_ESP_WIFI_NVS_ENABLED=y -CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y -# CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set -CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 -CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 -# CONFIG_ESP_WIFI_IRAM_OPT is not set -# CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set -# CONFIG_ESP_WIFI_RX_IRAM_OPT is not set -CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y -CONFIG_ESP_WIFI_ENABLE_SAE_PK=y -CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y -CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y -# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set -CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 -CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 -CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 -CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y -CONFIG_ESP_WIFI_GMAC_SUPPORT=y -CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y -# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set -CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 -# CONFIG_ESP_WIFI_NAN_ENABLE is not set -CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y -CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y -# CONFIG_ESP_WIFI_WAPI_PSK is not set -# CONFIG_ESP_WIFI_11KV_SUPPORT is not set -# CONFIG_ESP_WIFI_MBO_SUPPORT is not set -# CONFIG_ESP_WIFI_DPP_SUPPORT is not set -# CONFIG_ESP_WIFI_11R_SUPPORT is not set -# CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set - -# -# WPS Configuration Options -# -# CONFIG_ESP_WIFI_WPS_STRICT is not set -# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set -# end of WPS Configuration Options - -# CONFIG_ESP_WIFI_DEBUG_PRINT is not set -# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set -CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y -# CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set -# end of Wi-Fi - -# -# Core dump -# -# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set -# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set -CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y -# end of Core dump - -# -# FAT Filesystem support -# -CONFIG_FATFS_VOLUME_COUNT=2 -CONFIG_FATFS_LFN_NONE=y -# CONFIG_FATFS_LFN_HEAP is not set -# CONFIG_FATFS_LFN_STACK is not set -# CONFIG_FATFS_SECTOR_512 is not set -CONFIG_FATFS_SECTOR_4096=y -# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set -CONFIG_FATFS_CODEPAGE_437=y -# CONFIG_FATFS_CODEPAGE_720 is not set -# CONFIG_FATFS_CODEPAGE_737 is not set -# CONFIG_FATFS_CODEPAGE_771 is not set -# CONFIG_FATFS_CODEPAGE_775 is not set -# CONFIG_FATFS_CODEPAGE_850 is not set -# CONFIG_FATFS_CODEPAGE_852 is not set -# CONFIG_FATFS_CODEPAGE_855 is not set -# CONFIG_FATFS_CODEPAGE_857 is not set -# CONFIG_FATFS_CODEPAGE_860 is not set -# CONFIG_FATFS_CODEPAGE_861 is not set -# CONFIG_FATFS_CODEPAGE_862 is not set -# CONFIG_FATFS_CODEPAGE_863 is not set -# CONFIG_FATFS_CODEPAGE_864 is not set -# CONFIG_FATFS_CODEPAGE_865 is not set -# CONFIG_FATFS_CODEPAGE_866 is not set -# CONFIG_FATFS_CODEPAGE_869 is not set -# CONFIG_FATFS_CODEPAGE_932 is not set -# CONFIG_FATFS_CODEPAGE_936 is not set -# CONFIG_FATFS_CODEPAGE_949 is not set -# CONFIG_FATFS_CODEPAGE_950 is not set -CONFIG_FATFS_CODEPAGE=437 -CONFIG_FATFS_FS_LOCK=0 -CONFIG_FATFS_TIMEOUT_MS=10000 -CONFIG_FATFS_PER_FILE_CACHE=y -# CONFIG_FATFS_USE_FASTSEEK is not set -CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 -# CONFIG_FATFS_IMMEDIATE_FSYNC is not set -# CONFIG_FATFS_USE_LABEL is not set -CONFIG_FATFS_LINK_LOCK=y -# end of FAT Filesystem support - -# -# FreeRTOS -# - -# -# Kernel -# -# CONFIG_FREERTOS_SMP is not set -# CONFIG_FREERTOS_UNICORE is not set -CONFIG_FREERTOS_HZ=1000 -# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set -# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set -CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y -CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 -CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 -# CONFIG_FREERTOS_USE_IDLE_HOOK is not set -# CONFIG_FREERTOS_USE_TICK_HOOK is not set -CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 -# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set -CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" -# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set -# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set -CONFIG_FREERTOS_TIMER_TASK_NO_AFFINITY=y -CONFIG_FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY=0x7FFFFFFF -CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 -CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 -CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 -CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 -CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 -# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set -# CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set -# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set -# CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set -# end of Kernel - -# -# Port -# -CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y -# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set -CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y -# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set -# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set -CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y -CONFIG_FREERTOS_ISR_STACKSIZE=1536 -CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y -# CONFIG_FREERTOS_FPU_IN_ISR is not set -CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y -CONFIG_FREERTOS_CORETIMER_0=y -# CONFIG_FREERTOS_CORETIMER_1 is not set -CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y -# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set -# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set -# end of Port - -CONFIG_FREERTOS_PORT=y -CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF -CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y -CONFIG_FREERTOS_DEBUG_OCDAWARE=y -CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y -CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y -CONFIG_FREERTOS_NUMBER_OF_CORES=2 -# end of FreeRTOS - -# -# Hardware Abstraction Layer (HAL) and Low Level (LL) -# -CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y -# CONFIG_HAL_ASSERTION_DISABLE is not set -# CONFIG_HAL_ASSERTION_SILENT is not set -# CONFIG_HAL_ASSERTION_ENABLE is not set -CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 -CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y -CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y -# CONFIG_HAL_ECDSA_GEN_SIG_CM is not set -# end of Hardware Abstraction Layer (HAL) and Low Level (LL) - -# -# Heap memory debugging -# -CONFIG_HEAP_POISONING_DISABLED=y -# CONFIG_HEAP_POISONING_LIGHT is not set -# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set -CONFIG_HEAP_TRACING_OFF=y -# CONFIG_HEAP_TRACING_STANDALONE is not set -# CONFIG_HEAP_TRACING_TOHOST is not set -# CONFIG_HEAP_USE_HOOKS is not set -# CONFIG_HEAP_TASK_TRACKING is not set -# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set -# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set -# end of Heap memory debugging - -# -# Log output -# -CONFIG_LOG_DEFAULT_LEVEL_NONE=y -# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set -# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set -# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set -# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set -# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_LOG_DEFAULT_LEVEL=0 -CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y -# CONFIG_LOG_MAXIMUM_LEVEL_ERROR is not set -# CONFIG_LOG_MAXIMUM_LEVEL_WARN is not set -# CONFIG_LOG_MAXIMUM_LEVEL_INFO is not set -# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set -# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set -CONFIG_LOG_MAXIMUM_LEVEL=0 -# CONFIG_LOG_MASTER_LEVEL is not set -# CONFIG_LOG_COLORS is not set -CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y -# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set -# end of Log output - -# -# LWIP -# -CONFIG_LWIP_ENABLE=y -CONFIG_LWIP_LOCAL_HOSTNAME="espressif" -# CONFIG_LWIP_NETIF_API is not set -CONFIG_LWIP_TCPIP_TASK_PRIO=18 -# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set -# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -# CONFIG_LWIP_L2_TO_L3_COPY is not set -# CONFIG_LWIP_IRAM_OPTIMIZATION is not set -# CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set -CONFIG_LWIP_TIMERS_ONDEMAND=y -CONFIG_LWIP_ND6=y -# CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set -CONFIG_LWIP_MAX_SOCKETS=10 -# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set -# CONFIG_LWIP_SO_LINGER is not set -CONFIG_LWIP_SO_REUSE=y -CONFIG_LWIP_SO_REUSE_RXTOALL=y -CONFIG_LWIP_SO_RCVBUF=y -# CONFIG_LWIP_NETBUF_RECVINFO is not set -CONFIG_LWIP_IP_DEFAULT_TTL=64 -CONFIG_LWIP_IP4_FRAG=y -CONFIG_LWIP_IP6_FRAG=y -# CONFIG_LWIP_IP4_REASSEMBLY is not set -# CONFIG_LWIP_IP6_REASSEMBLY is not set -CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 -# CONFIG_LWIP_IP_FORWARD is not set -# CONFIG_LWIP_STATS is not set -CONFIG_LWIP_ESP_GRATUITOUS_ARP=y -CONFIG_LWIP_GARP_TMR_INTERVAL=60 -CONFIG_LWIP_ESP_MLDV6_REPORT=y -CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 -CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 -CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y -# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set -CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y -# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set -CONFIG_LWIP_DHCP_OPTIONS_LEN=68 -CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 -CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 - -# -# DHCP server -# -CONFIG_LWIP_DHCPS=y -CONFIG_LWIP_DHCPS_LEASE_UNIT=60 -CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 -CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y -# end of DHCP server - -# CONFIG_LWIP_AUTOIP is not set -CONFIG_LWIP_IPV4=y -CONFIG_LWIP_IPV6=y -# CONFIG_LWIP_IPV6_AUTOCONFIG is not set -CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 -# CONFIG_LWIP_IPV6_FORWARD is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5760 -CONFIG_LWIP_TCP_WND_DEFAULT=5760 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 -CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP - -# -# UDP -# -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# end of UDP - -# -# Checksums -# -# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set -# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set -CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y -# end of Checksums - -CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 -CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y -# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set -# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set -CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF -CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 -CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 -CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 -# CONFIG_LWIP_PPP_SUPPORT is not set -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 -# CONFIG_LWIP_SLIP_SUPPORT is not set - -# -# ICMP -# -CONFIG_LWIP_ICMP=y -# CONFIG_LWIP_MULTICAST_PING is not set -# CONFIG_LWIP_BROADCAST_PING is not set -# end of ICMP - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API - -# -# SNTP -# -CONFIG_LWIP_SNTP_MAX_SERVERS=1 -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set -CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 -CONFIG_LWIP_SNTP_STARTUP_DELAY=y -CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 -# end of SNTP - -# -# DNS -# -CONFIG_LWIP_DNS_MAX_HOST_IP=1 -CONFIG_LWIP_DNS_MAX_SERVERS=3 -# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set -# CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set -# end of DNS - -CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 -CONFIG_LWIP_ESP_LWIP_ASSERT=y - -# -# Hooks -# -# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set -CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y -# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set -CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y -# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set -# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set -CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y -# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set -# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set -CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_NONE=y -# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_DEFAULT is not set -# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_CUSTOM is not set -CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y -# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set -# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set -CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_NONE=y -# CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_CUSTOM is not set -# CONFIG_LWIP_HOOK_IP6_INPUT_NONE is not set -CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y -# CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set -# end of Hooks - -# CONFIG_LWIP_DEBUG is not set -# end of LWIP - -# -# mbedTLS -# -CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y -# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set -# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set -CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y -CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 -CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 -# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set -# CONFIG_MBEDTLS_DEBUG is not set - -# -# mbedTLS v3.x related -# -# CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set -# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set -# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set -# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set -CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y -CONFIG_MBEDTLS_PKCS7_C=y -# end of mbedTLS v3.x related - -# -# Certificate Bundle -# -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set -# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 -# end of Certificate Bundle - -# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set -CONFIG_MBEDTLS_CMAC_C=y -CONFIG_MBEDTLS_HARDWARE_AES=y -CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y -CONFIG_MBEDTLS_HARDWARE_MPI=y -# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set -CONFIG_MBEDTLS_HARDWARE_SHA=y -CONFIG_MBEDTLS_ROM_MD5=y -# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set -# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set -CONFIG_MBEDTLS_HAVE_TIME=y -# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set -# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set -CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y -CONFIG_MBEDTLS_SHA512_C=y -# CONFIG_MBEDTLS_SHA3_C is not set -CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y -# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set -# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set -# CONFIG_MBEDTLS_TLS_DISABLED is not set -CONFIG_MBEDTLS_TLS_SERVER=y -CONFIG_MBEDTLS_TLS_CLIENT=y -CONFIG_MBEDTLS_TLS_ENABLED=y - -# -# TLS Key Exchange Methods -# -CONFIG_MBEDTLS_PSK_MODES=y -CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_PSK=y -CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_PSK=y -CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y -# end of TLS Key Exchange Methods - -CONFIG_MBEDTLS_SSL_RENEGOTIATION=y -CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y -# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set -# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set -CONFIG_MBEDTLS_SSL_ALPN=y -CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y -CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y - -# -# Symmetric Ciphers -# -CONFIG_MBEDTLS_AES_C=y -# CONFIG_MBEDTLS_CAMELLIA_C is not set -# CONFIG_MBEDTLS_DES_C is not set -# CONFIG_MBEDTLS_BLOWFISH_C is not set -# CONFIG_MBEDTLS_XTEA_C is not set -CONFIG_MBEDTLS_CCM_C=y -CONFIG_MBEDTLS_GCM_C=y -# CONFIG_MBEDTLS_NIST_KW_C is not set -# end of Symmetric Ciphers - -# CONFIG_MBEDTLS_RIPEMD160_C is not set - -# -# Certificates -# -CONFIG_MBEDTLS_PEM_PARSE_C=y -CONFIG_MBEDTLS_PEM_WRITE_C=y -CONFIG_MBEDTLS_X509_CRL_PARSE_C=y -CONFIG_MBEDTLS_X509_CSR_PARSE_C=y -# end of Certificates - -CONFIG_MBEDTLS_ECP_C=y -# CONFIG_MBEDTLS_DHM_C is not set -CONFIG_MBEDTLS_ECDH_C=y -CONFIG_MBEDTLS_ECDSA_C=y -# CONFIG_MBEDTLS_ECJPAKE_C is not set -CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y -CONFIG_MBEDTLS_ECP_NIST_OPTIM=y -# CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set -# CONFIG_MBEDTLS_POLY1305_C is not set -# CONFIG_MBEDTLS_CHACHA20_C is not set -# CONFIG_MBEDTLS_HKDF_C is not set -# CONFIG_MBEDTLS_THREADING_C is not set -CONFIG_MBEDTLS_ERROR_STRINGS=y -CONFIG_MBEDTLS_FS_IO=y -# end of mbedTLS - -# -# ESP-MQTT Configurations -# -# CONFIG_MQTT_PROTOCOL_311 is not set -# CONFIG_MQTT_PROTOCOL_5 is not set -# CONFIG_MQTT_TRANSPORT_SSL is not set -# CONFIG_MQTT_TRANSPORT_WEBSOCKET is not set -# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set -# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set -# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set -# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set -# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set -# CONFIG_MQTT_CUSTOM_OUTBOX is not set -# end of ESP-MQTT Configurations - -# -# Newlib -# -CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set -CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y -# CONFIG_NEWLIB_NANO_FORMAT is not set -CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y -# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set -# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set -# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set -# end of Newlib - -# -# NVS -# -# CONFIG_NVS_ASSERT_ERROR_CHECK is not set -# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set -# end of NVS - -# -# OpenThread -# -# CONFIG_OPENTHREAD_ENABLED is not set - -# -# OpenThread Spinel -# -# CONFIG_OPENTHREAD_SPINEL_ONLY is not set -# end of OpenThread Spinel -# end of OpenThread - -# -# Protocomm -# -CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y -CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y -CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y -# end of Protocomm - -# -# PThreads -# -CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 -CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 -CONFIG_PTHREAD_STACK_MIN=768 -CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y -# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set -# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set -CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 -CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" -# end of PThreads - -# -# MMU Config -# -CONFIG_MMU_PAGE_SIZE_64KB=y -CONFIG_MMU_PAGE_MODE="64KB" -CONFIG_MMU_PAGE_SIZE=0x10000 -# end of MMU Config - -# -# Main Flash configuration -# - -# -# SPI Flash behavior when brownout -# -CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y -CONFIG_SPI_FLASH_BROWNOUT_RESET=y -# end of SPI Flash behavior when brownout - -# -# Optional and Experimental Features (READ DOCS FIRST) -# - -# -# Features here require specific hardware (READ DOCS FIRST!) -# -CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 -# CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set -# end of Optional and Experimental Features (READ DOCS FIRST) -# end of Main Flash configuration - -# -# SPI Flash driver -# -# CONFIG_SPI_FLASH_VERIFY_WRITE is not set -# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set -CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y -CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y -# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set -# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set -# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set -# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set -CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y -CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 -CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 -CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 -# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set -# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set -# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set - -# -# Auto-detect flash chips -# -CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y -CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y -CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y -CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y -CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y -CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y -# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set -# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set -# end of Auto-detect flash chips - -CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y -# end of SPI Flash driver - -# -# SPIFFS Configuration -# -CONFIG_SPIFFS_MAX_PARTITIONS=3 - -# -# SPIFFS Cache Configuration -# -CONFIG_SPIFFS_CACHE=y -CONFIG_SPIFFS_CACHE_WR=y -# CONFIG_SPIFFS_CACHE_STATS is not set -# end of SPIFFS Cache Configuration - -CONFIG_SPIFFS_PAGE_CHECK=y -CONFIG_SPIFFS_GC_MAX_RUNS=10 -# CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 -# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set -CONFIG_SPIFFS_USE_MAGIC=y -CONFIG_SPIFFS_USE_MAGIC_LENGTH=y -CONFIG_SPIFFS_META_LENGTH=4 -CONFIG_SPIFFS_USE_MTIME=y - -# -# Debug Configuration -# -# CONFIG_SPIFFS_DBG is not set -# CONFIG_SPIFFS_API_DBG is not set -# CONFIG_SPIFFS_GC_DBG is not set -# CONFIG_SPIFFS_CACHE_DBG is not set -# CONFIG_SPIFFS_CHECK_DBG is not set -# CONFIG_SPIFFS_TEST_VISUALISATION is not set -# end of Debug Configuration -# end of SPIFFS Configuration - -# -# TCP Transport -# - -# -# Websocket -# -CONFIG_WS_TRANSPORT=y -CONFIG_WS_BUFFER_SIZE=1024 -# CONFIG_WS_DYNAMIC_BUFFER is not set -# end of Websocket -# end of TCP Transport - -# -# Ultra Low Power (ULP) Co-processor -# -# CONFIG_ULP_COPROC_ENABLED is not set - -# -# ULP Debugging Options -# -# end of ULP Debugging Options -# end of Ultra Low Power (ULP) Co-processor - -# -# Unity unit testing library -# -CONFIG_UNITY_ENABLE_FLOAT=y -CONFIG_UNITY_ENABLE_DOUBLE=y -# CONFIG_UNITY_ENABLE_64BIT is not set -# CONFIG_UNITY_ENABLE_COLOR is not set -CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y -# CONFIG_UNITY_ENABLE_FIXTURE is not set -# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set -# end of Unity unit testing library - -# -# Virtual file system -# -CONFIG_VFS_SUPPORT_IO=y -CONFIG_VFS_SUPPORT_DIR=y -CONFIG_VFS_SUPPORT_SELECT=y -CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y -# CONFIG_VFS_SELECT_IN_RAM is not set -CONFIG_VFS_SUPPORT_TERMIOS=y -CONFIG_VFS_MAX_COUNT=8 - -# -# Host File System I/O (Semihosting) -# -CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -# end of Host File System I/O (Semihosting) -# end of Virtual file system - -# -# Wear Levelling -# -# CONFIG_WL_SECTOR_SIZE_512 is not set -CONFIG_WL_SECTOR_SIZE_4096=y -CONFIG_WL_SECTOR_SIZE=4096 -# end of Wear Levelling - -# -# Wi-Fi Provisioning Manager -# -CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 -CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 -# CONFIG_WIFI_PROV_BLE_BONDING is not set -CONFIG_WIFI_PROV_BLE_SEC_CONN=y -# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set -# CONFIG_WIFI_PROV_BLE_NOTIFY is not set -# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set -CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y -# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set -# end of Wi-Fi Provisioning Manager - -# -# Zigbee -# -# CONFIG_ZB_ENABLED is not set -# end of Zigbee - -# -# esp-modem -# -CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y -# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set -CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 -# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set -# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set -CONFIG_ESP_MODEM_C_API_STR_MAX=128 -# CONFIG_ESP_MODEM_URC_HANDLER is not set -# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set -# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set -# end of esp-modem - -# -# mDNS -# -CONFIG_MDNS_MAX_INTERFACES=3 -CONFIG_MDNS_MAX_SERVICES=10 -CONFIG_MDNS_TASK_PRIORITY=1 -CONFIG_MDNS_ACTION_QUEUE_LEN=16 -CONFIG_MDNS_TASK_STACK_SIZE=4096 -# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_MDNS_TASK_AFFINITY_CPU0=y -# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set -CONFIG_MDNS_TASK_AFFINITY=0x0 - -# -# MDNS Memory Configuration -# -CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y -CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y -# CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set -# end of MDNS Memory Configuration - -CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 -CONFIG_MDNS_TIMER_PERIOD_MS=100 -# CONFIG_MDNS_NETWORKING_SOCKET is not set -# CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set -# CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set -CONFIG_MDNS_ENABLE_CONSOLE_CLI=y -# CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set -CONFIG_MDNS_MULTIPLE_INSTANCE=y - -# -# MDNS Predefined interfaces -# -CONFIG_MDNS_PREDEF_NETIF_STA=y -CONFIG_MDNS_PREDEF_NETIF_AP=y -# end of MDNS Predefined interfaces -# end of mDNS - -# -# Network Provisioning Manager -# -CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y -CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 -CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 -# CONFIG_NETWORK_PROV_BLE_BONDING is not set -CONFIG_NETWORK_PROV_BLE_SEC_CONN=y -# CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set -# CONFIG_NETWORK_PROV_KEEP_BLE_ON_AFTER_PROV is not set -CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y -# CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set -# end of Network Provisioning Manager - -# -# LittleFS -# -# CONFIG_LITTLEFS_SDMMC_SUPPORT is not set -CONFIG_LITTLEFS_MAX_PARTITIONS=3 -CONFIG_LITTLEFS_PAGE_SIZE=256 -CONFIG_LITTLEFS_OBJ_NAME_LEN=64 -CONFIG_LITTLEFS_READ_SIZE=128 -CONFIG_LITTLEFS_WRITE_SIZE=128 -CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 -CONFIG_LITTLEFS_CACHE_SIZE=512 -CONFIG_LITTLEFS_BLOCK_CYCLES=512 -CONFIG_LITTLEFS_USE_MTIME=y -# CONFIG_LITTLEFS_USE_ONLY_HASH is not set -# CONFIG_LITTLEFS_HUMAN_READABLE is not set -CONFIG_LITTLEFS_MTIME_USE_SECONDS=y -# CONFIG_LITTLEFS_MTIME_USE_NONCE is not set -# CONFIG_LITTLEFS_SPIFFS_COMPAT is not set -# CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set -# CONFIG_LITTLEFS_FCNTL_GET_PATH is not set -# CONFIG_LITTLEFS_MULTIVERSION is not set -# CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set -CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y -# CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set -CONFIG_LITTLEFS_ASSERTS=y -# CONFIG_LITTLEFS_MMAP_PARTITION is not set -# end of LittleFS -# end of Component config - -# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 483bc0cf..75d97191 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,4 +3,5 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*) -idf_component_register(SRCS ${app_sources}) +idf_component_register(SRCS "Main.cpp" + INCLUDE_DIRS ".") From 2549d33ddcda5bc0edd37ddc38b69647f702baa3 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 24 Jun 2025 18:18:15 -0500 Subject: [PATCH 247/451] Revert "trying to compile with espressif plugin" This reverts commit f5e95fe22ec300a103b6cd92d051f18c61053699. --- .vscode/settings.json | 2 +- CMakeLists.txt | 8 +- dependencies.lock | 13 +- include/CMakeLists.txt | 6 - sdkconfig.old | 2103 +++++++++++++++++++++++++++++++++ sdkconfig.release | 2548 ++++++++++++++++++++++++++++++++++++++++ sdkconfig.release.old | 2197 ++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 3 +- 8 files changed, 6855 insertions(+), 25 deletions(-) delete mode 100644 include/CMakeLists.txt create mode 100644 sdkconfig.old create mode 100644 sdkconfig.release create mode 100644 sdkconfig.release.old diff --git a/.vscode/settings.json b/.vscode/settings.json index baf137d4..2888d84a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -119,6 +119,6 @@ "VERSIONFILE", "WEBSERVER" ], - "idf.pythonInstallPath": "C:\\Users\\anthony\\.espressif\\tools\\idf-python\\3.11.2\\python.exe", + "idf.pythonInstallPath": "/opt/homebrew/bin/python3", "idf.flashType": "UART", } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 39913c92..9a5f975e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.16.0) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(SmartSpin2k) -add_subdirectory(include) - - - +include_directories( + ${PROJECT_SOURCE_DIR}/include + ${PROJECT_SOURCE_DIR}/src +) \ No newline at end of file diff --git a/dependencies.lock b/dependencies.lock index 937a8ec5..3aef0ca5 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -41,16 +41,6 @@ dependencies: registry_url: https://components.espressif.com/ type: service version: 1.6.3 - espressif/esp_modem: - component_hash: b541c3f5765d3ba062c0d004b9ca6da6d0af908293421c2dbe046c537fb2a011 - dependencies: - - name: idf - require: private - version: '>=4.1' - source: - registry_url: https://components.espressif.com/ - type: service - version: 1.4.0 espressif/mdns: component_hash: 3ec0af5f6bce310512e90f482388d21cc7c0e99668172d2f895356165fc6f7c5 dependencies: @@ -91,11 +81,10 @@ direct_dependencies: - espressif/cbor - espressif/esp-zboss-lib - espressif/esp-zigbee-lib -- espressif/esp_modem - espressif/mdns - espressif/network_provisioning - idf - joltwallet/littlefs -manifest_hash: e9919b5b28bb7bb038864af176d8e81936400eff14ef44258dd5186bdc427ec2 +manifest_hash: cdea08c215af25ecb07f34a572afe529ccee1d11a022752ebfb3b54cbc0cb5f8 target: esp32 version: 2.0.0 diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt deleted file mode 100644 index 6c5c1ddd..00000000 --- a/include/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# This file was automatically generated for projects -# without default 'CMakeLists.txt' file. - -FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/include/*.*) - -#idf_component_register(SRCS ${app_sources}) \ No newline at end of file diff --git a/sdkconfig.old b/sdkconfig.old new file mode 100644 index 00000000..07c9dd84 --- /dev/null +++ b/sdkconfig.old @@ -0,0 +1,2103 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) 5.4.1 Project Configuration +# +CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined" +CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined" +CONFIG_SOC_DPORT_WORKAROUND="Not determined" +CONFIG_SOC_CAPS_ECO_VER_MAX=301 +CONFIG_SOC_ADC_SUPPORTED=y +CONFIG_SOC_DAC_SUPPORTED=y +CONFIG_SOC_UART_SUPPORTED=y +CONFIG_SOC_MCPWM_SUPPORTED=y +CONFIG_SOC_GPTIMER_SUPPORTED=y +CONFIG_SOC_SDMMC_HOST_SUPPORTED=y +CONFIG_SOC_BT_SUPPORTED=y +CONFIG_SOC_PCNT_SUPPORTED=y +CONFIG_SOC_PHY_SUPPORTED=y +CONFIG_SOC_WIFI_SUPPORTED=y +CONFIG_SOC_SDIO_SLAVE_SUPPORTED=y +CONFIG_SOC_TWAI_SUPPORTED=y +CONFIG_SOC_EFUSE_SUPPORTED=y +CONFIG_SOC_EMAC_SUPPORTED=y +CONFIG_SOC_ULP_SUPPORTED=y +CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y +CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y +CONFIG_SOC_RTC_MEM_SUPPORTED=y +CONFIG_SOC_I2S_SUPPORTED=y +CONFIG_SOC_RMT_SUPPORTED=y +CONFIG_SOC_SDM_SUPPORTED=y +CONFIG_SOC_GPSPI_SUPPORTED=y +CONFIG_SOC_LEDC_SUPPORTED=y +CONFIG_SOC_I2C_SUPPORTED=y +CONFIG_SOC_SUPPORT_COEXISTENCE=y +CONFIG_SOC_AES_SUPPORTED=y +CONFIG_SOC_MPI_SUPPORTED=y +CONFIG_SOC_SHA_SUPPORTED=y +CONFIG_SOC_FLASH_ENC_SUPPORTED=y +CONFIG_SOC_SECURE_BOOT_SUPPORTED=y +CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y +CONFIG_SOC_BOD_SUPPORTED=y +CONFIG_SOC_ULP_FSM_SUPPORTED=y +CONFIG_SOC_CLK_TREE_SUPPORTED=y +CONFIG_SOC_MPU_SUPPORTED=y +CONFIG_SOC_WDT_SUPPORTED=y +CONFIG_SOC_SPI_FLASH_SUPPORTED=y +CONFIG_SOC_RNG_SUPPORTED=y +CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y +CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y +CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y +CONFIG_SOC_PM_SUPPORTED=y +CONFIG_SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL=5 +CONFIG_SOC_XTAL_SUPPORT_26M=y +CONFIG_SOC_XTAL_SUPPORT_40M=y +CONFIG_SOC_XTAL_SUPPORT_AUTO_DETECT=y +CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DMA_SUPPORTED=y +CONFIG_SOC_ADC_PERIPH_NUM=2 +CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 +CONFIG_SOC_ADC_ATTEN_NUM=4 +CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 +CONFIG_SOC_ADC_PATT_LEN_MAX=16 +CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 +CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=4 +CONFIG_SOC_ADC_DIGI_MONITOR_NUM=0 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=2 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=20 +CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_SHARED_POWER=y +CONFIG_SOC_SHARED_IDCACHE_SUPPORTED=y +CONFIG_SOC_IDCACHE_PER_CORE=y +CONFIG_SOC_CPU_CORES_NUM=2 +CONFIG_SOC_CPU_INTR_NUM=32 +CONFIG_SOC_CPU_HAS_FPU=y +CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y +CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 +CONFIG_SOC_DAC_CHAN_NUM=2 +CONFIG_SOC_DAC_RESOLUTION=8 +CONFIG_SOC_DAC_DMA_16BIT_ALIGN=y +CONFIG_SOC_GPIO_PORT=1 +CONFIG_SOC_GPIO_PIN_COUNT=40 +CONFIG_SOC_GPIO_VALID_GPIO_MASK=0xFFFFFFFFFF +CONFIG_SOC_GPIO_IN_RANGE_MAX=39 +CONFIG_SOC_GPIO_OUT_RANGE_MAX=33 +CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0xEF0FEA +CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y +CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3 +CONFIG_SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP=y +CONFIG_SOC_I2C_NUM=2 +CONFIG_SOC_HP_I2C_NUM=2 +CONFIG_SOC_I2C_FIFO_LEN=32 +CONFIG_SOC_I2C_CMD_REG_NUM=16 +CONFIG_SOC_I2C_SUPPORT_SLAVE=y +CONFIG_SOC_I2C_SUPPORT_APB=y +CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR=y +CONFIG_SOC_I2C_STOP_INDEPENDENT=y +CONFIG_SOC_I2S_NUM=2 +CONFIG_SOC_I2S_HW_VERSION_1=y +CONFIG_SOC_I2S_SUPPORTS_APLL=y +CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y +CONFIG_SOC_I2S_SUPPORTS_PDM=y +CONFIG_SOC_I2S_SUPPORTS_PDM_TX=y +CONFIG_SOC_I2S_PDM_MAX_TX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_PDM_RX=y +CONFIG_SOC_I2S_PDM_MAX_RX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_ADC_DAC=y +CONFIG_SOC_I2S_SUPPORTS_ADC=y +CONFIG_SOC_I2S_SUPPORTS_DAC=y +CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y +CONFIG_SOC_I2S_MAX_DATA_WIDTH=24 +CONFIG_SOC_I2S_TRANS_SIZE_ALIGN_WORD=y +CONFIG_SOC_I2S_LCD_I80_VARIANT=y +CONFIG_SOC_LCD_I80_SUPPORTED=y +CONFIG_SOC_LCD_I80_BUSES=2 +CONFIG_SOC_LCD_I80_BUS_WIDTH=24 +CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y +CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y +CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y +CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y +CONFIG_SOC_LEDC_TIMER_NUM=4 +CONFIG_SOC_LEDC_CHANNEL_NUM=8 +CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=20 +CONFIG_SOC_MCPWM_GROUPS=2 +CONFIG_SOC_MCPWM_TIMERS_PER_GROUP=3 +CONFIG_SOC_MCPWM_OPERATORS_PER_GROUP=3 +CONFIG_SOC_MCPWM_COMPARATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GENERATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_TRIGGERS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GPIO_FAULTS_PER_GROUP=3 +CONFIG_SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP=y +CONFIG_SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER=3 +CONFIG_SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP=3 +CONFIG_SOC_MMU_PERIPH_NUM=2 +CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=3 +CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 +CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 +CONFIG_SOC_PCNT_GROUPS=1 +CONFIG_SOC_PCNT_UNITS_PER_GROUP=8 +CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 +CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 +CONFIG_SOC_RMT_GROUPS=1 +CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_CHANNELS_PER_GROUP=8 +CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 +CONFIG_SOC_RMT_SUPPORT_REF_TICK=y +CONFIG_SOC_RMT_SUPPORT_APB=y +CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y +CONFIG_SOC_RTCIO_PIN_COUNT=18 +CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y +CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y +CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_SDM_GROUPS=1 +CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 +CONFIG_SOC_SDM_CLK_SUPPORT_APB=y +CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y +CONFIG_SOC_SPI_AS_CS_SUPPORTED=y +CONFIG_SOC_SPI_PERIPH_NUM=3 +CONFIG_SOC_SPI_DMA_CHAN_NUM=2 +CONFIG_SOC_SPI_MAX_CS_NUM=3 +CONFIG_SOC_SPI_SUPPORT_CLK_APB=y +CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=64 +CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 +CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y +CONFIG_SOC_TIMER_GROUPS=2 +CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 +CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 +CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y +CONFIG_SOC_LP_TIMER_BIT_WIDTH_LO=32 +CONFIG_SOC_LP_TIMER_BIT_WIDTH_HI=16 +CONFIG_SOC_TOUCH_SENSOR_VERSION=1 +CONFIG_SOC_TOUCH_SENSOR_NUM=10 +CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1 +CONFIG_SOC_TWAI_CONTROLLER_NUM=1 +CONFIG_SOC_TWAI_BRP_MIN=2 +CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y +CONFIG_SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT=y +CONFIG_SOC_UART_NUM=3 +CONFIG_SOC_UART_HP_NUM=3 +CONFIG_SOC_UART_SUPPORT_APB_CLK=y +CONFIG_SOC_UART_SUPPORT_REF_TICK=y +CONFIG_SOC_UART_FIFO_LEN=128 +CONFIG_SOC_UART_BITRATE_MAX=5000000 +CONFIG_SOC_SPIRAM_SUPPORTED=y +CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y +CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG=y +CONFIG_SOC_SHA_ENDIANNESS_BE=y +CONFIG_SOC_SHA_SUPPORT_SHA1=y +CONFIG_SOC_SHA_SUPPORT_SHA256=y +CONFIG_SOC_SHA_SUPPORT_SHA384=y +CONFIG_SOC_SHA_SUPPORT_SHA512=y +CONFIG_SOC_MPI_MEM_BLOCKS_NUM=4 +CONFIG_SOC_MPI_OPERATIONS_NUM=y +CONFIG_SOC_RSA_MAX_BIT_LEN=4096 +CONFIG_SOC_AES_SUPPORT_AES_128=y +CONFIG_SOC_AES_SUPPORT_AES_192=y +CONFIG_SOC_AES_SUPPORT_AES_256=y +CONFIG_SOC_SECURE_BOOT_V1=y +CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=y +CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=32 +CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 +CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y +CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y +CONFIG_SOC_PM_SUPPORT_MODEM_PD=y +CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y +CONFIG_SOC_PM_MODEM_PD_BY_SW=y +CONFIG_SOC_CLK_APLL_SUPPORTED=y +CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y +CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y +CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y +CONFIG_SOC_SDMMC_USE_IOMUX=y +CONFIG_SOC_SDMMC_NUM_SLOTS=2 +CONFIG_SOC_WIFI_WAPI_SUPPORT=y +CONFIG_SOC_WIFI_CSI_SUPPORT=y +CONFIG_SOC_WIFI_MESH_SUPPORT=y +CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y +CONFIG_SOC_WIFI_NAN_SUPPORT=y +CONFIG_SOC_BLE_SUPPORTED=y +CONFIG_SOC_BLE_MESH_SUPPORTED=y +CONFIG_SOC_BT_CLASSIC_SUPPORTED=y +CONFIG_SOC_BLUFI_SUPPORTED=y +CONFIG_SOC_BT_H2C_ENC_KEY_CTRL_ENH_VSC_SUPPORTED=y +CONFIG_SOC_ULP_HAS_ADC=y +CONFIG_SOC_PHY_COMBO_MODULE=y +CONFIG_SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK=y +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TOOLCHAIN="gcc" +CONFIG_IDF_TOOLCHAIN_GCC=y +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET_ARCH="xtensa" +CONFIG_IDF_TARGET="esp32" +CONFIG_IDF_INIT_VERSION="5.4.1" +CONFIG_IDF_TARGET_ESP32=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# CONFIG_APP_REPRODUCIBLE_BUILD is not set +# CONFIG_APP_NO_BLOBS is not set +# CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# end of Build type + +# +# Bootloader config +# + +# +# Bootloader manager +# +CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y +CONFIG_BOOTLOADER_PROJECT_VER=1 +# end of Bootloader manager + +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set + +# +# Log +# +# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=3 + +# +# Format +# +# CONFIG_BOOTLOADER_LOG_COLORS is not set +CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y +# end of Format +# end of Log + +# +# Serial Flash Configurations +# +# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +# end of Serial Flash Configurations + +# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_V1_SUPPORTED=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +# end of Security features + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 +# end of Application manager + +CONFIG_ESP_ROM_HAS_CRC_LE=y +CONFIG_ESP_ROM_HAS_CRC_BE=y +CONFIG_ESP_ROM_HAS_MZ_CRC32=y +CONFIG_ESP_ROM_HAS_JPEG_DECODE=y +CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y +CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y +CONFIG_ESP_ROM_HAS_NEWLIB=y +CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y +CONFIG_ESP_ROM_HAS_NEWLIB_32BIT_TIME=y +CONFIG_ESP_ROM_HAS_SW_FLOAT=y +CONFIG_ESP_ROM_USB_OTG_NUM=-1 +CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1 +CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y +CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y + +# +# Serial flasher config +# +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHMODE="dio" +# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="40m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="2MB" +# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set +# CONFIG_PARTITION_TABLE_CUSTOM is not set +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Compiler options +# +CONFIG_COMPILER_OPTIMIZATION_DEBUG=y +# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set +# CONFIG_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y +CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set +CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y +# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +CONFIG_COMPILER_RT_LIB_GCCLIB=y +CONFIG_COMPILER_RT_LIB_NAME="gcc" +CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y +# CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set +# CONFIG_COMPILER_STATIC_ANALYZER is not set +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_JTAG is not set +CONFIG_APPTRACE_DEST_NONE=y +# CONFIG_APPTRACE_DEST_UART1 is not set +# CONFIG_APPTRACE_DEST_UART2 is not set +CONFIG_APPTRACE_DEST_UART_NONE=y +CONFIG_APPTRACE_UART_TASK_PRIO=1 +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# Bluetooth +# +# CONFIG_BT_ENABLED is not set +CONFIG_BT_ALARM_MAX_NUM=50 +# end of Bluetooth + +# +# Console Library +# +# CONFIG_CONSOLE_SORTED_HELP is not set +# end of Console Library + +# +# Driver Configurations +# + +# +# TWAI Configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y +CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y +CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID=y +CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT=y +CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y +# end of TWAI Configuration + +# +# Legacy ADC Driver Configuration +# +CONFIG_ADC_DISABLE_DAC=y +# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set + +# +# Legacy ADC Calibration Configuration +# +CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y +CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CAL_LUT_ENABLE=y +# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy ADC Calibration Configuration +# end of Legacy ADC Driver Configuration + +# +# Legacy DAC Driver Configurations +# +# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy DAC Driver Configurations + +# +# Legacy MCPWM Driver Configurations +# +# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy MCPWM Driver Configurations + +# +# Legacy Timer Group Driver Configurations +# +# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy Timer Group Driver Configurations + +# +# Legacy RMT Driver Configurations +# +# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy RMT Driver Configurations + +# +# Legacy I2S Driver Configurations +# +# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy I2S Driver Configurations + +# +# Legacy PCNT Driver Configurations +# +# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy PCNT Driver Configurations + +# +# Legacy SDM Driver Configurations +# +# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy SDM Driver Configurations +# end of Driver Configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set +CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set +CONFIG_EFUSE_MAX_BLK_LEN=192 +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +# CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set +# CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + +# +# ADC and ADC Calibration +# +# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set + +# +# ADC Calibration Configurations +# +CONFIG_ADC_CALI_EFUSE_TP_ENABLE=y +CONFIG_ADC_CALI_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CALI_LUT_ENABLE=y +# end of ADC Calibration Configurations + +CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# CONFIG_ADC_ENABLE_DEBUG_LOG is not set +# end of ADC and ADC Calibration + +# +# Wireless Coexistence +# +CONFIG_ESP_COEX_ENABLED=y +# CONFIG_ESP_COEX_GPIO_DEBUG is not set +# end of Wireless Coexistence + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# end of Common ESP-related + +# +# ESP-Driver:DAC Configurations +# +# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# CONFIG_DAC_ISR_IRAM_SAFE is not set +# CONFIG_DAC_ENABLE_DEBUG_LOG is not set +CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y +# end of ESP-Driver:DAC Configurations + +# +# ESP-Driver:GPIO Configurations +# +# CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set +# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:GPIO Configurations + +# +# ESP-Driver:GPTimer Configurations +# +CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y +# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:GPTimer Configurations + +# +# ESP-Driver:I2C Configurations +# +# CONFIG_I2C_ISR_IRAM_SAFE is not set +# CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set +# end of ESP-Driver:I2C Configurations + +# +# ESP-Driver:I2S Configurations +# +# CONFIG_I2S_ISR_IRAM_SAFE is not set +# CONFIG_I2S_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:I2S Configurations + +# +# ESP-Driver:LEDC Configurations +# +# CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:LEDC Configurations + +# +# ESP-Driver:MCPWM Configurations +# +# CONFIG_MCPWM_ISR_IRAM_SAFE is not set +# CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:MCPWM Configurations + +# +# ESP-Driver:PCNT Configurations +# +# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_PCNT_ISR_IRAM_SAFE is not set +# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:PCNT Configurations + +# +# ESP-Driver:RMT Configurations +# +# CONFIG_RMT_ISR_IRAM_SAFE is not set +# CONFIG_RMT_RECV_FUNC_IN_IRAM is not set +# CONFIG_RMT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:RMT Configurations + +# +# ESP-Driver:Sigma Delta Modulator Configurations +# +# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_SDM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Sigma Delta Modulator Configurations + +# +# ESP-Driver:SPI Configurations +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of ESP-Driver:SPI Configurations + +# +# ESP-Driver:Touch Sensor Configurations +# +# CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set +# CONFIG_TOUCH_ISR_IRAM_SAFE is not set +# CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Touch Sensor Configurations + +# +# ESP-Driver:UART Configurations +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of ESP-Driver:UART Configurations + +# +# Ethernet +# +CONFIG_ETH_ENABLED=y +CONFIG_ETH_USE_ESP32_EMAC=y +CONFIG_ETH_PHY_INTERFACE_RMII=y +CONFIG_ETH_RMII_CLK_INPUT=y +# CONFIG_ETH_RMII_CLK_OUTPUT is not set +CONFIG_ETH_RMII_CLK_IN_GPIO=0 +CONFIG_ETH_DMA_BUFFER_SIZE=512 +CONFIG_ETH_DMA_RX_BUFFER_NUM=10 +CONFIG_ETH_DMA_TX_BUFFER_NUM=10 +# CONFIG_ETH_IRAM_OPTIMIZATION is not set +CONFIG_ETH_USE_SPI_ETHERNET=y +# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set +# CONFIG_ETH_SPI_ETHERNET_W5500 is not set +# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set +# CONFIG_ETH_USE_OPENETH is not set +# CONFIG_ETH_TRANSMIT_MUTEX is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +CONFIG_ESP_GDBSTUB_ENABLED=y +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set +CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y +CONFIG_ESP_GDBSTUB_MAX_TASKS=32 +# end of GDB Stub + +# +# ESP HID +# +CONFIG_ESPHID_TASK_SIZE_BT=2048 +CONFIG_ESPHID_TASK_SIZE_BLE=4096 +# end of ESP HID + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set +CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 +# end of ESP HTTPS server + +# +# Hardware Settings +# + +# +# Chip revision +# +CONFIG_ESP32_REV_MIN_0=y +# CONFIG_ESP32_REV_MIN_1 is not set +# CONFIG_ESP32_REV_MIN_1_1 is not set +# CONFIG_ESP32_REV_MIN_2 is not set +# CONFIG_ESP32_REV_MIN_3 is not set +# CONFIG_ESP32_REV_MIN_3_1 is not set +CONFIG_ESP32_REV_MIN=0 +CONFIG_ESP32_REV_MIN_FULL=0 +CONFIG_ESP_REV_MIN_FULL=0 + +# +# Maximum Supported ESP32 Revision (Rev v3.99) +# +CONFIG_ESP32_REV_MAX_FULL=399 +CONFIG_ESP_REV_MAX_FULL=399 +CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL=0 +CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL=99 + +# +# Maximum Supported ESP32 eFuse Block Revision (eFuse Block Rev v0.99) +# +# end of Chip revision + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set +# CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set +# end of MAC Config + +# +# Sleep Config +# +# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set +CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +# CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set +CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set +CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 +# CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set +# CONFIG_ESP_SLEEP_DEBUG is not set +CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y +# end of Sleep Config + +# +# RTC Clock Config +# +CONFIG_RTC_CLK_SRC_INT_RC=y +# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_RTC_CLK_CAL_CYCLES=1024 +# end of RTC Clock Config + +# +# Peripheral Control +# +CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y +# end of Peripheral Control + +# +# Main XTAL Config +# +# CONFIG_XTAL_FREQ_26 is not set +# CONFIG_XTAL_FREQ_32 is not set +CONFIG_XTAL_FREQ_40=y +# CONFIG_XTAL_FREQ_AUTO is not set +CONFIG_XTAL_FREQ=40 +# end of Main XTAL Config + +CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y +# end of Hardware Settings + +# +# ESP-Driver:LCD Controller Configurations +# +# CONFIG_LCD_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:LCD Controller Configurations + +# +# ESP-MM: Memory Management Configurations +# +# end of ESP-MM: Memory Management Configurations + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +# CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y +# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# CONFIG_ESP_NETIF_L2_TAP is not set +# CONFIG_ESP_NETIF_BRIDGE_EN is not set +# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set +# end of ESP NETIF Adapter + +# +# Partition API Configuration +# +# end of Partition API Configuration + +# +# PHY +# +CONFIG_ESP_PHY_ENABLED=y +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set +# CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set +CONFIG_ESP_PHY_RF_CAL_PARTIAL=y +# CONFIG_ESP_PHY_RF_CAL_NONE is not set +# CONFIG_ESP_PHY_RF_CAL_FULL is not set +CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# CONFIG_ESP_PHY_RECORD_USED_TIME is not set +# end of PHY + +# +# Power Management +# +# CONFIG_PM_ENABLE is not set +# CONFIG_PM_SLP_IRAM_OPT is not set +# end of Power Management + +# +# ESP PSRAM +# +# CONFIG_SPIRAM is not set +# end of ESP PSRAM + +# +# ESP Ringbuf +# +# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set +# end of ESP Ringbuf + +# +# ESP Security Specific +# +# end of ESP Security Specific + +# +# ESP System Settings +# +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 + +# +# Memory +# +# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set + +# +# Non-backward compatible options +# +# CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set +# end of Non-backward compatible options +# end of Memory + +# +# Trace memory +# +# CONFIG_ESP32_TRAX is not set +CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 +# end of Trace memory + +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 + +# +# Memory protection +# +# end of Memory protection + +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 +CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set +# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_INT_WDT_CHECK_CPU1=y +CONFIG_ESP_TASK_WDT_EN=y +CONFIG_ESP_TASK_WDT_INIT=y +# CONFIG_ESP_TASK_WDT_PANIC is not set +CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP_DEBUG_OCDAWARE=y +# CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y + +# +# Brownout Detector +# +CONFIG_ESP_BROWNOUT_DET=y +CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_ESP_BROWNOUT_DET_LVL=0 +# end of Brownout Detector + +# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set +CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y +# end of ESP System Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y +CONFIG_ESP_IPC_ISR_ENABLE=y +# end of IPC (Inter-Processor Call) + +# +# ESP Timer (High Resolution Timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set +CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 +CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y +CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +CONFIG_ESP_TIMER_IMPL_TG0_LAC=y +# end of ESP Timer (High Resolution Timer) + +# +# Wi-Fi +# +CONFIG_ESP_WIFI_ENABLED=y +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 +CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 +# CONFIG_ESP_WIFI_CSI_ENABLED is not set +CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP_WIFI_TX_BA_WIN=6 +CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP_WIFI_RX_BA_WIN=6 +CONFIG_ESP_WIFI_NVS_ENABLED=y +CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP_WIFI_IRAM_OPT=y +# CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set +CONFIG_ESP_WIFI_RX_IRAM_OPT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP_WIFI_ENABLE_SAE_PK=y +CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 +CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 +CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 +CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y +CONFIG_ESP_WIFI_GMAC_SUPPORT=y +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set +CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# CONFIG_ESP_WIFI_NAN_ENABLE is not set +CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y +CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# CONFIG_ESP_WIFI_WAPI_PSK is not set +# CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# CONFIG_ESP_WIFI_11R_SUPPORT is not set +# CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set + +# +# WPS Configuration Options +# +# CONFIG_ESP_WIFI_WPS_STRICT is not set +# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set +# end of WPS Configuration Options + +# CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set +CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y +# CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set +# end of Wi-Fi + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +CONFIG_FATFS_VOLUME_COUNT=2 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +# CONFIG_FATFS_SECTOR_512 is not set +CONFIG_FATFS_SECTOR_4096=y +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_USE_STRFUNC_NONE=y +# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set +# CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# CONFIG_FATFS_IMMEDIATE_FSYNC is not set +# CONFIG_FATFS_USE_LABEL is not set +CONFIG_FATFS_LINK_LOCK=y +# end of FAT Filesystem support + +# +# FreeRTOS +# + +# +# Kernel +# +# CONFIG_FREERTOS_SMP is not set +# CONFIG_FREERTOS_UNICORE is not set +CONFIG_FREERTOS_HZ=1000 +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +# CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# CONFIG_FREERTOS_USE_TICK_HOOK is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_USE_TIMERS=y +CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set +CONFIG_FREERTOS_TIMER_TASK_NO_AFFINITY=y +CONFIG_FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set +# end of Kernel + +# +# Port +# +CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# CONFIG_FREERTOS_FPU_IN_ISR is not set +CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# end of Port + +# +# Extra +# +# end of Extra + +CONFIG_FREERTOS_PORT=y +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y +CONFIG_FREERTOS_NUMBER_OF_CORES=2 +# end of FreeRTOS + +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILENT is not set +# CONFIG_HAL_ASSERTION_ENABLE is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 +CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y +CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_USE_HOOKS is not set +# CONFIG_HEAP_TASK_TRACKING is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set +# end of Heap memory debugging + +# +# Log +# + +# +# Log Level +# +# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +CONFIG_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=3 +CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=3 + +# +# Level Settings +# +# CONFIG_LOG_MASTER_LEVEL is not set +CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y +# CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set +# CONFIG_LOG_TAG_LEVEL_IMPL_LINKED_LIST is not set +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_AND_LINKED_LIST=y +# CONFIG_LOG_TAG_LEVEL_CACHE_ARRAY is not set +CONFIG_LOG_TAG_LEVEL_CACHE_BINARY_MIN_HEAP=y +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 +# end of Level Settings +# end of Log Level + +# +# Format +# +# CONFIG_LOG_COLORS is not set +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Format +# end of Log + +# +# LWIP +# +CONFIG_LWIP_ENABLE=y +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# CONFIG_LWIP_NETIF_API is not set +CONFIG_LWIP_TCPIP_TASK_PRIO=18 +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_ND6=y +# CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# CONFIG_LWIP_SO_RCVBUF is not set +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP_DEFAULT_TTL=64 +CONFIG_LWIP_IP4_FRAG=y +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +# CONFIG_LWIP_IP6_REASSEMBLY is not set +CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_ESP_MLDV6_REPORT=y +CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set +# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 +CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 + +# +# DHCP server +# +CONFIG_LWIP_DHCPS=y +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y +CONFIG_LWIP_DHCPS_ADD_DNS=y +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV4=y +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5760 +CONFIG_LWIP_TCP_WND_DEFAULT=5760 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 +CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 +CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 +CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 +# CONFIG_LWIP_PPP_SUPPORT is not set +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +CONFIG_LWIP_SNTP_STARTUP_DELAY=y +CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 +# end of SNTP + +# +# DNS +# +CONFIG_LWIP_DNS_MAX_HOST_IP=1 +CONFIG_LWIP_DNS_MAX_SERVERS=3 +# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set +# CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set +# end of DNS + +CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y +# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set +CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y +# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set +# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_NONE=y +# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_CUSTOM is not set +# CONFIG_LWIP_HOOK_IP6_INPUT_NONE is not set +CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y +# CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set + +# +# mbedTLS v3.x related +# +# CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set +# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set +CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y +CONFIG_MBEDTLS_PKCS7_C=y +# end of mbedTLS v3.x related + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y +# CONFIG_MBEDTLS_SHA3_C is not set +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +CONFIG_MBEDTLS_PSK_MODES=y +CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y +CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y +# CONFIG_MBEDTLS_DHM_C is not set +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +CONFIG_MBEDTLS_ERROR_STRINGS=y +CONFIG_MBEDTLS_FS_IO=y +# end of mbedTLS + +# +# ESP-MQTT Configurations +# +CONFIG_MQTT_PROTOCOL_311=y +# CONFIG_MQTT_PROTOCOL_5 is not set +CONFIG_MQTT_TRANSPORT_SSL=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set +# end of Newlib + +# +# NVS +# +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set +# end of NVS + +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set + +# +# OpenThread Spinel +# +# CONFIG_OPENTHREAD_SPINEL_ONLY is not set +# end of OpenThread Spinel +# end of OpenThread + +# +# Protocomm +# +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_PATCH_VERSION=y +# end of Protocomm + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y +# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set +# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# MMU Config +# +CONFIG_MMU_PAGE_SIZE_64KB=y +CONFIG_MMU_PAGE_MODE="64KB" +CONFIG_MMU_PAGE_SIZE=0x10000 +# end of MMU Config + +# +# Main Flash configuration +# + +# +# SPI Flash behavior when brownout +# +CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y +CONFIG_SPI_FLASH_BROWNOUT_RESET=y +# end of SPI Flash behavior when brownout + +# +# Optional and Experimental Features (READ DOCS FIRST) +# + +# +# Features here require specific hardware (READ DOCS FIRST!) +# +CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 +# CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set +# end of Optional and Experimental Features (READ DOCS FIRST) +# end of Main Flash configuration + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y +CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +CONFIG_WS_TRANSPORT=y +CONFIG_WS_BUFFER_SIZE=1024 +# CONFIG_WS_DYNAMIC_BUFFER is not set +# end of Websocket +# end of TCP Transport + +# +# Ultra Low Power (ULP) Co-processor +# +# CONFIG_ULP_COPROC_ENABLED is not set + +# +# ULP Debugging Options +# +# end of ULP Debugging Options +# end of Ultra Low Power (ULP) Co-processor + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_64BIT is not set +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +# CONFIG_VFS_SELECT_IN_RAM is not set +CONFIG_VFS_SUPPORT_TERMIOS=y +CONFIG_VFS_MAX_COUNT=8 + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# end of Host File System I/O (Semihosting) + +CONFIG_VFS_INITIALIZE_DEV_NULL=y +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y +# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set +# end of Wi-Fi Provisioning Manager +# end of Component config + +# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set + +# Deprecated options for backward compatibility +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# CONFIG_NO_BLOBS is not set +# CONFIG_ESP32_NO_BLOBS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=3 +# CONFIG_APP_ROLLBACK_ENABLE is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +# CONFIG_FLASHMODE_QIO is not set +# CONFIG_FLASHMODE_QOUT is not set +CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DOUT is not set +CONFIG_MONITOR_BAUD=115200 +CONFIG_OPTIMIZATION_LEVEL_DEBUG=y +CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y +CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y +# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_ADC2_DISABLE_DAC=y +# CONFIG_MCPWM_ISR_IN_IRAM is not set +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +CONFIG_GDBSTUB_SUPPORT_TASKS=y +CONFIG_GDBSTUB_MAX_TASKS=32 +# CONFIG_OTA_ALLOW_HTTP is not set +# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set +CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y +CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 +# CONFIG_ESP_SYSTEM_PD_FLASH is not set +CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y +CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y +# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set +# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set +# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set +CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 +# CONFIG_ESP32_XTAL_FREQ_26 is not set +CONFIG_ESP32_XTAL_FREQ_40=y +# CONFIG_ESP32_XTAL_FREQ_AUTO is not set +CONFIG_ESP32_XTAL_FREQ=40 +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# CONFIG_REDUCE_PHY_TX_POWER is not set +# CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set +# CONFIG_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y +# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160 +CONFIG_TRACEMEM_RESERVE_DRAM=0x0 +# CONFIG_ESP32_PANIC_PRINT_HALT is not set +CONFIG_ESP32_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32_PANIC_GDBSTUB is not set +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=3584 +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_CONSOLE_UART_NONE is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +CONFIG_INT_WDT_CHECK_CPU1=y +CONFIG_TASK_WDT=y +CONFIG_ESP_TASK_WDT=y +# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_TIMEOUT_S=5 +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP32_DEBUG_OCDAWARE=y +CONFIG_BROWNOUT_DET=y +CONFIG_ESP32_BROWNOUT_DET=y +CONFIG_BROWNOUT_DET_LVL_SEL_0=y +CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_BROWNOUT_DET_LVL=0 +CONFIG_ESP32_BROWNOUT_DET_LVL=0 +# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set +CONFIG_IPC_TASK_STACK_SIZE=1024 +CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y +CONFIG_WPA_MBEDTLS_CRYPTO=y +CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# CONFIG_WPA_MBO_SUPPORT is not set +# CONFIG_WPA_DPP_SUPPORT is not set +# CONFIG_WPA_11R_SUPPORT is not set +# CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set +# CONFIG_L2_TO_L3_COPY is not set +CONFIG_ESP_GRATUITOUS_ARP=y +CONFIG_GARP_TMR_INTERVAL=60 +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5760 +CONFIG_TCP_WND_DEFAULT=5760 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_HRT is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +# CONFIG_ESP32_ULP_COPROC_ENABLED is not set +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# End of deprecated options diff --git a/sdkconfig.release b/sdkconfig.release new file mode 100644 index 00000000..6aa2dd4c --- /dev/null +++ b/sdkconfig.release @@ -0,0 +1,2548 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) 5.4.1 Project Configuration +# +CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined" +CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined" +CONFIG_SOC_DPORT_WORKAROUND="Not determined" +CONFIG_SOC_CAPS_ECO_VER_MAX=301 +CONFIG_SOC_ADC_SUPPORTED=y +CONFIG_SOC_DAC_SUPPORTED=y +CONFIG_SOC_UART_SUPPORTED=y +CONFIG_SOC_MCPWM_SUPPORTED=y +CONFIG_SOC_GPTIMER_SUPPORTED=y +CONFIG_SOC_SDMMC_HOST_SUPPORTED=y +CONFIG_SOC_BT_SUPPORTED=y +CONFIG_SOC_PCNT_SUPPORTED=y +CONFIG_SOC_PHY_SUPPORTED=y +CONFIG_SOC_WIFI_SUPPORTED=y +CONFIG_SOC_SDIO_SLAVE_SUPPORTED=y +CONFIG_SOC_TWAI_SUPPORTED=y +CONFIG_SOC_EFUSE_SUPPORTED=y +CONFIG_SOC_EMAC_SUPPORTED=y +CONFIG_SOC_ULP_SUPPORTED=y +CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y +CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y +CONFIG_SOC_RTC_MEM_SUPPORTED=y +CONFIG_SOC_I2S_SUPPORTED=y +CONFIG_SOC_RMT_SUPPORTED=y +CONFIG_SOC_SDM_SUPPORTED=y +CONFIG_SOC_GPSPI_SUPPORTED=y +CONFIG_SOC_LEDC_SUPPORTED=y +CONFIG_SOC_I2C_SUPPORTED=y +CONFIG_SOC_SUPPORT_COEXISTENCE=y +CONFIG_SOC_AES_SUPPORTED=y +CONFIG_SOC_MPI_SUPPORTED=y +CONFIG_SOC_SHA_SUPPORTED=y +CONFIG_SOC_FLASH_ENC_SUPPORTED=y +CONFIG_SOC_SECURE_BOOT_SUPPORTED=y +CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y +CONFIG_SOC_BOD_SUPPORTED=y +CONFIG_SOC_ULP_FSM_SUPPORTED=y +CONFIG_SOC_CLK_TREE_SUPPORTED=y +CONFIG_SOC_MPU_SUPPORTED=y +CONFIG_SOC_WDT_SUPPORTED=y +CONFIG_SOC_SPI_FLASH_SUPPORTED=y +CONFIG_SOC_RNG_SUPPORTED=y +CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y +CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y +CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y +CONFIG_SOC_PM_SUPPORTED=y +CONFIG_SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL=5 +CONFIG_SOC_XTAL_SUPPORT_26M=y +CONFIG_SOC_XTAL_SUPPORT_40M=y +CONFIG_SOC_XTAL_SUPPORT_AUTO_DETECT=y +CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DMA_SUPPORTED=y +CONFIG_SOC_ADC_PERIPH_NUM=2 +CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 +CONFIG_SOC_ADC_ATTEN_NUM=4 +CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 +CONFIG_SOC_ADC_PATT_LEN_MAX=16 +CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 +CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=4 +CONFIG_SOC_ADC_DIGI_MONITOR_NUM=0 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=2 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=20 +CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_SHARED_POWER=y +CONFIG_SOC_SHARED_IDCACHE_SUPPORTED=y +CONFIG_SOC_IDCACHE_PER_CORE=y +CONFIG_SOC_CPU_CORES_NUM=2 +CONFIG_SOC_CPU_INTR_NUM=32 +CONFIG_SOC_CPU_HAS_FPU=y +CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y +CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 +CONFIG_SOC_DAC_CHAN_NUM=2 +CONFIG_SOC_DAC_RESOLUTION=8 +CONFIG_SOC_DAC_DMA_16BIT_ALIGN=y +CONFIG_SOC_GPIO_PORT=1 +CONFIG_SOC_GPIO_PIN_COUNT=40 +CONFIG_SOC_GPIO_VALID_GPIO_MASK=0xFFFFFFFFFF +CONFIG_SOC_GPIO_IN_RANGE_MAX=39 +CONFIG_SOC_GPIO_OUT_RANGE_MAX=33 +CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0xEF0FEA +CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y +CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3 +CONFIG_SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP=y +CONFIG_SOC_I2C_NUM=2 +CONFIG_SOC_HP_I2C_NUM=2 +CONFIG_SOC_I2C_FIFO_LEN=32 +CONFIG_SOC_I2C_CMD_REG_NUM=16 +CONFIG_SOC_I2C_SUPPORT_SLAVE=y +CONFIG_SOC_I2C_SUPPORT_APB=y +CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR=y +CONFIG_SOC_I2C_STOP_INDEPENDENT=y +CONFIG_SOC_I2S_NUM=2 +CONFIG_SOC_I2S_HW_VERSION_1=y +CONFIG_SOC_I2S_SUPPORTS_APLL=y +CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y +CONFIG_SOC_I2S_SUPPORTS_PDM=y +CONFIG_SOC_I2S_SUPPORTS_PDM_TX=y +CONFIG_SOC_I2S_PDM_MAX_TX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_PDM_RX=y +CONFIG_SOC_I2S_PDM_MAX_RX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_ADC_DAC=y +CONFIG_SOC_I2S_SUPPORTS_ADC=y +CONFIG_SOC_I2S_SUPPORTS_DAC=y +CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y +CONFIG_SOC_I2S_MAX_DATA_WIDTH=24 +CONFIG_SOC_I2S_TRANS_SIZE_ALIGN_WORD=y +CONFIG_SOC_I2S_LCD_I80_VARIANT=y +CONFIG_SOC_LCD_I80_SUPPORTED=y +CONFIG_SOC_LCD_I80_BUSES=2 +CONFIG_SOC_LCD_I80_BUS_WIDTH=24 +CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y +CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y +CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y +CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y +CONFIG_SOC_LEDC_TIMER_NUM=4 +CONFIG_SOC_LEDC_CHANNEL_NUM=8 +CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=20 +CONFIG_SOC_MCPWM_GROUPS=2 +CONFIG_SOC_MCPWM_TIMERS_PER_GROUP=3 +CONFIG_SOC_MCPWM_OPERATORS_PER_GROUP=3 +CONFIG_SOC_MCPWM_COMPARATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GENERATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_TRIGGERS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GPIO_FAULTS_PER_GROUP=3 +CONFIG_SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP=y +CONFIG_SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER=3 +CONFIG_SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP=3 +CONFIG_SOC_MMU_PERIPH_NUM=2 +CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=3 +CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 +CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 +CONFIG_SOC_PCNT_GROUPS=1 +CONFIG_SOC_PCNT_UNITS_PER_GROUP=8 +CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 +CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 +CONFIG_SOC_RMT_GROUPS=1 +CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_CHANNELS_PER_GROUP=8 +CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 +CONFIG_SOC_RMT_SUPPORT_REF_TICK=y +CONFIG_SOC_RMT_SUPPORT_APB=y +CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y +CONFIG_SOC_RTCIO_PIN_COUNT=18 +CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y +CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y +CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_SDM_GROUPS=1 +CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 +CONFIG_SOC_SDM_CLK_SUPPORT_APB=y +CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y +CONFIG_SOC_SPI_AS_CS_SUPPORTED=y +CONFIG_SOC_SPI_PERIPH_NUM=3 +CONFIG_SOC_SPI_DMA_CHAN_NUM=2 +CONFIG_SOC_SPI_MAX_CS_NUM=3 +CONFIG_SOC_SPI_SUPPORT_CLK_APB=y +CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=64 +CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 +CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y +CONFIG_SOC_TIMER_GROUPS=2 +CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 +CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 +CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y +CONFIG_SOC_LP_TIMER_BIT_WIDTH_LO=32 +CONFIG_SOC_LP_TIMER_BIT_WIDTH_HI=16 +CONFIG_SOC_TOUCH_SENSOR_VERSION=1 +CONFIG_SOC_TOUCH_SENSOR_NUM=10 +CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1 +CONFIG_SOC_TWAI_CONTROLLER_NUM=1 +CONFIG_SOC_TWAI_BRP_MIN=2 +CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y +CONFIG_SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT=y +CONFIG_SOC_UART_NUM=3 +CONFIG_SOC_UART_HP_NUM=3 +CONFIG_SOC_UART_SUPPORT_APB_CLK=y +CONFIG_SOC_UART_SUPPORT_REF_TICK=y +CONFIG_SOC_UART_FIFO_LEN=128 +CONFIG_SOC_UART_BITRATE_MAX=5000000 +CONFIG_SOC_SPIRAM_SUPPORTED=y +CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y +CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG=y +CONFIG_SOC_SHA_ENDIANNESS_BE=y +CONFIG_SOC_SHA_SUPPORT_SHA1=y +CONFIG_SOC_SHA_SUPPORT_SHA256=y +CONFIG_SOC_SHA_SUPPORT_SHA384=y +CONFIG_SOC_SHA_SUPPORT_SHA512=y +CONFIG_SOC_MPI_MEM_BLOCKS_NUM=4 +CONFIG_SOC_MPI_OPERATIONS_NUM=y +CONFIG_SOC_RSA_MAX_BIT_LEN=4096 +CONFIG_SOC_AES_SUPPORT_AES_128=y +CONFIG_SOC_AES_SUPPORT_AES_192=y +CONFIG_SOC_AES_SUPPORT_AES_256=y +CONFIG_SOC_SECURE_BOOT_V1=y +CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=y +CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=32 +CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 +CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y +CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y +CONFIG_SOC_PM_SUPPORT_MODEM_PD=y +CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y +CONFIG_SOC_PM_MODEM_PD_BY_SW=y +CONFIG_SOC_CLK_APLL_SUPPORTED=y +CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y +CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y +CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y +CONFIG_SOC_SDMMC_USE_IOMUX=y +CONFIG_SOC_SDMMC_NUM_SLOTS=2 +CONFIG_SOC_WIFI_WAPI_SUPPORT=y +CONFIG_SOC_WIFI_CSI_SUPPORT=y +CONFIG_SOC_WIFI_MESH_SUPPORT=y +CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y +CONFIG_SOC_WIFI_NAN_SUPPORT=y +CONFIG_SOC_BLE_SUPPORTED=y +CONFIG_SOC_BLE_MESH_SUPPORTED=y +CONFIG_SOC_BT_CLASSIC_SUPPORTED=y +CONFIG_SOC_BLUFI_SUPPORTED=y +CONFIG_SOC_BT_H2C_ENC_KEY_CTRL_ENH_VSC_SUPPORTED=y +CONFIG_SOC_ULP_HAS_ADC=y +CONFIG_SOC_PHY_COMBO_MODULE=y +CONFIG_SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK=y +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TOOLCHAIN="gcc" +CONFIG_IDF_TOOLCHAIN_GCC=y +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET_ARCH="xtensa" +CONFIG_IDF_TARGET="esp32" +CONFIG_IDF_INIT_VERSION="5.4.1" +CONFIG_IDF_TARGET_ESP32=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# CONFIG_APP_REPRODUCIBLE_BUILD is not set +# CONFIG_APP_NO_BLOBS is not set +# CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# end of Build type + +# +# Bootloader config +# + +# +# Bootloader manager +# +CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y +CONFIG_BOOTLOADER_PROJECT_VER=1 +# end of Bootloader manager + +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set + +# +# Log +# +# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=3 + +# +# Format +# +# CONFIG_BOOTLOADER_LOG_COLORS is not set +CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y +# end of Format +# end of Log + +# +# Serial Flash Configurations +# +# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +# end of Serial Flash Configurations + +# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_V1_SUPPORTED=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +# end of Security features + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 +# end of Application manager + +CONFIG_ESP_ROM_HAS_CRC_LE=y +CONFIG_ESP_ROM_HAS_CRC_BE=y +CONFIG_ESP_ROM_HAS_MZ_CRC32=y +CONFIG_ESP_ROM_HAS_JPEG_DECODE=y +CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y +CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y +CONFIG_ESP_ROM_HAS_NEWLIB=y +CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y +CONFIG_ESP_ROM_HAS_NEWLIB_32BIT_TIME=y +CONFIG_ESP_ROM_HAS_SW_FLOAT=y +CONFIG_ESP_ROM_USB_OTG_NUM=-1 +CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1 +CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y +CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y + +# +# Serial flasher config +# +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHMODE="dio" +# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="40m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="2MB" +# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set +# CONFIG_PARTITION_TABLE_CUSTOM is not set +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Arduino Configuration +# +CONFIG_ARDUINO_VARIANT="esp32" +CONFIG_ENABLE_ARDUINO_DEPENDS=y +# CONFIG_AUTOSTART_ARDUINO is not set +# CONFIG_ARDUINO_RUN_CORE0 is not set +CONFIG_ARDUINO_RUN_CORE1=y +# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_RUNNING_CORE=1 +CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 +# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set +CONFIG_ARDUINO_EVENT_RUN_CORE1=y +# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set +CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y +CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=2048 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 +CONFIG_ARDUINO_UDP_RUN_CORE0=y +# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set +# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_UDP_RUNNING_CORE=0 +CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 +# CONFIG_ARDUINO_ISR_IRAM is not set +# CONFIG_DISABLE_HAL_LOCKS is not set + +# +# Debug Log Configuration +# +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE=y +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=0 +# CONFIG_ARDUHAL_LOG_COLORS is not set +# CONFIG_ARDUHAL_ESP_LOG is not set +# end of Debug Log Configuration + +# CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set +CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS=y +CONFIG_ARDUHAL_PARTITION_SCHEME="min_spiffs" +CONFIG_ARDUINO_SELECTIVE_COMPILATION=y +CONFIG_ARDUINO_SELECTIVE_SPI=y +CONFIG_ARDUINO_SELECTIVE_Wire=y +CONFIG_ARDUINO_SELECTIVE_ESP_SR=y +CONFIG_ARDUINO_SELECTIVE_EEPROM=y +# CONFIG_ARDUINO_SELECTIVE_Preferences is not set +# CONFIG_ARDUINO_SELECTIVE_Ticker is not set +CONFIG_ARDUINO_SELECTIVE_Update=y +# CONFIG_ARDUINO_SELECTIVE_Zigbee is not set +CONFIG_ARDUINO_SELECTIVE_FS=y +# CONFIG_ARDUINO_SELECTIVE_SD is not set +# CONFIG_ARDUINO_SELECTIVE_SD_MMC is not set +# CONFIG_ARDUINO_SELECTIVE_SPIFFS is not set +# CONFIG_ARDUINO_SELECTIVE_FFat is not set +CONFIG_ARDUINO_SELECTIVE_LittleFS=y +CONFIG_ARDUINO_SELECTIVE_Network=y +# CONFIG_ARDUINO_SELECTIVE_Ethernet is not set +CONFIG_ARDUINO_SELECTIVE_PPP=y +CONFIG_ARDUINO_SELECTIVE_ArduinoOTA=y +CONFIG_ARDUINO_SELECTIVE_AsyncUDP=y +CONFIG_ARDUINO_SELECTIVE_DNSServer=y +CONFIG_ARDUINO_SELECTIVE_ESPmDNS=y +CONFIG_ARDUINO_SELECTIVE_HTTPClient=y +# CONFIG_ARDUINO_SELECTIVE_Matter is not set +# CONFIG_ARDUINO_SELECTIVE_NetBIOS is not set +CONFIG_ARDUINO_SELECTIVE_WebServer=y +CONFIG_ARDUINO_SELECTIVE_WiFi=y +CONFIG_ARDUINO_SELECTIVE_NetworkClientSecure=y +CONFIG_ARDUINO_SELECTIVE_WiFiProv=y +CONFIG_ARDUINO_SELECTIVE_BLE=y +# CONFIG_ARDUINO_SELECTIVE_BluetoothSerial is not set +CONFIG_ARDUINO_SELECTIVE_SimpleBLE=y +# CONFIG_ARDUINO_SELECTIVE_RainMaker is not set +# CONFIG_ARDUINO_SELECTIVE_OpenThread is not set +# CONFIG_ARDUINO_SELECTIVE_Insights is not set +# end of Arduino Configuration + +# +# Compiler options +# +# CONFIG_COMPILER_OPTIMIZATION_DEBUG is not set +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y +CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set +CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y +# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +CONFIG_COMPILER_RT_LIB_GCCLIB=y +CONFIG_COMPILER_RT_LIB_NAME="gcc" +CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y +# CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set +# CONFIG_COMPILER_STATIC_ANALYZER is not set +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_JTAG is not set +CONFIG_APPTRACE_DEST_NONE=y +# CONFIG_APPTRACE_DEST_UART1 is not set +# CONFIG_APPTRACE_DEST_UART2 is not set +CONFIG_APPTRACE_DEST_UART_NONE=y +CONFIG_APPTRACE_UART_TASK_PRIO=1 +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# Bluetooth +# +CONFIG_BT_ENABLED=y +# CONFIG_BT_BLUEDROID_ENABLED is not set +CONFIG_BT_NIMBLE_ENABLED=y +# CONFIG_BT_CONTROLLER_ONLY is not set +CONFIG_BT_CONTROLLER_ENABLED=y +# CONFIG_BT_CONTROLLER_DISABLED is not set + +# +# NimBLE Options +# +CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y +# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_NONE is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_WARNING is not set +CONFIG_BT_NIMBLE_LOG_LEVEL_INFO=y +# CONFIG_BT_NIMBLE_LOG_LEVEL_DEBUG is not set +CONFIG_BT_NIMBLE_LOG_LEVEL=1 +CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 +CONFIG_BT_NIMBLE_MAX_BONDS=1 +CONFIG_BT_NIMBLE_MAX_CCCDS=1 +CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM=0 +CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y +# CONFIG_BT_NIMBLE_PINNED_TO_CORE_1 is not set +CONFIG_BT_NIMBLE_PINNED_TO_CORE=0 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=4096 +CONFIG_BT_NIMBLE_ROLE_CENTRAL=y +CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y +CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y +CONFIG_BT_NIMBLE_ROLE_OBSERVER=y +# CONFIG_BT_NIMBLE_NVS_PERSIST is not set +# CONFIG_BT_NIMBLE_SMP_ID_RESET is not set +# CONFIG_BT_NIMBLE_SECURITY_ENABLE is not set +# CONFIG_BT_NIMBLE_DEBUG is not set +# CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set +CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" +CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 +CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=256 +CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE=0 + +# +# Memory Settings +# +CONFIG_BT_NIMBLE_MSYS_1_BLOCK_COUNT=12 +CONFIG_BT_NIMBLE_MSYS_1_BLOCK_SIZE=256 +CONFIG_BT_NIMBLE_MSYS_2_BLOCK_COUNT=24 +CONFIG_BT_NIMBLE_MSYS_2_BLOCK_SIZE=320 +CONFIG_BT_NIMBLE_TRANSPORT_ACL_FROM_LL_COUNT=24 +CONFIG_BT_NIMBLE_TRANSPORT_ACL_SIZE=255 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_COUNT=30 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_DISCARD_COUNT=8 +CONFIG_BT_NIMBLE_L2CAP_COC_SDU_BUFF_COUNT=1 +# end of Memory Settings + +CONFIG_BT_NIMBLE_GATT_MAX_PROCS=4 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL=y +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y +CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 +# CONFIG_BT_NIMBLE_MESH is not set +CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y +CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 +# CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set +# CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set +CONFIG_BT_NIMBLE_WHITELIST_SIZE=1 +# CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set +# CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set +CONFIG_BT_NIMBLE_USE_ESP_TIMER=y +CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y +# CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set + +# +# GAP Service +# + +# +# GAP Appearance write permissions +# +# CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set +# end of GAP Appearance write permissions + +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ENC=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHN=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHR=0 +CONFIG_BT_NIMBLE_SVC_GAP_CAR_CHAR_NOT_SUPP=y +# CONFIG_BT_NIMBLE_SVC_GAP_CAR_NOT_SUPP is not set +# CONFIG_BT_NIMBLE_SVC_GAP_CAR_SUPP is not set +CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 + +# +# GAP device name write permissions +# +# CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set +# end of GAP device name write permissions + +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_ENC=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHEN=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHOR=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 +# CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL is not set +# end of GAP Service + +# +# BLE Services +# +# CONFIG_BT_NIMBLE_HID_SERVICE is not set +# CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY is not set + +# +# Device Information Service +# +# CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME is not set +# CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER is not set +# CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION is not set +# CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION is not set +# CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION is not set +# CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID is not set +# CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID is not set +# CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED is not set +# end of Device Information Service +# end of BLE Services + +# CONFIG_BT_NIMBLE_VS_SUPPORT is not set +# CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set +# CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set +# CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set +# CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT is not set + +# +# Host-controller Transport +# +CONFIG_UART_HW_FLOWCTRL_DISABLE=y +# CONFIG_UART_HW_FLOWCTRL_CTS_RTS is not set +CONFIG_BT_NIMBLE_HCI_UART_FLOW_CTRL=0 +CONFIG_BT_NIMBLE_HCI_UART_RTS_PIN=19 +CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 +# end of Host-controller Transport + +CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 +# CONFIG_BT_NIMBLE_SUBRATE is not set +# end of NimBLE Options + +# +# Controller Options +# +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +# CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set +# CONFIG_BTDM_CTRL_MODE_BTDM is not set +CONFIG_BTDM_CTRL_BLE_MAX_CONN=3 +CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 +CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 +CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 +CONFIG_BTDM_CTRL_PCM_FSYNCSHP_EFF=0 +CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=3 +CONFIG_BTDM_CTRL_BR_EDR_MIN_ENC_KEY_SZ_DFT_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CTRL_PINNED_TO_CORE_0=y +# CONFIG_BTDM_CTRL_PINNED_TO_CORE_1 is not set +CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 +CONFIG_BTDM_CTRL_HCI_MODE_VHCI=y +# CONFIG_BTDM_CTRL_HCI_MODE_UART_H4 is not set + +# +# MODEM SLEEP Options +# +CONFIG_BTDM_CTRL_MODEM_SLEEP=y +CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG=y +# CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_EVED is not set +CONFIG_BTDM_CTRL_LPCLK_SEL_MAIN_XTAL=y +# end of MODEM SLEEP Options + +CONFIG_BTDM_BLE_DEFAULT_SCA_250PPM=y +CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 +CONFIG_BTDM_BLE_SCAN_DUPL=y +CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y +# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA is not set +# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE is not set +CONFIG_BTDM_SCAN_DUPL_TYPE=0 +CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 +CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 +# CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set +CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y +# CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set +# CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set +CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y +CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 +CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 + +# +# BLE disconnects when Instant Passed (0x28) occurs +# +# CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set +# CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set +# end of BLE disconnects when Instant Passed (0x28) occurs + +CONFIG_BTDM_BLE_CHAN_ASS_EN=y +CONFIG_BTDM_BLE_PING_EN=y +# CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 is not set +CONFIG_BTDM_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_CTRL_HLI=y +# end of Controller Options + +# +# Common Options +# +CONFIG_BT_ALARM_MAX_NUM=50 +# CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set +# end of Common Options + +# CONFIG_BT_HCI_LOG_DEBUG_EN is not set +# end of Bluetooth + +# CONFIG_BLE_MESH is not set + +# +# Console Library +# +# CONFIG_CONSOLE_SORTED_HELP is not set +# end of Console Library + +# +# Driver Configurations +# + +# +# TWAI Configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y +CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y +CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID=y +CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT=y +CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y +# end of TWAI Configuration + +# +# Legacy ADC Driver Configuration +# +CONFIG_ADC_DISABLE_DAC=y +# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set + +# +# Legacy ADC Calibration Configuration +# +CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y +CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CAL_LUT_ENABLE=y +# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy ADC Calibration Configuration +# end of Legacy ADC Driver Configuration + +# +# Legacy DAC Driver Configurations +# +# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy DAC Driver Configurations + +# +# Legacy MCPWM Driver Configurations +# +# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy MCPWM Driver Configurations + +# +# Legacy Timer Group Driver Configurations +# +# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy Timer Group Driver Configurations + +# +# Legacy RMT Driver Configurations +# +# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy RMT Driver Configurations + +# +# Legacy I2S Driver Configurations +# +# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy I2S Driver Configurations + +# +# Legacy PCNT Driver Configurations +# +# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy PCNT Driver Configurations + +# +# Legacy SDM Driver Configurations +# +# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy SDM Driver Configurations +# end of Driver Configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set +CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set +CONFIG_EFUSE_MAX_BLK_LEN=192 +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +# CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set +# CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + +# +# ADC and ADC Calibration +# +# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set + +# +# ADC Calibration Configurations +# +CONFIG_ADC_CALI_EFUSE_TP_ENABLE=y +CONFIG_ADC_CALI_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CALI_LUT_ENABLE=y +# end of ADC Calibration Configurations + +CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# CONFIG_ADC_ENABLE_DEBUG_LOG is not set +# end of ADC and ADC Calibration + +# +# Wireless Coexistence +# +CONFIG_ESP_COEX_ENABLED=y +CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y +# CONFIG_ESP_COEX_POWER_MANAGEMENT is not set +# CONFIG_ESP_COEX_GPIO_DEBUG is not set +# end of Wireless Coexistence + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# end of Common ESP-related + +# +# ESP-Driver:DAC Configurations +# +# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# CONFIG_DAC_ISR_IRAM_SAFE is not set +# CONFIG_DAC_ENABLE_DEBUG_LOG is not set +CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y +# end of ESP-Driver:DAC Configurations + +# +# ESP-Driver:GPIO Configurations +# +# CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set +# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:GPIO Configurations + +# +# ESP-Driver:GPTimer Configurations +# +CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y +# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:GPTimer Configurations + +# +# ESP-Driver:I2C Configurations +# +# CONFIG_I2C_ISR_IRAM_SAFE is not set +# CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set +# end of ESP-Driver:I2C Configurations + +# +# ESP-Driver:I2S Configurations +# +# CONFIG_I2S_ISR_IRAM_SAFE is not set +# CONFIG_I2S_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:I2S Configurations + +# +# ESP-Driver:LEDC Configurations +# +# CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:LEDC Configurations + +# +# ESP-Driver:MCPWM Configurations +# +# CONFIG_MCPWM_ISR_IRAM_SAFE is not set +# CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:MCPWM Configurations + +# +# ESP-Driver:PCNT Configurations +# +# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_PCNT_ISR_IRAM_SAFE is not set +# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:PCNT Configurations + +# +# ESP-Driver:RMT Configurations +# +# CONFIG_RMT_ISR_IRAM_SAFE is not set +# CONFIG_RMT_RECV_FUNC_IN_IRAM is not set +# CONFIG_RMT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:RMT Configurations + +# +# ESP-Driver:Sigma Delta Modulator Configurations +# +# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_SDM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Sigma Delta Modulator Configurations + +# +# ESP-Driver:SPI Configurations +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of ESP-Driver:SPI Configurations + +# +# ESP-Driver:Touch Sensor Configurations +# +# CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set +# CONFIG_TOUCH_ISR_IRAM_SAFE is not set +# CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Touch Sensor Configurations + +# +# ESP-Driver:UART Configurations +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of ESP-Driver:UART Configurations + +# +# Ethernet +# +# CONFIG_ETH_USE_ESP32_EMAC is not set +# CONFIG_ETH_USE_SPI_ETHERNET is not set +# CONFIG_ETH_USE_OPENETH is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +CONFIG_ESP_GDBSTUB_ENABLED=y +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set +CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y +CONFIG_ESP_GDBSTUB_MAX_TASKS=32 +# end of GDB Stub + +# +# ESP HID +# +CONFIG_ESPHID_TASK_SIZE_BT=2048 +CONFIG_ESPHID_TASK_SIZE_BLE=4096 +# end of ESP HID + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set +CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 +# end of ESP HTTPS server + +# +# Hardware Settings +# + +# +# Chip revision +# +CONFIG_ESP32_REV_MIN_0=y +# CONFIG_ESP32_REV_MIN_1 is not set +# CONFIG_ESP32_REV_MIN_1_1 is not set +# CONFIG_ESP32_REV_MIN_2 is not set +# CONFIG_ESP32_REV_MIN_3 is not set +# CONFIG_ESP32_REV_MIN_3_1 is not set +CONFIG_ESP32_REV_MIN=0 +CONFIG_ESP32_REV_MIN_FULL=0 +CONFIG_ESP_REV_MIN_FULL=0 + +# +# Maximum Supported ESP32 Revision (Rev v3.99) +# +CONFIG_ESP32_REV_MAX_FULL=399 +CONFIG_ESP_REV_MAX_FULL=399 +CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL=0 +CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL=99 + +# +# Maximum Supported ESP32 eFuse Block Revision (eFuse Block Rev v0.99) +# +# end of Chip revision + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set +# CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set +# end of MAC Config + +# +# Sleep Config +# +# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set +CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +# CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set +CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set +CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 +# CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set +# CONFIG_ESP_SLEEP_DEBUG is not set +CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y +# end of Sleep Config + +# +# RTC Clock Config +# +CONFIG_RTC_CLK_SRC_INT_RC=y +# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_RTC_CLK_CAL_CYCLES=1024 +# end of RTC Clock Config + +# +# Peripheral Control +# +CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y +# end of Peripheral Control + +# +# Main XTAL Config +# +# CONFIG_XTAL_FREQ_26 is not set +# CONFIG_XTAL_FREQ_32 is not set +CONFIG_XTAL_FREQ_40=y +# CONFIG_XTAL_FREQ_AUTO is not set +CONFIG_XTAL_FREQ=40 +# end of Main XTAL Config + +CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y +# end of Hardware Settings + +# +# ESP-Driver:LCD Controller Configurations +# +# CONFIG_LCD_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:LCD Controller Configurations + +# +# ESP-MM: Memory Management Configurations +# +# end of ESP-MM: Memory Management Configurations + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +# CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y +# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# CONFIG_ESP_NETIF_L2_TAP is not set +# CONFIG_ESP_NETIF_BRIDGE_EN is not set +# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set +# end of ESP NETIF Adapter + +# +# Partition API Configuration +# +# end of Partition API Configuration + +# +# PHY +# +CONFIG_ESP_PHY_ENABLED=y +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set +# CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set +CONFIG_ESP_PHY_RF_CAL_PARTIAL=y +# CONFIG_ESP_PHY_RF_CAL_NONE is not set +# CONFIG_ESP_PHY_RF_CAL_FULL is not set +CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# CONFIG_ESP_PHY_RECORD_USED_TIME is not set +# end of PHY + +# +# Power Management +# +# CONFIG_PM_ENABLE is not set +# CONFIG_PM_SLP_IRAM_OPT is not set +# end of Power Management + +# +# ESP PSRAM +# +# CONFIG_SPIRAM is not set +# end of ESP PSRAM + +# +# ESP Ringbuf +# +# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set +# end of ESP Ringbuf + +# +# ESP Security Specific +# +# end of ESP Security Specific + +# +# ESP System Settings +# +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 + +# +# Memory +# +# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set + +# +# Non-backward compatible options +# +# CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set +# end of Non-backward compatible options +# end of Memory + +# +# Trace memory +# +# CONFIG_ESP32_TRAX is not set +CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 +# end of Trace memory + +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 + +# +# Memory protection +# +# end of Memory protection + +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 +CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set +# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_INT_WDT_CHECK_CPU1=y +CONFIG_ESP_TASK_WDT_EN=y +CONFIG_ESP_TASK_WDT_INIT=y +# CONFIG_ESP_TASK_WDT_PANIC is not set +CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP_DEBUG_OCDAWARE=y +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y + +# +# Brownout Detector +# +CONFIG_ESP_BROWNOUT_DET=y +CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_ESP_BROWNOUT_DET_LVL=0 +# end of Brownout Detector + +# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set +CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y +# end of ESP System Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y +CONFIG_ESP_IPC_ISR_ENABLE=y +# end of IPC (Inter-Processor Call) + +# +# ESP Timer (High Resolution Timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set +CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 +CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y +CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +CONFIG_ESP_TIMER_IMPL_TG0_LAC=y +# end of ESP Timer (High Resolution Timer) + +# +# Wi-Fi +# +CONFIG_ESP_WIFI_ENABLED=y +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 +CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 +# CONFIG_ESP_WIFI_CSI_ENABLED is not set +CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP_WIFI_TX_BA_WIN=6 +CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP_WIFI_RX_BA_WIN=6 +CONFIG_ESP_WIFI_NVS_ENABLED=y +CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +# CONFIG_ESP_WIFI_IRAM_OPT is not set +# CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set +# CONFIG_ESP_WIFI_RX_IRAM_OPT is not set +CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP_WIFI_ENABLE_SAE_PK=y +CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 +CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 +CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 +CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y +CONFIG_ESP_WIFI_GMAC_SUPPORT=y +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set +CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# CONFIG_ESP_WIFI_NAN_ENABLE is not set +CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y +CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# CONFIG_ESP_WIFI_WAPI_PSK is not set +# CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# CONFIG_ESP_WIFI_11R_SUPPORT is not set +# CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set + +# +# WPS Configuration Options +# +# CONFIG_ESP_WIFI_WPS_STRICT is not set +# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set +# end of WPS Configuration Options + +# CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set +CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y +# CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set +# end of Wi-Fi + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +CONFIG_FATFS_VOLUME_COUNT=2 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +# CONFIG_FATFS_SECTOR_512 is not set +CONFIG_FATFS_SECTOR_4096=y +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_USE_STRFUNC_NONE=y +# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set +# CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# CONFIG_FATFS_IMMEDIATE_FSYNC is not set +# CONFIG_FATFS_USE_LABEL is not set +CONFIG_FATFS_LINK_LOCK=y +# end of FAT Filesystem support + +# +# FreeRTOS +# + +# +# Kernel +# +# CONFIG_FREERTOS_SMP is not set +# CONFIG_FREERTOS_UNICORE is not set +CONFIG_FREERTOS_HZ=1000 +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +# CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# CONFIG_FREERTOS_USE_TICK_HOOK is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_USE_TIMERS=y +CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set +CONFIG_FREERTOS_TIMER_TASK_NO_AFFINITY=y +CONFIG_FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set +# end of Kernel + +# +# Port +# +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# CONFIG_FREERTOS_FPU_IN_ISR is not set +CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# end of Port + +# +# Extra +# +# end of Extra + +CONFIG_FREERTOS_PORT=y +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y +CONFIG_FREERTOS_NUMBER_OF_CORES=2 +# end of FreeRTOS + +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILENT is not set +# CONFIG_HAL_ASSERTION_ENABLE is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 +CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y +CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_USE_HOOKS is not set +# CONFIG_HEAP_TASK_TRACKING is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set +# end of Heap memory debugging + +# +# Log +# + +# +# Log Level +# +CONFIG_LOG_DEFAULT_LEVEL_NONE=y +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=0 +CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_ERROR is not set +# CONFIG_LOG_MAXIMUM_LEVEL_WARN is not set +# CONFIG_LOG_MAXIMUM_LEVEL_INFO is not set +# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=0 + +# +# Level Settings +# +# CONFIG_LOG_MASTER_LEVEL is not set +CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y +# CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set +# CONFIG_LOG_TAG_LEVEL_IMPL_LINKED_LIST is not set +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_AND_LINKED_LIST=y +# CONFIG_LOG_TAG_LEVEL_CACHE_ARRAY is not set +CONFIG_LOG_TAG_LEVEL_CACHE_BINARY_MIN_HEAP=y +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 +# end of Level Settings +# end of Log Level + +# +# Format +# +# CONFIG_LOG_COLORS is not set +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Format +# end of Log + +# +# LWIP +# +CONFIG_LWIP_ENABLE=y +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# CONFIG_LWIP_NETIF_API is not set +CONFIG_LWIP_TCPIP_TASK_PRIO=18 +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_ND6=y +# CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +CONFIG_LWIP_SO_RCVBUF=y +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP_DEFAULT_TTL=64 +CONFIG_LWIP_IP4_FRAG=y +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +# CONFIG_LWIP_IP6_REASSEMBLY is not set +CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_ESP_MLDV6_REPORT=y +CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set +# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 +CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 + +# +# DHCP server +# +CONFIG_LWIP_DHCPS=y +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y +CONFIG_LWIP_DHCPS_ADD_DNS=y +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV4=y +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5760 +CONFIG_LWIP_TCP_WND_DEFAULT=5760 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 +CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 +CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 +CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 +# CONFIG_LWIP_PPP_SUPPORT is not set +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +CONFIG_LWIP_SNTP_STARTUP_DELAY=y +CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 +# end of SNTP + +# +# DNS +# +CONFIG_LWIP_DNS_MAX_HOST_IP=1 +CONFIG_LWIP_DNS_MAX_SERVERS=3 +# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set +# CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set +# end of DNS + +CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y +# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set +CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y +# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set +# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_NONE=y +# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_CUSTOM is not set +# CONFIG_LWIP_HOOK_IP6_INPUT_NONE is not set +CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y +# CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set + +# +# mbedTLS v3.x related +# +# CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set +# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set +CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y +CONFIG_MBEDTLS_PKCS7_C=y +# end of mbedTLS v3.x related + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y +# CONFIG_MBEDTLS_SHA3_C is not set +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +CONFIG_MBEDTLS_PSK_MODES=y +CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y +CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y +# CONFIG_MBEDTLS_DHM_C is not set +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +CONFIG_MBEDTLS_ERROR_STRINGS=y +CONFIG_MBEDTLS_FS_IO=y +# end of mbedTLS + +# +# ESP-MQTT Configurations +# +# CONFIG_MQTT_PROTOCOL_311 is not set +# CONFIG_MQTT_PROTOCOL_5 is not set +# CONFIG_MQTT_TRANSPORT_SSL is not set +# CONFIG_MQTT_TRANSPORT_WEBSOCKET is not set +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set +# end of Newlib + +# +# NVS +# +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set +# end of NVS + +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set + +# +# OpenThread Spinel +# +# CONFIG_OPENTHREAD_SPINEL_ONLY is not set +# end of OpenThread Spinel +# end of OpenThread + +# +# Protocomm +# +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_PATCH_VERSION=y +# end of Protocomm + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y +# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set +# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# MMU Config +# +CONFIG_MMU_PAGE_SIZE_64KB=y +CONFIG_MMU_PAGE_MODE="64KB" +CONFIG_MMU_PAGE_SIZE=0x10000 +# end of MMU Config + +# +# Main Flash configuration +# + +# +# SPI Flash behavior when brownout +# +CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y +CONFIG_SPI_FLASH_BROWNOUT_RESET=y +# end of SPI Flash behavior when brownout + +# +# Optional and Experimental Features (READ DOCS FIRST) +# + +# +# Features here require specific hardware (READ DOCS FIRST!) +# +CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 +# CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set +# end of Optional and Experimental Features (READ DOCS FIRST) +# end of Main Flash configuration + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y +CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +CONFIG_WS_TRANSPORT=y +CONFIG_WS_BUFFER_SIZE=1024 +# CONFIG_WS_DYNAMIC_BUFFER is not set +# end of Websocket +# end of TCP Transport + +# +# Ultra Low Power (ULP) Co-processor +# +# CONFIG_ULP_COPROC_ENABLED is not set + +# +# ULP Debugging Options +# +# end of ULP Debugging Options +# end of Ultra Low Power (ULP) Co-processor + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_64BIT is not set +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +# CONFIG_VFS_SELECT_IN_RAM is not set +CONFIG_VFS_SUPPORT_TERMIOS=y +CONFIG_VFS_MAX_COUNT=8 + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# end of Host File System I/O (Semihosting) + +CONFIG_VFS_INITIALIZE_DEV_NULL=y +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_WIFI_PROV_BLE_BONDING is not set +CONFIG_WIFI_PROV_BLE_SEC_CONN=y +# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set +# CONFIG_WIFI_PROV_BLE_NOTIFY is not set +# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set +CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y +# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set +# end of Wi-Fi Provisioning Manager + +# +# Zigbee +# +# CONFIG_ZB_ENABLED is not set +# end of Zigbee + +# +# mDNS +# +CONFIG_MDNS_MAX_INTERFACES=3 +CONFIG_MDNS_MAX_SERVICES=10 +CONFIG_MDNS_TASK_PRIORITY=1 +CONFIG_MDNS_ACTION_QUEUE_LEN=16 +CONFIG_MDNS_TASK_STACK_SIZE=4096 +# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_MDNS_TASK_AFFINITY_CPU0=y +# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set +CONFIG_MDNS_TASK_AFFINITY=0x0 + +# +# MDNS Memory Configuration +# +CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y +CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y +# CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set +# end of MDNS Memory Configuration + +CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 +CONFIG_MDNS_TIMER_PERIOD_MS=100 +# CONFIG_MDNS_NETWORKING_SOCKET is not set +# CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set +# CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set +CONFIG_MDNS_ENABLE_CONSOLE_CLI=y +# CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set +CONFIG_MDNS_MULTIPLE_INSTANCE=y + +# +# MDNS Predefined interfaces +# +CONFIG_MDNS_PREDEF_NETIF_STA=y +CONFIG_MDNS_PREDEF_NETIF_AP=y +# end of MDNS Predefined interfaces +# end of mDNS + +# +# Network Provisioning Manager +# +CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y +CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_NETWORK_PROV_BLE_BONDING is not set +CONFIG_NETWORK_PROV_BLE_SEC_CONN=y +# CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set +# CONFIG_NETWORK_PROV_KEEP_BLE_ON_AFTER_PROV is not set +CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y +# CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set +# end of Network Provisioning Manager + +# +# LittleFS +# +# CONFIG_LITTLEFS_SDMMC_SUPPORT is not set +CONFIG_LITTLEFS_MAX_PARTITIONS=3 +CONFIG_LITTLEFS_PAGE_SIZE=256 +CONFIG_LITTLEFS_OBJ_NAME_LEN=64 +CONFIG_LITTLEFS_READ_SIZE=128 +CONFIG_LITTLEFS_WRITE_SIZE=128 +CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 +CONFIG_LITTLEFS_CACHE_SIZE=512 +CONFIG_LITTLEFS_BLOCK_CYCLES=512 +CONFIG_LITTLEFS_USE_MTIME=y +# CONFIG_LITTLEFS_USE_ONLY_HASH is not set +# CONFIG_LITTLEFS_HUMAN_READABLE is not set +CONFIG_LITTLEFS_MTIME_USE_SECONDS=y +# CONFIG_LITTLEFS_MTIME_USE_NONCE is not set +# CONFIG_LITTLEFS_SPIFFS_COMPAT is not set +# CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set +# CONFIG_LITTLEFS_FCNTL_GET_PATH is not set +# CONFIG_LITTLEFS_MULTIVERSION is not set +# CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set +CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y +# CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set +CONFIG_LITTLEFS_ASSERTS=y +# CONFIG_LITTLEFS_MMAP_PARTITION is not set +# end of LittleFS +# end of Component config + +# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set + +# Deprecated options for backward compatibility +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# CONFIG_NO_BLOBS is not set +# CONFIG_ESP32_NO_BLOBS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=3 +# CONFIG_APP_ROLLBACK_ENABLE is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +# CONFIG_FLASHMODE_QIO is not set +# CONFIG_FLASHMODE_QOUT is not set +CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DOUT is not set +CONFIG_MONITOR_BAUD=115200 +# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set +CONFIG_OPTIMIZATION_LEVEL_RELEASE=y +CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +# CONFIG_BLUEDROID_ENABLED is not set +CONFIG_NIMBLE_ENABLED=y +CONFIG_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y +# CONFIG_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set +CONFIG_NIMBLE_MAX_CONNECTIONS=7 +CONFIG_NIMBLE_MAX_BONDS=1 +CONFIG_NIMBLE_MAX_CCCDS=1 +CONFIG_NIMBLE_L2CAP_COC_MAX_NUM=0 +CONFIG_NIMBLE_PINNED_TO_CORE_0=y +# CONFIG_NIMBLE_PINNED_TO_CORE_1 is not set +CONFIG_NIMBLE_PINNED_TO_CORE=0 +CONFIG_NIMBLE_TASK_STACK_SIZE=4096 +CONFIG_BT_NIMBLE_TASK_STACK_SIZE=4096 +CONFIG_NIMBLE_ROLE_CENTRAL=y +CONFIG_NIMBLE_ROLE_PERIPHERAL=y +CONFIG_NIMBLE_ROLE_BROADCASTER=y +CONFIG_NIMBLE_ROLE_OBSERVER=y +# CONFIG_NIMBLE_NVS_PERSIST is not set +# CONFIG_NIMBLE_DEBUG is not set +CONFIG_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" +CONFIG_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 +CONFIG_NIMBLE_ATT_PREFERRED_MTU=256 +CONFIG_NIMBLE_SVC_GAP_APPEARANCE=0 +CONFIG_BT_NIMBLE_MSYS1_BLOCK_COUNT=12 +CONFIG_BT_NIMBLE_ACL_BUF_COUNT=24 +CONFIG_BT_NIMBLE_ACL_BUF_SIZE=255 +CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70 +CONFIG_BT_NIMBLE_HCI_EVT_HI_BUF_COUNT=30 +CONFIG_BT_NIMBLE_HCI_EVT_LO_BUF_COUNT=8 +CONFIG_NIMBLE_HS_FLOW_CTRL=y +CONFIG_NIMBLE_HS_FLOW_CTRL_ITVL=1000 +CONFIG_NIMBLE_HS_FLOW_CTRL_THRESH=2 +CONFIG_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y +CONFIG_NIMBLE_RPA_TIMEOUT=900 +# CONFIG_NIMBLE_MESH is not set +CONFIG_NIMBLE_CRYPTO_STACK_MBEDTLS=y +CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y +# CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY is not set +# CONFIG_BTDM_CONTROLLER_MODE_BTDM is not set +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=3 +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=3 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 +CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI=y +# CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4 is not set +CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=y +CONFIG_BLE_SCAN_DUPLICATE=y +CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y +# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA is not set +# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR is not set +CONFIG_SCAN_DUPLICATE_TYPE=0 +CONFIG_DUPLICATE_SCAN_CACHE_SIZE=100 +# CONFIG_BLE_MESH_SCAN_DUPLICATE_EN is not set +CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y +CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED=y +CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM=100 +CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 +CONFIG_ADC2_DISABLE_DAC=y +CONFIG_SW_COEXIST_ENABLE=y +CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y +CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y +# CONFIG_MCPWM_ISR_IN_IRAM is not set +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +CONFIG_GDBSTUB_SUPPORT_TASKS=y +CONFIG_GDBSTUB_MAX_TASKS=32 +# CONFIG_OTA_ALLOW_HTTP is not set +# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set +CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y +CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 +# CONFIG_ESP_SYSTEM_PD_FLASH is not set +CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y +CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y +# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set +# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set +# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set +CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 +# CONFIG_ESP32_XTAL_FREQ_26 is not set +CONFIG_ESP32_XTAL_FREQ_40=y +# CONFIG_ESP32_XTAL_FREQ_AUTO is not set +CONFIG_ESP32_XTAL_FREQ=40 +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# CONFIG_REDUCE_PHY_TX_POWER is not set +# CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set +# CONFIG_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y +# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160 +CONFIG_TRACEMEM_RESERVE_DRAM=0x0 +# CONFIG_ESP32_PANIC_PRINT_HALT is not set +CONFIG_ESP32_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32_PANIC_GDBSTUB is not set +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=3584 +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_CONSOLE_UART_NONE is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +CONFIG_INT_WDT_CHECK_CPU1=y +CONFIG_TASK_WDT=y +CONFIG_ESP_TASK_WDT=y +# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_TIMEOUT_S=5 +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP32_DEBUG_OCDAWARE=y +CONFIG_BROWNOUT_DET=y +CONFIG_ESP32_BROWNOUT_DET=y +CONFIG_BROWNOUT_DET_LVL_SEL_0=y +CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_BROWNOUT_DET_LVL=0 +CONFIG_ESP32_BROWNOUT_DET_LVL=0 +# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set +CONFIG_IPC_TASK_STACK_SIZE=1024 +CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +# CONFIG_ESP32_WIFI_IRAM_OPT is not set +# CONFIG_ESP32_WIFI_RX_IRAM_OPT is not set +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y +CONFIG_WPA_MBEDTLS_CRYPTO=y +CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# CONFIG_WPA_MBO_SUPPORT is not set +# CONFIG_WPA_DPP_SUPPORT is not set +# CONFIG_WPA_11R_SUPPORT is not set +# CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set +# CONFIG_L2_TO_L3_COPY is not set +CONFIG_ESP_GRATUITOUS_ARP=y +CONFIG_GARP_TMR_INTERVAL=60 +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5760 +CONFIG_TCP_WND_DEFAULT=5760 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_HRT is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +# CONFIG_ESP32_ULP_COPROC_ENABLED is not set +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# End of deprecated options diff --git a/sdkconfig.release.old b/sdkconfig.release.old new file mode 100644 index 00000000..8017e96b --- /dev/null +++ b/sdkconfig.release.old @@ -0,0 +1,2197 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) 5.3.2 Project Configuration +# +CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined" +CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined" +CONFIG_SOC_DPORT_WORKAROUND="Not determined" +CONFIG_SOC_CAPS_ECO_VER_MAX=301 +CONFIG_SOC_ADC_SUPPORTED=y +CONFIG_SOC_DAC_SUPPORTED=y +CONFIG_SOC_UART_SUPPORTED=y +CONFIG_SOC_MCPWM_SUPPORTED=y +CONFIG_SOC_GPTIMER_SUPPORTED=y +CONFIG_SOC_SDMMC_HOST_SUPPORTED=y +CONFIG_SOC_BT_SUPPORTED=y +CONFIG_SOC_PCNT_SUPPORTED=y +CONFIG_SOC_PHY_SUPPORTED=y +CONFIG_SOC_WIFI_SUPPORTED=y +CONFIG_SOC_SDIO_SLAVE_SUPPORTED=y +CONFIG_SOC_TWAI_SUPPORTED=y +CONFIG_SOC_EFUSE_SUPPORTED=y +CONFIG_SOC_EMAC_SUPPORTED=y +CONFIG_SOC_ULP_SUPPORTED=y +CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y +CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y +CONFIG_SOC_RTC_MEM_SUPPORTED=y +CONFIG_SOC_I2S_SUPPORTED=y +CONFIG_SOC_RMT_SUPPORTED=y +CONFIG_SOC_SDM_SUPPORTED=y +CONFIG_SOC_GPSPI_SUPPORTED=y +CONFIG_SOC_LEDC_SUPPORTED=y +CONFIG_SOC_I2C_SUPPORTED=y +CONFIG_SOC_SUPPORT_COEXISTENCE=y +CONFIG_SOC_AES_SUPPORTED=y +CONFIG_SOC_MPI_SUPPORTED=y +CONFIG_SOC_SHA_SUPPORTED=y +CONFIG_SOC_FLASH_ENC_SUPPORTED=y +CONFIG_SOC_SECURE_BOOT_SUPPORTED=y +CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y +CONFIG_SOC_BOD_SUPPORTED=y +CONFIG_SOC_ULP_FSM_SUPPORTED=y +CONFIG_SOC_CLK_TREE_SUPPORTED=y +CONFIG_SOC_MPU_SUPPORTED=y +CONFIG_SOC_WDT_SUPPORTED=y +CONFIG_SOC_SPI_FLASH_SUPPORTED=y +CONFIG_SOC_RNG_SUPPORTED=y +CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y +CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y +CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y +CONFIG_SOC_PM_SUPPORTED=y +CONFIG_SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL=5 +CONFIG_SOC_XTAL_SUPPORT_26M=y +CONFIG_SOC_XTAL_SUPPORT_40M=y +CONFIG_SOC_XTAL_SUPPORT_AUTO_DETECT=y +CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DMA_SUPPORTED=y +CONFIG_SOC_ADC_PERIPH_NUM=2 +CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 +CONFIG_SOC_ADC_ATTEN_NUM=4 +CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 +CONFIG_SOC_ADC_PATT_LEN_MAX=16 +CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 +CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=4 +CONFIG_SOC_ADC_DIGI_MONITOR_NUM=0 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=2 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=20 +CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_SHARED_POWER=y +CONFIG_SOC_SHARED_IDCACHE_SUPPORTED=y +CONFIG_SOC_IDCACHE_PER_CORE=y +CONFIG_SOC_CPU_CORES_NUM=2 +CONFIG_SOC_CPU_INTR_NUM=32 +CONFIG_SOC_CPU_HAS_FPU=y +CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y +CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 +CONFIG_SOC_DAC_CHAN_NUM=2 +CONFIG_SOC_DAC_RESOLUTION=8 +CONFIG_SOC_DAC_DMA_16BIT_ALIGN=y +CONFIG_SOC_GPIO_PORT=1 +CONFIG_SOC_GPIO_PIN_COUNT=40 +CONFIG_SOC_GPIO_VALID_GPIO_MASK=0xFFFFFFFFFF +CONFIG_SOC_GPIO_IN_RANGE_MAX=39 +CONFIG_SOC_GPIO_OUT_RANGE_MAX=33 +CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0xEF0FEA +CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y +CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3 +CONFIG_SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP=y +CONFIG_SOC_I2C_NUM=2 +CONFIG_SOC_HP_I2C_NUM=2 +CONFIG_SOC_I2C_FIFO_LEN=32 +CONFIG_SOC_I2C_CMD_REG_NUM=16 +CONFIG_SOC_I2C_SUPPORT_SLAVE=y +CONFIG_SOC_I2C_SUPPORT_APB=y +CONFIG_SOC_I2C_STOP_INDEPENDENT=y +CONFIG_SOC_I2S_NUM=2 +CONFIG_SOC_I2S_HW_VERSION_1=y +CONFIG_SOC_I2S_SUPPORTS_APLL=y +CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y +CONFIG_SOC_I2S_SUPPORTS_PDM=y +CONFIG_SOC_I2S_SUPPORTS_PDM_TX=y +CONFIG_SOC_I2S_PDM_MAX_TX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_PDM_RX=y +CONFIG_SOC_I2S_PDM_MAX_RX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_ADC_DAC=y +CONFIG_SOC_I2S_SUPPORTS_ADC=y +CONFIG_SOC_I2S_SUPPORTS_DAC=y +CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y +CONFIG_SOC_I2S_MAX_DATA_WIDTH=24 +CONFIG_SOC_I2S_TRANS_SIZE_ALIGN_WORD=y +CONFIG_SOC_I2S_LCD_I80_VARIANT=y +CONFIG_SOC_LCD_I80_SUPPORTED=y +CONFIG_SOC_LCD_I80_BUSES=2 +CONFIG_SOC_LCD_I80_BUS_WIDTH=24 +CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y +CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y +CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y +CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y +CONFIG_SOC_LEDC_CHANNEL_NUM=8 +CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=20 +CONFIG_SOC_MCPWM_GROUPS=2 +CONFIG_SOC_MCPWM_TIMERS_PER_GROUP=3 +CONFIG_SOC_MCPWM_OPERATORS_PER_GROUP=3 +CONFIG_SOC_MCPWM_COMPARATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GENERATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_TRIGGERS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GPIO_FAULTS_PER_GROUP=3 +CONFIG_SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP=y +CONFIG_SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER=3 +CONFIG_SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP=3 +CONFIG_SOC_MMU_PERIPH_NUM=2 +CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=3 +CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 +CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 +CONFIG_SOC_PCNT_GROUPS=1 +CONFIG_SOC_PCNT_UNITS_PER_GROUP=8 +CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 +CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 +CONFIG_SOC_RMT_GROUPS=1 +CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_CHANNELS_PER_GROUP=8 +CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 +CONFIG_SOC_RMT_SUPPORT_REF_TICK=y +CONFIG_SOC_RMT_SUPPORT_APB=y +CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y +CONFIG_SOC_RTCIO_PIN_COUNT=18 +CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y +CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y +CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_SDM_GROUPS=1 +CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 +CONFIG_SOC_SDM_CLK_SUPPORT_APB=y +CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y +CONFIG_SOC_SPI_AS_CS_SUPPORTED=y +CONFIG_SOC_SPI_PERIPH_NUM=3 +CONFIG_SOC_SPI_DMA_CHAN_NUM=2 +CONFIG_SOC_SPI_MAX_CS_NUM=3 +CONFIG_SOC_SPI_SUPPORT_CLK_APB=y +CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=64 +CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 +CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y +CONFIG_SOC_TIMER_GROUPS=2 +CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 +CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 +CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y +CONFIG_SOC_TOUCH_SENSOR_VERSION=1 +CONFIG_SOC_TOUCH_SENSOR_NUM=10 +CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1 +CONFIG_SOC_TWAI_CONTROLLER_NUM=1 +CONFIG_SOC_TWAI_BRP_MIN=2 +CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y +CONFIG_SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT=y +CONFIG_SOC_UART_NUM=3 +CONFIG_SOC_UART_HP_NUM=3 +CONFIG_SOC_UART_SUPPORT_APB_CLK=y +CONFIG_SOC_UART_SUPPORT_REF_TICK=y +CONFIG_SOC_UART_FIFO_LEN=128 +CONFIG_SOC_UART_BITRATE_MAX=5000000 +CONFIG_SOC_SPIRAM_SUPPORTED=y +CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y +CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG=y +CONFIG_SOC_SHA_ENDIANNESS_BE=y +CONFIG_SOC_SHA_SUPPORT_SHA1=y +CONFIG_SOC_SHA_SUPPORT_SHA256=y +CONFIG_SOC_SHA_SUPPORT_SHA384=y +CONFIG_SOC_SHA_SUPPORT_SHA512=y +CONFIG_SOC_MPI_MEM_BLOCKS_NUM=4 +CONFIG_SOC_MPI_OPERATIONS_NUM=y +CONFIG_SOC_RSA_MAX_BIT_LEN=4096 +CONFIG_SOC_AES_SUPPORT_AES_128=y +CONFIG_SOC_AES_SUPPORT_AES_192=y +CONFIG_SOC_AES_SUPPORT_AES_256=y +CONFIG_SOC_SECURE_BOOT_V1=y +CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=y +CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=32 +CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 +CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y +CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y +CONFIG_SOC_PM_SUPPORT_MODEM_PD=y +CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y +CONFIG_SOC_CLK_APLL_SUPPORTED=y +CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y +CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y +CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y +CONFIG_SOC_SDMMC_USE_IOMUX=y +CONFIG_SOC_SDMMC_NUM_SLOTS=2 +CONFIG_SOC_WIFI_WAPI_SUPPORT=y +CONFIG_SOC_WIFI_CSI_SUPPORT=y +CONFIG_SOC_WIFI_MESH_SUPPORT=y +CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y +CONFIG_SOC_WIFI_NAN_SUPPORT=y +CONFIG_SOC_BLE_SUPPORTED=y +CONFIG_SOC_BLE_MESH_SUPPORTED=y +CONFIG_SOC_BT_CLASSIC_SUPPORTED=y +CONFIG_SOC_BLUFI_SUPPORTED=y +CONFIG_SOC_BT_H2C_ENC_KEY_CTRL_ENH_VSC_SUPPORTED=y +CONFIG_SOC_ULP_HAS_ADC=y +CONFIG_SOC_PHY_COMBO_MODULE=y +CONFIG_SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK=y +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TOOLCHAIN="gcc" +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET_ARCH="xtensa" +CONFIG_IDF_TARGET="esp32" +CONFIG_IDF_INIT_VERSION="5.4.1" +CONFIG_IDF_TARGET_ESP32=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# CONFIG_APP_REPRODUCIBLE_BUILD is not set +# CONFIG_APP_NO_BLOBS is not set +# CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# end of Build type + +# +# Bootloader config +# + +# +# Bootloader manager +# +CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y +CONFIG_BOOTLOADER_PROJECT_VER=1 +# end of Bootloader manager + +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=3 + +# +# Serial Flash Configurations +# +# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +# end of Serial Flash Configurations + +# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_V1_SUPPORTED=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +# end of Security features + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 +# end of Application manager + +CONFIG_ESP_ROM_HAS_CRC_LE=y +CONFIG_ESP_ROM_HAS_CRC_BE=y +CONFIG_ESP_ROM_HAS_MZ_CRC32=y +CONFIG_ESP_ROM_HAS_JPEG_DECODE=y +CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y +CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y +CONFIG_ESP_ROM_HAS_NEWLIB=y +CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y +CONFIG_ESP_ROM_HAS_NEWLIB_32BIT_TIME=y +CONFIG_ESP_ROM_HAS_SW_FLOAT=y +CONFIG_ESP_ROM_USB_OTG_NUM=-1 +CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1 +CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y + +# +# Serial flasher config +# +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHMODE="dio" +# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="40m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="2MB" +# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_CUSTOM is not set +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Arduino Configuration +# +CONFIG_ARDUINO_VARIANT="esp32" +CONFIG_ENABLE_ARDUINO_DEPENDS=y +# CONFIG_AUTOSTART_ARDUINO is not set +# CONFIG_ARDUINO_RUN_CORE0 is not set +CONFIG_ARDUINO_RUN_CORE1=y +# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_RUNNING_CORE=1 +CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 +# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set +CONFIG_ARDUINO_EVENT_RUN_CORE1=y +# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set +CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y +CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=2048 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 +CONFIG_ARDUINO_UDP_RUN_CORE0=y +# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set +# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_UDP_RUNNING_CORE=0 +CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 +# CONFIG_ARDUINO_ISR_IRAM is not set +# CONFIG_DISABLE_HAL_LOCKS is not set + +# +# Debug Log Configuration +# +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE=y +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=0 +# CONFIG_ARDUHAL_LOG_COLORS is not set +# CONFIG_ARDUHAL_ESP_LOG is not set +# end of Debug Log Configuration + +# CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set +CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS=y +CONFIG_ARDUHAL_PARTITION_SCHEME="min_spiffs" +CONFIG_ARDUINO_SELECTIVE_COMPILATION=y +CONFIG_ARDUINO_SELECTIVE_SPI=y +CONFIG_ARDUINO_SELECTIVE_Wire=y +CONFIG_ARDUINO_SELECTIVE_ESP_SR=y +CONFIG_ARDUINO_SELECTIVE_EEPROM=y +# CONFIG_ARDUINO_SELECTIVE_Preferences is not set +# CONFIG_ARDUINO_SELECTIVE_Ticker is not set +CONFIG_ARDUINO_SELECTIVE_Update=y +# CONFIG_ARDUINO_SELECTIVE_Zigbee is not set +CONFIG_ARDUINO_SELECTIVE_FS=y +# CONFIG_ARDUINO_SELECTIVE_SD is not set +# CONFIG_ARDUINO_SELECTIVE_SD_MMC is not set +# CONFIG_ARDUINO_SELECTIVE_SPIFFS is not set +# CONFIG_ARDUINO_SELECTIVE_FFat is not set +CONFIG_ARDUINO_SELECTIVE_LittleFS=y +CONFIG_ARDUINO_SELECTIVE_Network=y +# CONFIG_ARDUINO_SELECTIVE_Ethernet is not set +CONFIG_ARDUINO_SELECTIVE_PPP=y +CONFIG_ARDUINO_SELECTIVE_ArduinoOTA=y +CONFIG_ARDUINO_SELECTIVE_AsyncUDP=y +CONFIG_ARDUINO_SELECTIVE_DNSServer=y +CONFIG_ARDUINO_SELECTIVE_ESPmDNS=y +CONFIG_ARDUINO_SELECTIVE_HTTPClient=y +# CONFIG_ARDUINO_SELECTIVE_Matter is not set +# CONFIG_ARDUINO_SELECTIVE_NetBIOS is not set +CONFIG_ARDUINO_SELECTIVE_WebServer=y +CONFIG_ARDUINO_SELECTIVE_WiFi=y +CONFIG_ARDUINO_SELECTIVE_NetworkClientSecure=y +CONFIG_ARDUINO_SELECTIVE_WiFiProv=y +CONFIG_ARDUINO_SELECTIVE_BLE=y +# CONFIG_ARDUINO_SELECTIVE_BluetoothSerial is not set +CONFIG_ARDUINO_SELECTIVE_SimpleBLE=y +# CONFIG_ARDUINO_SELECTIVE_RainMaker is not set +# CONFIG_ARDUINO_SELECTIVE_OpenThread is not set +# CONFIG_ARDUINO_SELECTIVE_Insights is not set +# end of Arduino Configuration + +# +# Compiler options +# +CONFIG_COMPILER_OPTIMIZATION_DEBUG=y +# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set +# CONFIG_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set +CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +CONFIG_COMPILER_RT_LIB_GCCLIB=y +CONFIG_COMPILER_RT_LIB_NAME="gcc" +CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y +# CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_JTAG is not set +CONFIG_APPTRACE_DEST_NONE=y +# CONFIG_APPTRACE_DEST_UART1 is not set +# CONFIG_APPTRACE_DEST_UART2 is not set +CONFIG_APPTRACE_DEST_UART_NONE=y +CONFIG_APPTRACE_UART_TASK_PRIO=1 +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# Bluetooth +# +CONFIG_BT_ENABLED=y +# CONFIG_BT_BLUEDROID_ENABLED is not set +CONFIG_BT_NIMBLE_ENABLED=y +# CONFIG_BT_CONTROLLER_ONLY is not set +CONFIG_BT_CONTROLLER_ENABLED=y +# CONFIG_BT_CONTROLLER_DISABLED is not set + +# +# NimBLE Options +# +CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y +# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_NONE is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_WARNING is not set +CONFIG_BT_NIMBLE_LOG_LEVEL_INFO=y +# CONFIG_BT_NIMBLE_LOG_LEVEL_DEBUG is not set +CONFIG_BT_NIMBLE_LOG_LEVEL=1 +CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 +CONFIG_BT_NIMBLE_MAX_BONDS=1 +CONFIG_BT_NIMBLE_MAX_CCCDS=1 +CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM=0 +CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y +# CONFIG_BT_NIMBLE_PINNED_TO_CORE_1 is not set +CONFIG_BT_NIMBLE_PINNED_TO_CORE=0 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=4096 +CONFIG_BT_NIMBLE_ROLE_CENTRAL=y +CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y +CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y +CONFIG_BT_NIMBLE_ROLE_OBSERVER=y +# CONFIG_BT_NIMBLE_NVS_PERSIST is not set +# CONFIG_BT_NIMBLE_SMP_ID_RESET is not set +# CONFIG_BT_NIMBLE_SECURITY_ENABLE is not set +# CONFIG_BT_NIMBLE_DEBUG is not set +# CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set +CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" +CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 +CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=256 +CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE=0 + +# +# Memory Settings +# +CONFIG_BT_NIMBLE_MSYS_1_BLOCK_COUNT=12 +CONFIG_BT_NIMBLE_MSYS_1_BLOCK_SIZE=256 +CONFIG_BT_NIMBLE_MSYS_2_BLOCK_COUNT=24 +CONFIG_BT_NIMBLE_MSYS_2_BLOCK_SIZE=320 +CONFIG_BT_NIMBLE_TRANSPORT_ACL_FROM_LL_COUNT=24 +CONFIG_BT_NIMBLE_TRANSPORT_ACL_SIZE=255 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_COUNT=30 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_DISCARD_COUNT=8 +CONFIG_BT_NIMBLE_L2CAP_COC_SDU_BUFF_COUNT=1 +# end of Memory Settings + +CONFIG_BT_NIMBLE_GATT_MAX_PROCS=4 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL=y +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y +CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 +# CONFIG_BT_NIMBLE_MESH is not set +CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y +CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 +# CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set +# CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set +CONFIG_BT_NIMBLE_WHITELIST_SIZE=1 +# CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set +# CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set +CONFIG_BT_NIMBLE_USE_ESP_TIMER=y +CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y +# CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set + +# +# GAP Service +# + +# +# GAP Appearance write permissions +# +# CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set +# end of GAP Appearance write permissions + +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ENC=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHN=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHR=0 +CONFIG_BT_NIMBLE_SVC_GAP_CAR_CHAR_NOT_SUPP=y +# CONFIG_BT_NIMBLE_SVC_GAP_CAR_NOT_SUPP is not set +# CONFIG_BT_NIMBLE_SVC_GAP_CAR_SUPP is not set +CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 + +# +# GAP device name write permissions +# +# CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set +# end of GAP device name write permissions + +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_ENC=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHEN=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHOR=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 +# CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL is not set +# end of GAP Service + +# +# BLE Services +# +# CONFIG_BT_NIMBLE_HID_SERVICE is not set +# CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY is not set + +# +# Device Information Service +# +# CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME is not set +# CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER is not set +# CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION is not set +# CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION is not set +# CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION is not set +# CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID is not set +# CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID is not set +# CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED is not set +# end of Device Information Service +# end of BLE Services + +# CONFIG_BT_NIMBLE_VS_SUPPORT is not set +# CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set +# CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set +# CONFIG_BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN is not set +# CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set + +# +# Host-controller Transport +# +CONFIG_UART_HW_FLOWCTRL_DISABLE=y +# CONFIG_UART_HW_FLOWCTRL_CTS_RTS is not set +CONFIG_BT_NIMBLE_HCI_UART_FLOW_CTRL=0 +CONFIG_BT_NIMBLE_HCI_UART_RTS_PIN=19 +CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 +# end of Host-controller Transport + +CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 +# CONFIG_BT_NIMBLE_SUBRATE is not set +# end of NimBLE Options + +# +# Controller Options +# +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +# CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set +# CONFIG_BTDM_CTRL_MODE_BTDM is not set +CONFIG_BTDM_CTRL_BLE_MAX_CONN=3 +CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 +CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 +CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 +CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=3 +CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CTRL_PINNED_TO_CORE_0=y +# CONFIG_BTDM_CTRL_PINNED_TO_CORE_1 is not set +CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 +CONFIG_BTDM_CTRL_HCI_MODE_VHCI=y +# CONFIG_BTDM_CTRL_HCI_MODE_UART_H4 is not set + +# +# MODEM SLEEP Options +# +CONFIG_BTDM_CTRL_MODEM_SLEEP=y +CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG=y +# CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_EVED is not set +CONFIG_BTDM_CTRL_LPCLK_SEL_MAIN_XTAL=y +# end of MODEM SLEEP Options + +CONFIG_BTDM_BLE_DEFAULT_SCA_250PPM=y +CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 +CONFIG_BTDM_BLE_SCAN_DUPL=y +CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y +# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA is not set +# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE is not set +CONFIG_BTDM_SCAN_DUPL_TYPE=0 +CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 +CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 +# CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set +CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y +# CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set +# CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set +CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y +CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 +CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 + +# +# BLE disconnect when instant passed +# +# CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set +# CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set +# end of BLE disconnect when instant passed + +CONFIG_BTDM_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_CTRL_HLI=y +# end of Controller Options + +# +# Common Options +# +CONFIG_BT_ALARM_MAX_NUM=50 +# end of Common Options + +# CONFIG_BT_HCI_LOG_DEBUG_EN is not set +# end of Bluetooth + +# CONFIG_BLE_MESH is not set + +# +# Console Library +# +# CONFIG_CONSOLE_SORTED_HELP is not set +# end of Console Library + +# +# Driver Configurations +# + +# +# TWAI Configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y +CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y +CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID=y +CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT=y +CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y +# end of TWAI Configuration + +# +# Legacy ADC Driver Configuration +# +CONFIG_ADC_DISABLE_DAC=y +# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set + +# +# Legacy ADC Calibration Configuration +# +CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y +CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CAL_LUT_ENABLE=y +# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy ADC Calibration Configuration +# end of Legacy ADC Driver Configuration + +# +# Legacy DAC Driver Configurations +# +# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy DAC Driver Configurations + +# +# Legacy MCPWM Driver Configurations +# +# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy MCPWM Driver Configurations + +# +# Legacy Timer Group Driver Configurations +# +# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy Timer Group Driver Configurations + +# +# Legacy RMT Driver Configurations +# +# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy RMT Driver Configurations + +# +# Legacy I2S Driver Configurations +# +# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy I2S Driver Configurations + +# +# Legacy PCNT Driver Configurations +# +# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy PCNT Driver Configurations + +# +# Legacy SDM Driver Configurations +# +# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy SDM Driver Configurations +# end of Driver Configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set +CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set +CONFIG_EFUSE_MAX_BLK_LEN=192 +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +# CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set +# CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + +# +# ADC and ADC Calibration +# +# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set + +# +# ADC Calibration Configurations +# +CONFIG_ADC_CALI_EFUSE_TP_ENABLE=y +CONFIG_ADC_CALI_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CALI_LUT_ENABLE=y +# end of ADC Calibration Configurations + +CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# CONFIG_ADC_ENABLE_DEBUG_LOG is not set +# end of ADC and ADC Calibration + +# +# Wireless Coexistence +# +CONFIG_ESP_COEX_ENABLED=y +CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y +# CONFIG_ESP_COEX_POWER_MANAGEMENT is not set +# CONFIG_ESP_COEX_GPIO_DEBUG is not set +# end of Wireless Coexistence + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# end of Common ESP-related + +# +# ESP-Driver:DAC Configurations +# +# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# CONFIG_DAC_ISR_IRAM_SAFE is not set +# CONFIG_DAC_ENABLE_DEBUG_LOG is not set +CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y +# end of ESP-Driver:DAC Configurations + +# +# ESP-Driver:GPIO Configurations +# +# CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set +# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:GPIO Configurations + +# +# ESP-Driver:GPTimer Configurations +# +CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y +# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:GPTimer Configurations + +# +# ESP-Driver:I2C Configurations +# +# CONFIG_I2C_ISR_IRAM_SAFE is not set +# CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:I2C Configurations + +# +# ESP-Driver:I2S Configurations +# +# CONFIG_I2S_ISR_IRAM_SAFE is not set +# CONFIG_I2S_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:I2S Configurations + +# +# ESP-Driver:LEDC Configurations +# +# CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:LEDC Configurations + +# +# ESP-Driver:MCPWM Configurations +# +# CONFIG_MCPWM_ISR_IRAM_SAFE is not set +# CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:MCPWM Configurations + +# +# ESP-Driver:PCNT Configurations +# +# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_PCNT_ISR_IRAM_SAFE is not set +# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:PCNT Configurations + +# +# ESP-Driver:RMT Configurations +# +# CONFIG_RMT_ISR_IRAM_SAFE is not set +# CONFIG_RMT_RECV_FUNC_IN_IRAM is not set +# CONFIG_RMT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:RMT Configurations + +# +# ESP-Driver:Sigma Delta Modulator Configurations +# +# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_SDM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Sigma Delta Modulator Configurations + +# +# ESP-Driver:SPI Configurations +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of ESP-Driver:SPI Configurations + +# +# ESP-Driver:Touch Sensor Configurations +# +# CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set +# CONFIG_TOUCH_ISR_IRAM_SAFE is not set +# CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Touch Sensor Configurations + +# +# ESP-Driver:UART Configurations +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of ESP-Driver:UART Configurations + +# +# Ethernet +# +# CONFIG_ETH_USE_ESP32_EMAC is not set +# CONFIG_ETH_USE_SPI_ETHERNET is not set +# CONFIG_ETH_USE_OPENETH is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +CONFIG_ESP_GDBSTUB_ENABLED=y +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set +CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y +CONFIG_ESP_GDBSTUB_MAX_TASKS=32 +# end of GDB Stub + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +# end of ESP HTTPS server + +# +# Hardware Settings +# + +# +# Chip revision +# +CONFIG_ESP32_REV_MIN_0=y +# CONFIG_ESP32_REV_MIN_1 is not set +# CONFIG_ESP32_REV_MIN_1_1 is not set +# CONFIG_ESP32_REV_MIN_2 is not set +# CONFIG_ESP32_REV_MIN_3 is not set +# CONFIG_ESP32_REV_MIN_3_1 is not set +CONFIG_ESP32_REV_MIN=0 +CONFIG_ESP32_REV_MIN_FULL=0 +CONFIG_ESP_REV_MIN_FULL=0 + +# +# Maximum Supported ESP32 Revision (Rev v3.99) +# +CONFIG_ESP32_REV_MAX_FULL=399 +CONFIG_ESP_REV_MAX_FULL=399 +CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL=0 +CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL=99 + +# +# Maximum Supported ESP32 eFuse Block Revision (eFuse Block Rev v0.99) +# +# end of Chip revision + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set +# CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set +# end of MAC Config + +# +# Sleep Config +# +# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set +CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +# CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set +CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set +CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 +# CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set +# CONFIG_ESP_SLEEP_DEBUG is not set +CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y +# end of Sleep Config + +# +# RTC Clock Config +# +CONFIG_RTC_CLK_SRC_INT_RC=y +# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_RTC_CLK_CAL_CYCLES=1024 +# end of RTC Clock Config + +# +# Peripheral Control +# +CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y +# end of Peripheral Control + +# +# Main XTAL Config +# +# CONFIG_XTAL_FREQ_26 is not set +CONFIG_XTAL_FREQ_40=y +# CONFIG_XTAL_FREQ_AUTO is not set +CONFIG_XTAL_FREQ=40 +# end of Main XTAL Config + +CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y +# end of Hardware Settings + +# +# LCD and Touch Panel +# + +# +# LCD Touch Drivers are maintained in the IDF Component Registry +# + +# +# LCD Peripheral Configuration +# +# CONFIG_LCD_ENABLE_DEBUG_LOG is not set +# end of LCD Peripheral Configuration +# end of LCD and Touch Panel + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# CONFIG_ESP_NETIF_L2_TAP is not set +# CONFIG_ESP_NETIF_BRIDGE_EN is not set +# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set +# end of ESP NETIF Adapter + +# +# Partition API Configuration +# +# end of Partition API Configuration + +# +# PHY +# +CONFIG_ESP_PHY_ENABLED=y +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set +# CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set +CONFIG_ESP_PHY_RF_CAL_PARTIAL=y +# CONFIG_ESP_PHY_RF_CAL_NONE is not set +# CONFIG_ESP_PHY_RF_CAL_FULL is not set +CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# end of PHY + +# +# Power Management +# +# CONFIG_PM_ENABLE is not set +# CONFIG_PM_SLP_IRAM_OPT is not set +# end of Power Management + +# +# ESP PSRAM +# +# CONFIG_SPIRAM is not set +# end of ESP PSRAM + +# +# ESP Ringbuf +# +# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set +# end of ESP Ringbuf + +# +# ESP System Settings +# +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 + +# +# Memory +# +# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set + +# +# Non-backward compatible options +# +# CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set +# end of Non-backward compatible options +# end of Memory + +# +# Trace memory +# +# CONFIG_ESP32_TRAX is not set +CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 +# end of Trace memory + +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 + +# +# Memory protection +# +# end of Memory protection + +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 +CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set +# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_INT_WDT_CHECK_CPU1=y +CONFIG_ESP_TASK_WDT_EN=y +CONFIG_ESP_TASK_WDT_INIT=y +# CONFIG_ESP_TASK_WDT_PANIC is not set +CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP_DEBUG_OCDAWARE=y +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y + +# +# Brownout Detector +# +CONFIG_ESP_BROWNOUT_DET=y +CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_ESP_BROWNOUT_DET_LVL=0 +# end of Brownout Detector + +# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set +CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y +# end of ESP System Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y +CONFIG_ESP_IPC_ISR_ENABLE=y +# end of IPC (Inter-Processor Call) + +# +# ESP Timer (High Resolution Timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set +CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 +CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y +CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +CONFIG_ESP_TIMER_IMPL_TG0_LAC=y +# end of ESP Timer (High Resolution Timer) + +# +# Wi-Fi +# +CONFIG_ESP_WIFI_ENABLED=y +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 +CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 +# CONFIG_ESP_WIFI_CSI_ENABLED is not set +CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP_WIFI_TX_BA_WIN=6 +CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP_WIFI_RX_BA_WIN=6 +CONFIG_ESP_WIFI_NVS_ENABLED=y +CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +# CONFIG_ESP_WIFI_IRAM_OPT is not set +# CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set +# CONFIG_ESP_WIFI_RX_IRAM_OPT is not set +CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP_WIFI_ENABLE_SAE_PK=y +CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 +CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 +CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 +CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y +CONFIG_ESP_WIFI_GMAC_SUPPORT=y +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set +CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# CONFIG_ESP_WIFI_NAN_ENABLE is not set +CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y +CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# CONFIG_ESP_WIFI_WAPI_PSK is not set +# CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# CONFIG_ESP_WIFI_11R_SUPPORT is not set +# CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set + +# +# WPS Configuration Options +# +# CONFIG_ESP_WIFI_WPS_STRICT is not set +# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set +# end of WPS Configuration Options + +# CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set +CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y +# CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set +# end of Wi-Fi + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +CONFIG_FATFS_VOLUME_COUNT=2 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +# CONFIG_FATFS_SECTOR_512 is not set +CONFIG_FATFS_SECTOR_4096=y +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# CONFIG_FATFS_IMMEDIATE_FSYNC is not set +# CONFIG_FATFS_USE_LABEL is not set +CONFIG_FATFS_LINK_LOCK=y +# end of FAT Filesystem support + +# +# FreeRTOS +# + +# +# Kernel +# +# CONFIG_FREERTOS_SMP is not set +# CONFIG_FREERTOS_UNICORE is not set +CONFIG_FREERTOS_HZ=1000 +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +# CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# CONFIG_FREERTOS_USE_TICK_HOOK is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set +CONFIG_FREERTOS_TIMER_TASK_NO_AFFINITY=y +CONFIG_FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set +# end of Kernel + +# +# Port +# +CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# CONFIG_FREERTOS_FPU_IN_ISR is not set +CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# end of Port + +CONFIG_FREERTOS_PORT=y +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y +CONFIG_FREERTOS_NUMBER_OF_CORES=2 +# end of FreeRTOS + +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILENT is not set +# CONFIG_HAL_ASSERTION_ENABLE is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 +CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y +CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y +# CONFIG_HAL_ECDSA_GEN_SIG_CM is not set +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_USE_HOOKS is not set +# CONFIG_HEAP_TASK_TRACKING is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set +# end of Heap memory debugging + +# +# Log output +# +CONFIG_LOG_DEFAULT_LEVEL_NONE=y +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=0 +CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_ERROR is not set +# CONFIG_LOG_MAXIMUM_LEVEL_WARN is not set +# CONFIG_LOG_MAXIMUM_LEVEL_INFO is not set +# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=0 +# CONFIG_LOG_MASTER_LEVEL is not set +# CONFIG_LOG_COLORS is not set +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Log output + +# +# LWIP +# +CONFIG_LWIP_ENABLE=y +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# CONFIG_LWIP_NETIF_API is not set +CONFIG_LWIP_TCPIP_TASK_PRIO=18 +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_ND6=y +# CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +CONFIG_LWIP_SO_RCVBUF=y +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP_DEFAULT_TTL=64 +CONFIG_LWIP_IP4_FRAG=y +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +# CONFIG_LWIP_IP6_REASSEMBLY is not set +CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_ESP_MLDV6_REPORT=y +CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 +CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 + +# +# DHCP server +# +CONFIG_LWIP_DHCPS=y +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV4=y +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5760 +CONFIG_LWIP_TCP_WND_DEFAULT=5760 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 +CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 +CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 +CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +CONFIG_LWIP_SNTP_STARTUP_DELAY=y +CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 +# end of SNTP + +# +# DNS +# +CONFIG_LWIP_DNS_MAX_HOST_IP=1 +CONFIG_LWIP_DNS_MAX_SERVERS=3 +# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set +# CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set +# end of DNS + +CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y +# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set +CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y +# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set +# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_NONE=y +# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_CUSTOM is not set +# CONFIG_LWIP_HOOK_IP6_INPUT_NONE is not set +CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y +# CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set + +# +# mbedTLS v3.x related +# +# CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set +# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set +CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y +CONFIG_MBEDTLS_PKCS7_C=y +# end of mbedTLS v3.x related + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y +# CONFIG_MBEDTLS_SHA3_C is not set +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +CONFIG_MBEDTLS_PSK_MODES=y +CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +# CONFIG_MBEDTLS_DHM_C is not set +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +CONFIG_MBEDTLS_ERROR_STRINGS=y +CONFIG_MBEDTLS_FS_IO=y +# end of mbedTLS + +# +# ESP-MQTT Configurations +# +# CONFIG_MQTT_PROTOCOL_311 is not set +# CONFIG_MQTT_PROTOCOL_5 is not set +# CONFIG_MQTT_TRANSPORT_SSL is not set +# CONFIG_MQTT_TRANSPORT_WEBSOCKET is not set +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set +# end of Newlib + +# +# NVS +# +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set +# end of NVS + +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set + +# +# OpenThread Spinel +# +# CONFIG_OPENTHREAD_SPINEL_ONLY is not set +# end of OpenThread Spinel +# end of OpenThread + +# +# Protocomm +# +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +# end of Protocomm + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y +# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set +# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# MMU Config +# +CONFIG_MMU_PAGE_SIZE_64KB=y +CONFIG_MMU_PAGE_MODE="64KB" +CONFIG_MMU_PAGE_SIZE=0x10000 +# end of MMU Config + +# +# Main Flash configuration +# + +# +# SPI Flash behavior when brownout +# +CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y +CONFIG_SPI_FLASH_BROWNOUT_RESET=y +# end of SPI Flash behavior when brownout + +# +# Optional and Experimental Features (READ DOCS FIRST) +# + +# +# Features here require specific hardware (READ DOCS FIRST!) +# +CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 +# CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set +# end of Optional and Experimental Features (READ DOCS FIRST) +# end of Main Flash configuration + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y +CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +CONFIG_WS_TRANSPORT=y +CONFIG_WS_BUFFER_SIZE=1024 +# CONFIG_WS_DYNAMIC_BUFFER is not set +# end of Websocket +# end of TCP Transport + +# +# Ultra Low Power (ULP) Co-processor +# +# CONFIG_ULP_COPROC_ENABLED is not set + +# +# ULP Debugging Options +# +# end of ULP Debugging Options +# end of Ultra Low Power (ULP) Co-processor + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_64BIT is not set +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +# CONFIG_VFS_SELECT_IN_RAM is not set +CONFIG_VFS_SUPPORT_TERMIOS=y +CONFIG_VFS_MAX_COUNT=8 + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# end of Host File System I/O (Semihosting) +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_WIFI_PROV_BLE_BONDING is not set +CONFIG_WIFI_PROV_BLE_SEC_CONN=y +# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set +# CONFIG_WIFI_PROV_BLE_NOTIFY is not set +# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set +CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y +# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set +# end of Wi-Fi Provisioning Manager + +# +# Zigbee +# +# CONFIG_ZB_ENABLED is not set +# end of Zigbee + +# +# esp-modem +# +CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y +# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set +CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 +# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set +# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set +CONFIG_ESP_MODEM_C_API_STR_MAX=128 +# CONFIG_ESP_MODEM_URC_HANDLER is not set +# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set +# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set +# end of esp-modem + +# +# mDNS +# +CONFIG_MDNS_MAX_INTERFACES=3 +CONFIG_MDNS_MAX_SERVICES=10 +CONFIG_MDNS_TASK_PRIORITY=1 +CONFIG_MDNS_ACTION_QUEUE_LEN=16 +CONFIG_MDNS_TASK_STACK_SIZE=4096 +# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_MDNS_TASK_AFFINITY_CPU0=y +# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set +CONFIG_MDNS_TASK_AFFINITY=0x0 + +# +# MDNS Memory Configuration +# +CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y +CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y +# CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set +# end of MDNS Memory Configuration + +CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 +CONFIG_MDNS_TIMER_PERIOD_MS=100 +# CONFIG_MDNS_NETWORKING_SOCKET is not set +# CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set +# CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set +CONFIG_MDNS_ENABLE_CONSOLE_CLI=y +# CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set +CONFIG_MDNS_MULTIPLE_INSTANCE=y + +# +# MDNS Predefined interfaces +# +CONFIG_MDNS_PREDEF_NETIF_STA=y +CONFIG_MDNS_PREDEF_NETIF_AP=y +# end of MDNS Predefined interfaces +# end of mDNS + +# +# Network Provisioning Manager +# +CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y +CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_NETWORK_PROV_BLE_BONDING is not set +CONFIG_NETWORK_PROV_BLE_SEC_CONN=y +# CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set +# CONFIG_NETWORK_PROV_KEEP_BLE_ON_AFTER_PROV is not set +CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y +# CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set +# end of Network Provisioning Manager + +# +# LittleFS +# +# CONFIG_LITTLEFS_SDMMC_SUPPORT is not set +CONFIG_LITTLEFS_MAX_PARTITIONS=3 +CONFIG_LITTLEFS_PAGE_SIZE=256 +CONFIG_LITTLEFS_OBJ_NAME_LEN=64 +CONFIG_LITTLEFS_READ_SIZE=128 +CONFIG_LITTLEFS_WRITE_SIZE=128 +CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 +CONFIG_LITTLEFS_CACHE_SIZE=512 +CONFIG_LITTLEFS_BLOCK_CYCLES=512 +CONFIG_LITTLEFS_USE_MTIME=y +# CONFIG_LITTLEFS_USE_ONLY_HASH is not set +# CONFIG_LITTLEFS_HUMAN_READABLE is not set +CONFIG_LITTLEFS_MTIME_USE_SECONDS=y +# CONFIG_LITTLEFS_MTIME_USE_NONCE is not set +# CONFIG_LITTLEFS_SPIFFS_COMPAT is not set +# CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set +# CONFIG_LITTLEFS_FCNTL_GET_PATH is not set +# CONFIG_LITTLEFS_MULTIVERSION is not set +# CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set +CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y +# CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set +CONFIG_LITTLEFS_ASSERTS=y +# CONFIG_LITTLEFS_MMAP_PARTITION is not set +# end of LittleFS +# end of Component config + +# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 75d97191..483bc0cf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,5 +3,4 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*) -idf_component_register(SRCS "Main.cpp" - INCLUDE_DIRS ".") +idf_component_register(SRCS ${app_sources}) From b034920071779073e66f85fa78610ab46e8ee98c Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 24 Jun 2025 18:35:34 -0500 Subject: [PATCH 248/451] Revert "trying to compile with espressif plugin" This reverts commit f5e95fe22ec300a103b6cd92d051f18c61053699. --- dependencies.lock | 13 +- sdkconfig.release | 429 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 441 insertions(+), 1 deletion(-) diff --git a/dependencies.lock b/dependencies.lock index 3aef0ca5..937a8ec5 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -41,6 +41,16 @@ dependencies: registry_url: https://components.espressif.com/ type: service version: 1.6.3 + espressif/esp_modem: + component_hash: b541c3f5765d3ba062c0d004b9ca6da6d0af908293421c2dbe046c537fb2a011 + dependencies: + - name: idf + require: private + version: '>=4.1' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.4.0 espressif/mdns: component_hash: 3ec0af5f6bce310512e90f482388d21cc7c0e99668172d2f895356165fc6f7c5 dependencies: @@ -81,10 +91,11 @@ direct_dependencies: - espressif/cbor - espressif/esp-zboss-lib - espressif/esp-zigbee-lib +- espressif/esp_modem - espressif/mdns - espressif/network_provisioning - idf - joltwallet/littlefs -manifest_hash: cdea08c215af25ecb07f34a572afe529ccee1d11a022752ebfb3b54cbc0cb5f8 +manifest_hash: e9919b5b28bb7bb038864af176d8e81936400eff14ef44258dd5186bdc427ec2 target: esp32 version: 2.0.0 diff --git a/sdkconfig.release b/sdkconfig.release index 6aa2dd4c..fa80a910 100644 --- a/sdkconfig.release +++ b/sdkconfig.release @@ -259,9 +259,13 @@ CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y CONFIG_APP_BUILD_GENERATE_BINARIES=y CONFIG_APP_BUILD_BOOTLOADER=y CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# default: # CONFIG_APP_REPRODUCIBLE_BUILD is not set +# default: # CONFIG_APP_NO_BLOBS is not set +# default: # CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# default: # CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set # end of Build type @@ -296,6 +300,7 @@ CONFIG_BOOTLOADER_LOG_LEVEL=3 # # Format # +# default: # CONFIG_BOOTLOADER_LOG_COLORS is not set CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y # end of Format @@ -304,23 +309,32 @@ CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y # # Serial Flash Configurations # +# default: # CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y # end of Serial Flash Configurations # CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# default: # CONFIG_BOOTLOADER_FACTORY_RESET is not set +# default: # CONFIG_BOOTLOADER_APP_TEST is not set CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y CONFIG_BOOTLOADER_WDT_ENABLE=y +# default: # CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# default: # CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# default: # CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set # end of Bootloader config @@ -328,8 +342,11 @@ CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 # Security features # CONFIG_SECURE_BOOT_V1_SUPPORTED=y +# default: # CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# default: # CONFIG_SECURE_BOOT is not set +# default: # CONFIG_SECURE_FLASH_ENC_ENABLED is not set # end of Security features @@ -337,8 +354,11 @@ CONFIG_SECURE_BOOT_V1_SUPPORTED=y # Application manager # CONFIG_APP_COMPILE_TIME_DATE=y +# default: # CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# default: # CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# default: # CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 # end of Application manager @@ -361,6 +381,7 @@ CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y # # Serial flasher config # +# default: # CONFIG_ESPTOOLPY_NO_STUB is not set # CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set @@ -382,6 +403,7 @@ CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set CONFIG_ESPTOOLPY_FLASHSIZE="2MB" +# default: # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set @@ -411,6 +433,7 @@ CONFIG_PARTITION_TABLE_MD5=y # CONFIG_ARDUINO_VARIANT="esp32" CONFIG_ENABLE_ARDUINO_DEPENDS=y +# default: # CONFIG_AUTOSTART_ARDUINO is not set # CONFIG_ARDUINO_RUN_CORE0 is not set CONFIG_ARDUINO_RUN_CORE1=y @@ -432,7 +455,9 @@ CONFIG_ARDUINO_UDP_RUN_CORE0=y # CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set CONFIG_ARDUINO_UDP_RUNNING_CORE=0 CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 +# default: # CONFIG_ARDUINO_ISR_IRAM is not set +# default: # CONFIG_DISABLE_HAL_LOCKS is not set # @@ -445,7 +470,9 @@ CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE=y # CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set # CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=0 +# default: # CONFIG_ARDUHAL_LOG_COLORS is not set +# default: # CONFIG_ARDUHAL_ESP_LOG is not set # end of Debug Log Configuration @@ -460,17 +487,25 @@ CONFIG_ARDUINO_SELECTIVE_SPI=y CONFIG_ARDUINO_SELECTIVE_Wire=y CONFIG_ARDUINO_SELECTIVE_ESP_SR=y CONFIG_ARDUINO_SELECTIVE_EEPROM=y +# default: # CONFIG_ARDUINO_SELECTIVE_Preferences is not set +# default: # CONFIG_ARDUINO_SELECTIVE_Ticker is not set CONFIG_ARDUINO_SELECTIVE_Update=y +# default: # CONFIG_ARDUINO_SELECTIVE_Zigbee is not set CONFIG_ARDUINO_SELECTIVE_FS=y +# default: # CONFIG_ARDUINO_SELECTIVE_SD is not set +# default: # CONFIG_ARDUINO_SELECTIVE_SD_MMC is not set +# default: # CONFIG_ARDUINO_SELECTIVE_SPIFFS is not set +# default: # CONFIG_ARDUINO_SELECTIVE_FFat is not set CONFIG_ARDUINO_SELECTIVE_LittleFS=y CONFIG_ARDUINO_SELECTIVE_Network=y +# default: # CONFIG_ARDUINO_SELECTIVE_Ethernet is not set CONFIG_ARDUINO_SELECTIVE_PPP=y CONFIG_ARDUINO_SELECTIVE_ArduinoOTA=y @@ -478,17 +513,23 @@ CONFIG_ARDUINO_SELECTIVE_AsyncUDP=y CONFIG_ARDUINO_SELECTIVE_DNSServer=y CONFIG_ARDUINO_SELECTIVE_ESPmDNS=y CONFIG_ARDUINO_SELECTIVE_HTTPClient=y +# default: # CONFIG_ARDUINO_SELECTIVE_Matter is not set +# default: # CONFIG_ARDUINO_SELECTIVE_NetBIOS is not set CONFIG_ARDUINO_SELECTIVE_WebServer=y CONFIG_ARDUINO_SELECTIVE_WiFi=y CONFIG_ARDUINO_SELECTIVE_NetworkClientSecure=y CONFIG_ARDUINO_SELECTIVE_WiFiProv=y CONFIG_ARDUINO_SELECTIVE_BLE=y +# default: # CONFIG_ARDUINO_SELECTIVE_BluetoothSerial is not set CONFIG_ARDUINO_SELECTIVE_SimpleBLE=y +# default: # CONFIG_ARDUINO_SELECTIVE_RainMaker is not set +# default: # CONFIG_ARDUINO_SELECTIVE_OpenThread is not set +# default: # CONFIG_ARDUINO_SELECTIVE_Insights is not set # end of Arduino Configuration @@ -505,25 +546,35 @@ CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# default: # CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# default: # CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# default: # CONFIG_COMPILER_CXX_RTTI is not set CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set # CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set # CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# default: # CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set +# default: # CONFIG_COMPILER_WARN_WRITE_STRINGS is not set CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y +# default: # CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# default: # CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# default: # CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set +# default: # CONFIG_COMPILER_DUMP_RTL_FILES is not set CONFIG_COMPILER_RT_LIB_GCCLIB=y CONFIG_COMPILER_RT_LIB_NAME="gcc" CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y # CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set +# default: # CONFIG_COMPILER_STATIC_ANALYZER is not set # end of Compiler options @@ -576,10 +627,15 @@ CONFIG_BT_NIMBLE_ROLE_CENTRAL=y CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y CONFIG_BT_NIMBLE_ROLE_OBSERVER=y +# default: # CONFIG_BT_NIMBLE_NVS_PERSIST is not set +# default: # CONFIG_BT_NIMBLE_SMP_ID_RESET is not set +# default: # CONFIG_BT_NIMBLE_SECURITY_ENABLE is not set +# default: # CONFIG_BT_NIMBLE_DEBUG is not set +# default: # CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 @@ -607,16 +663,22 @@ CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 +# default: # CONFIG_BT_NIMBLE_MESH is not set CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 +# default: # CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set +# default: # CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set CONFIG_BT_NIMBLE_WHITELIST_SIZE=1 +# default: # CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set +# default: # CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set CONFIG_BT_NIMBLE_USE_ESP_TIMER=y CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y +# default: # CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set # @@ -626,6 +688,7 @@ CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y # # GAP Appearance write permissions # +# default: # CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set # end of GAP Appearance write permissions @@ -641,6 +704,7 @@ CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 # # GAP device name write permissions # +# default: # CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set # end of GAP device name write permissions @@ -652,33 +716,49 @@ CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 +# default: # CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL is not set # end of GAP Service # # BLE Services # +# default: # CONFIG_BT_NIMBLE_HID_SERVICE is not set +# default: # CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY is not set # # Device Information Service # +# default: # CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED is not set # end of Device Information Service # end of BLE Services +# default: # CONFIG_BT_NIMBLE_VS_SUPPORT is not set +# default: # CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set +# default: # CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set +# default: # CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set +# default: # CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT is not set # @@ -692,6 +772,7 @@ CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 # end of Host-controller Transport CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 +# default: # CONFIG_BT_NIMBLE_SUBRATE is not set # end of NimBLE Options @@ -734,9 +815,12 @@ CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y CONFIG_BTDM_SCAN_DUPL_TYPE=0 CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 +# default: # CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y +# default: # CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set +# default: # CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 @@ -745,12 +829,15 @@ CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # # BLE disconnects when Instant Passed (0x28) occurs # +# default: # CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set +# default: # CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set # end of BLE disconnects when Instant Passed (0x28) occurs CONFIG_BTDM_BLE_CHAN_ASS_EN=y CONFIG_BTDM_BLE_PING_EN=y +# default: # CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 is not set CONFIG_BTDM_RESERVE_DRAM=0xdb5c CONFIG_BTDM_CTRL_HLI=y @@ -760,17 +847,21 @@ CONFIG_BTDM_CTRL_HLI=y # Common Options # CONFIG_BT_ALARM_MAX_NUM=50 +# default: # CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set # end of Common Options +# default: # CONFIG_BT_HCI_LOG_DEBUG_EN is not set # end of Bluetooth +# default: # CONFIG_BLE_MESH is not set # # Console Library # +# default: # CONFIG_CONSOLE_SORTED_HELP is not set # end of Console Library @@ -781,6 +872,7 @@ CONFIG_BT_ALARM_MAX_NUM=50 # # TWAI Configuration # +# default: # CONFIG_TWAI_ISR_IN_IRAM is not set CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y @@ -793,7 +885,9 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # Legacy ADC Driver Configuration # CONFIG_ADC_DISABLE_DAC=y +# default: # CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set # @@ -802,6 +896,7 @@ CONFIG_ADC_DISABLE_DAC=y CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y CONFIG_ADC_CAL_LUT_ENABLE=y +# default: # CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set # end of Legacy ADC Calibration Configuration # end of Legacy ADC Driver Configuration @@ -809,49 +904,63 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # # Legacy DAC Driver Configurations # +# default: # CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy DAC Driver Configurations # # Legacy MCPWM Driver Configurations # +# default: # CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy MCPWM Driver Configurations # # Legacy Timer Group Driver Configurations # +# default: # CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Timer Group Driver Configurations # # Legacy RMT Driver Configurations # +# default: # CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy RMT Driver Configurations # # Legacy I2S Driver Configurations # +# default: # CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy I2S Driver Configurations # # Legacy PCNT Driver Configurations # +# default: # CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy PCNT Driver Configurations # # Legacy SDM Driver Configurations # +# default: # CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy SDM Driver Configurations # end of Driver Configurations @@ -859,7 +968,9 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # # eFuse Bit Manager # +# default: # CONFIG_EFUSE_CUSTOM_TABLE is not set +# default: # CONFIG_EFUSE_VIRTUAL is not set # CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y @@ -871,19 +982,28 @@ CONFIG_EFUSE_MAX_BLK_LEN=192 # ESP-TLS # CONFIG_ESP_TLS_USING_MBEDTLS=y +# default: # CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set +# default: # CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# default: # CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set +# default: # CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set +# default: # CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set +# default: # CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# default: # CONFIG_ESP_TLS_INSECURE is not set # end of ESP-TLS # # ADC and ADC Calibration # +# default: # CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set # @@ -895,6 +1015,7 @@ CONFIG_ADC_CALI_LUT_ENABLE=y # end of ADC Calibration Configurations CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# default: # CONFIG_ADC_ENABLE_DEBUG_LOG is not set # end of ADC and ADC Calibration @@ -903,7 +1024,9 @@ CONFIG_ADC_DISABLE_DAC_OUTPUT=y # CONFIG_ESP_COEX_ENABLED=y CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y +# default: # CONFIG_ESP_COEX_POWER_MANAGEMENT is not set +# default: # CONFIG_ESP_COEX_GPIO_DEBUG is not set # end of Wireless Coexistence @@ -916,8 +1039,11 @@ CONFIG_ESP_ERR_TO_NAME_LOOKUP=y # # ESP-Driver:DAC Configurations # +# default: # CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_DAC_ISR_IRAM_SAFE is not set +# default: # CONFIG_DAC_ENABLE_DEBUG_LOG is not set CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # end of ESP-Driver:DAC Configurations @@ -925,7 +1051,9 @@ CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # # ESP-Driver:GPIO Configurations # +# default: # CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set +# default: # CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:GPIO Configurations @@ -933,68 +1061,90 @@ CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # ESP-Driver:GPTimer Configurations # CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y +# default: # CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# default: # CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:GPTimer Configurations # # ESP-Driver:I2C Configurations # +# default: # CONFIG_I2C_ISR_IRAM_SAFE is not set +# default: # CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# default: # CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set # end of ESP-Driver:I2C Configurations # # ESP-Driver:I2S Configurations # +# default: # CONFIG_I2S_ISR_IRAM_SAFE is not set +# default: # CONFIG_I2S_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:I2S Configurations # # ESP-Driver:LEDC Configurations # +# default: # CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:LEDC Configurations # # ESP-Driver:MCPWM Configurations # +# default: # CONFIG_MCPWM_ISR_IRAM_SAFE is not set +# default: # CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:MCPWM Configurations # # ESP-Driver:PCNT Configurations # +# default: # CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_PCNT_ISR_IRAM_SAFE is not set +# default: # CONFIG_PCNT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:PCNT Configurations # # ESP-Driver:RMT Configurations # +# default: # CONFIG_RMT_ISR_IRAM_SAFE is not set +# default: # CONFIG_RMT_RECV_FUNC_IN_IRAM is not set +# default: # CONFIG_RMT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:RMT Configurations # # ESP-Driver:Sigma Delta Modulator Configurations # +# default: # CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_SDM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Sigma Delta Modulator Configurations # # ESP-Driver:SPI Configurations # +# default: # CONFIG_SPI_MASTER_IN_IRAM is not set CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# default: # CONFIG_SPI_SLAVE_IN_IRAM is not set CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # end of ESP-Driver:SPI Configurations @@ -1002,28 +1152,36 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # # ESP-Driver:Touch Sensor Configurations # +# default: # CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_TOUCH_ISR_IRAM_SAFE is not set +# default: # CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Touch Sensor Configurations # # ESP-Driver:UART Configurations # +# default: # CONFIG_UART_ISR_IN_IRAM is not set # end of ESP-Driver:UART Configurations # # Ethernet # +# default: # CONFIG_ETH_USE_ESP32_EMAC is not set +# default: # CONFIG_ETH_USE_SPI_ETHERNET is not set +# default: # CONFIG_ETH_USE_OPENETH is not set # end of Ethernet # # Event Loop Library # +# default: # CONFIG_ESP_EVENT_LOOP_PROFILING is not set CONFIG_ESP_EVENT_POST_FROM_ISR=y CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y @@ -1033,6 +1191,7 @@ CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y # GDB Stub # CONFIG_ESP_GDBSTUB_ENABLED=y +# default: # CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y CONFIG_ESP_GDBSTUB_MAX_TASKS=32 @@ -1049,8 +1208,11 @@ CONFIG_ESPHID_TASK_SIZE_BLE=4096 # ESP HTTP client # CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 # end of ESP HTTP client @@ -1062,8 +1224,11 @@ CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 CONFIG_HTTPD_MAX_URI_LEN=512 CONFIG_HTTPD_ERR_RESP_NO_DELAY=y CONFIG_HTTPD_PURGE_BUF_LEN=32 +# default: # CONFIG_HTTPD_LOG_PURGE_DATA is not set +# default: # CONFIG_HTTPD_WS_SUPPORT is not set +# default: # CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # end of HTTP Server @@ -1071,7 +1236,9 @@ CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # # ESP HTTPS OTA # +# default: # CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# default: # CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS OTA @@ -1079,6 +1246,7 @@ CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # # ESP HTTPS server # +# default: # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS server @@ -1125,20 +1293,27 @@ CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 # CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 +# default: # CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set +# default: # CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set # end of MAC Config # # Sleep Config # +# default: # CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +# default: # CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# default: # CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 +# default: # CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set +# default: # CONFIG_ESP_SLEEP_DEBUG is not set CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y # end of Sleep Config @@ -1175,6 +1350,7 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # # ESP-Driver:LCD Controller Configurations # +# default: # CONFIG_LCD_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:LCD Controller Configurations @@ -1187,14 +1363,19 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # ESP NETIF Adapter # CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +# default: # CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set CONFIG_ESP_NETIF_TCPIP_LWIP=y # CONFIG_ESP_NETIF_LOOPBACK is not set CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y +# default: # CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# default: # CONFIG_ESP_NETIF_L2_TAP is not set +# default: # CONFIG_ESP_NETIF_BRIDGE_EN is not set +# default: # CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set # end of ESP NETIF Adapter @@ -1208,35 +1389,44 @@ CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y # CONFIG_ESP_PHY_ENABLED=y CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# default: # CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP_PHY_MAX_TX_POWER=20 +# default: # CONFIG_ESP_PHY_REDUCE_TX_POWER is not set +# default: # CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set CONFIG_ESP_PHY_RF_CAL_PARTIAL=y # CONFIG_ESP_PHY_RF_CAL_NONE is not set # CONFIG_ESP_PHY_RF_CAL_FULL is not set CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# default: # CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# default: # CONFIG_ESP_PHY_RECORD_USED_TIME is not set # end of PHY # # Power Management # +# default: # CONFIG_PM_ENABLE is not set +# default: # CONFIG_PM_SLP_IRAM_OPT is not set # end of Power Management # # ESP PSRAM # +# default: # CONFIG_SPIRAM is not set # end of ESP PSRAM # # ESP Ringbuf # +# default: # CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set # end of ESP Ringbuf @@ -1256,11 +1446,13 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 # # Memory # +# default: # CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set # # Non-backward compatible options # +# default: # CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set # end of Non-backward compatible options # end of Memory @@ -1268,6 +1460,7 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 # # Trace memory # +# default: # CONFIG_ESP32_TRAX is not set CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 # end of Trace memory @@ -1303,11 +1496,14 @@ CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 CONFIG_ESP_INT_WDT_CHECK_CPU1=y CONFIG_ESP_TASK_WDT_EN=y CONFIG_ESP_TASK_WDT_INIT=y +# default: # CONFIG_ESP_TASK_WDT_PANIC is not set CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# default: # CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# default: # CONFIG_ESP_DEBUG_STUBS_ENABLE is not set CONFIG_ESP_DEBUG_OCDAWARE=y CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y @@ -1327,6 +1523,7 @@ CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y CONFIG_ESP_BROWNOUT_DET_LVL=0 # end of Brownout Detector +# default: # CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y # end of ESP System Settings @@ -1342,15 +1539,18 @@ CONFIG_ESP_IPC_ISR_ENABLE=y # # ESP Timer (High Resolution Timer) # +# default: # CONFIG_ESP_TIMER_PROFILING is not set CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# default: # CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# default: # CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set CONFIG_ESP_TIMER_IMPL_TG0_LAC=y # end of ESP Timer (High Resolution Timer) @@ -1369,6 +1569,7 @@ CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y # CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 +# default: # CONFIG_ESP_WIFI_CSI_ENABLED is not set CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP_WIFI_TX_BA_WIN=6 @@ -1379,13 +1580,17 @@ CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +# default: # CONFIG_ESP_WIFI_IRAM_OPT is not set +# default: # CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set +# default: # CONFIG_ESP_WIFI_RX_IRAM_OPT is not set CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y CONFIG_ESP_WIFI_ENABLE_SAE_PK=y CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# default: # CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 @@ -1393,28 +1598,41 @@ CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y CONFIG_ESP_WIFI_GMAC_SUPPORT=y CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# default: # CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# default: # CONFIG_ESP_WIFI_NAN_ENABLE is not set CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# default: # CONFIG_ESP_WIFI_WAPI_PSK is not set +# default: # CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_11R_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set # # WPS Configuration Options # +# default: # CONFIG_ESP_WIFI_WPS_STRICT is not set +# default: # CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set # end of WPS Configuration Options +# default: # CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# default: # CONFIG_ESP_WIFI_TESTING_OPTIONS is not set CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y +# default: # CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set # end of Wi-Fi @@ -1461,12 +1679,15 @@ CONFIG_FATFS_CODEPAGE=437 CONFIG_FATFS_FS_LOCK=0 CONFIG_FATFS_TIMEOUT_MS=10000 CONFIG_FATFS_PER_FILE_CACHE=y +# default: # CONFIG_FATFS_USE_FASTSEEK is not set CONFIG_FATFS_USE_STRFUNC_NONE=y # CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set # CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# default: # CONFIG_FATFS_IMMEDIATE_FSYNC is not set +# default: # CONFIG_FATFS_USE_LABEL is not set CONFIG_FATFS_LINK_LOCK=y # end of FAT Filesystem support @@ -1478,7 +1699,9 @@ CONFIG_FATFS_LINK_LOCK=y # # Kernel # +# default: # CONFIG_FREERTOS_SMP is not set +# default: # CONFIG_FREERTOS_UNICORE is not set CONFIG_FREERTOS_HZ=1000 # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set @@ -1486,9 +1709,12 @@ CONFIG_FREERTOS_HZ=1000 CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +# default: # CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# default: # CONFIG_FREERTOS_USE_TICK_HOOK is not set CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# default: # CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set CONFIG_FREERTOS_USE_TIMERS=y CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" @@ -1501,28 +1727,38 @@ CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# default: # CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# default: # CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set +# default: # CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# default: # CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set # end of Kernel # # Port # +# default: # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# default: # CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set +# default: # CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y CONFIG_FREERTOS_ISR_STACKSIZE=1536 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# default: # CONFIG_FREERTOS_FPU_IN_ISR is not set CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y CONFIG_FREERTOS_CORETIMER_0=y # CONFIG_FREERTOS_CORETIMER_1 is not set CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# default: # CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +# default: # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set # end of Port @@ -1561,9 +1797,13 @@ CONFIG_HEAP_POISONING_DISABLED=y CONFIG_HEAP_TRACING_OFF=y # CONFIG_HEAP_TRACING_STANDALONE is not set # CONFIG_HEAP_TRACING_TOHOST is not set +# default: # CONFIG_HEAP_USE_HOOKS is not set +# default: # CONFIG_HEAP_TASK_TRACKING is not set +# default: # CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# default: # CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set # end of Heap memory debugging @@ -1592,6 +1832,7 @@ CONFIG_LOG_MAXIMUM_LEVEL=0 # # Level Settings # +# default: # CONFIG_LOG_MASTER_LEVEL is not set CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y # CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set @@ -1606,6 +1847,7 @@ CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 # # Format # +# default: # CONFIG_LOG_COLORS is not set CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set @@ -1617,31 +1859,45 @@ CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LWIP_ENABLE=y CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# default: # CONFIG_LWIP_NETIF_API is not set CONFIG_LWIP_TCPIP_TASK_PRIO=18 +# default: # CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# default: # CONFIG_LWIP_CHECK_THREAD_SAFETY is not set CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# default: # CONFIG_LWIP_L2_TO_L3_COPY is not set +# default: # CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# default: # CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set CONFIG_LWIP_TIMERS_ONDEMAND=y CONFIG_LWIP_ND6=y +# default: # CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set CONFIG_LWIP_MAX_SOCKETS=10 +# default: # CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# default: # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y CONFIG_LWIP_SO_RCVBUF=y +# default: # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP_DEFAULT_TTL=64 CONFIG_LWIP_IP4_FRAG=y CONFIG_LWIP_IP6_FRAG=y +# default: # CONFIG_LWIP_IP4_REASSEMBLY is not set +# default: # CONFIG_LWIP_IP6_REASSEMBLY is not set CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# default: # CONFIG_LWIP_IP_FORWARD is not set +# default: # CONFIG_LWIP_STATS is not set CONFIG_LWIP_ESP_GRATUITOUS_ARP=y CONFIG_LWIP_GARP_TMR_INTERVAL=60 @@ -1651,8 +1907,10 @@ CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y # CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set # CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set +# default: # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# default: # CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set CONFIG_LWIP_DHCP_OPTIONS_LEN=68 CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 @@ -1668,12 +1926,16 @@ CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y CONFIG_LWIP_DHCPS_ADD_DNS=y # end of DHCP server +# default: # CONFIG_LWIP_AUTOIP is not set CONFIG_LWIP_IPV4=y CONFIG_LWIP_IPV6=y +# default: # CONFIG_LWIP_IPV6_AUTOCONFIG is not set CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# default: # CONFIG_LWIP_IPV6_FORWARD is not set +# default: # CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set CONFIG_LWIP_NETIF_LOOPBACK=y CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 @@ -1697,6 +1959,7 @@ CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 CONFIG_LWIP_TCP_QUEUE_OOSEQ=y CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 +# default: # CONFIG_LWIP_TCP_SACK_OUT is not set CONFIG_LWIP_TCP_OVERSIZE_MSS=y # CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set @@ -1714,7 +1977,9 @@ CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 # # Checksums # +# default: # CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# default: # CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums @@ -1729,14 +1994,18 @@ CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 +# default: # CONFIG_LWIP_PPP_SUPPORT is not set +# default: # CONFIG_LWIP_SLIP_SUPPORT is not set # # ICMP # CONFIG_LWIP_ICMP=y +# default: # CONFIG_LWIP_MULTICAST_PING is not set +# default: # CONFIG_LWIP_BROADCAST_PING is not set # end of ICMP @@ -1750,6 +2019,7 @@ CONFIG_LWIP_MAX_RAW_PCBS=16 # SNTP # CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# default: # CONFIG_LWIP_DHCP_GET_NTP_SRV is not set CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 CONFIG_LWIP_SNTP_STARTUP_DELAY=y @@ -1761,7 +2031,9 @@ CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 # CONFIG_LWIP_DNS_MAX_HOST_IP=1 CONFIG_LWIP_DNS_MAX_SERVERS=3 +# default: # CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set +# default: # CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set # end of DNS @@ -1793,6 +2065,7 @@ CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y # CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set # end of Hooks +# default: # CONFIG_LWIP_DEBUG is not set # end of LWIP @@ -1805,15 +2078,21 @@ CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# default: # CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# default: # CONFIG_MBEDTLS_DEBUG is not set # # mbedTLS v3.x related # +# default: # CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set +# default: # CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# default: # CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# default: # CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y CONFIG_MBEDTLS_PKCS7_C=y @@ -1826,26 +2105,35 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# default: # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# default: # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 # end of Certificate Bundle +# default: # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set CONFIG_MBEDTLS_CMAC_C=y CONFIG_MBEDTLS_HARDWARE_AES=y CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y CONFIG_MBEDTLS_HARDWARE_MPI=y +# default: # CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set CONFIG_MBEDTLS_HARDWARE_SHA=y CONFIG_MBEDTLS_ROM_MD5=y +# default: # CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# default: # CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set CONFIG_MBEDTLS_HAVE_TIME=y +# default: # CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set +# default: # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y CONFIG_MBEDTLS_SHA512_C=y +# default: # CONFIG_MBEDTLS_SHA3_C is not set CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y # CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set @@ -1872,7 +2160,9 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y CONFIG_MBEDTLS_SSL_RENEGOTIATION=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# default: # CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# default: # CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set CONFIG_MBEDTLS_SSL_ALPN=y CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y @@ -1882,15 +2172,21 @@ CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y # Symmetric Ciphers # CONFIG_MBEDTLS_AES_C=y +# default: # CONFIG_MBEDTLS_CAMELLIA_C is not set +# default: # CONFIG_MBEDTLS_DES_C is not set +# default: # CONFIG_MBEDTLS_BLOWFISH_C is not set +# default: # CONFIG_MBEDTLS_XTEA_C is not set CONFIG_MBEDTLS_CCM_C=y CONFIG_MBEDTLS_GCM_C=y +# default: # CONFIG_MBEDTLS_NIST_KW_C is not set # end of Symmetric Ciphers +# default: # CONFIG_MBEDTLS_RIPEMD160_C is not set # @@ -1905,9 +2201,11 @@ CONFIG_MBEDTLS_X509_CSR_PARSE_C=y CONFIG_MBEDTLS_ECP_C=y CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y +# default: # CONFIG_MBEDTLS_DHM_C is not set CONFIG_MBEDTLS_ECDH_C=y CONFIG_MBEDTLS_ECDSA_C=y +# default: # CONFIG_MBEDTLS_ECJPAKE_C is not set CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y @@ -1922,10 +2220,15 @@ CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# default: # CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set +# default: # CONFIG_MBEDTLS_POLY1305_C is not set +# default: # CONFIG_MBEDTLS_CHACHA20_C is not set +# default: # CONFIG_MBEDTLS_HKDF_C is not set +# default: # CONFIG_MBEDTLS_THREADING_C is not set CONFIG_MBEDTLS_ERROR_STRINGS=y CONFIG_MBEDTLS_FS_IO=y @@ -1934,15 +2237,25 @@ CONFIG_MBEDTLS_FS_IO=y # # ESP-MQTT Configurations # +# default: # CONFIG_MQTT_PROTOCOL_311 is not set +# default: # CONFIG_MQTT_PROTOCOL_5 is not set +# default: # CONFIG_MQTT_TRANSPORT_SSL is not set +# default: # CONFIG_MQTT_TRANSPORT_WEBSOCKET is not set +# default: # CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# default: # CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# default: # CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# default: # CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# default: # CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# default: # CONFIG_MQTT_CUSTOM_OUTBOX is not set # end of ESP-MQTT Configurations @@ -1955,6 +2268,7 @@ CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y # CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set # CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# default: # CONFIG_NEWLIB_NANO_FORMAT is not set CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y # CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set @@ -1965,18 +2279,22 @@ CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y # # NVS # +# default: # CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# default: # CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set # end of NVS # # OpenThread # +# default: # CONFIG_OPENTHREAD_ENABLED is not set # # OpenThread Spinel # +# default: # CONFIG_OPENTHREAD_SPINEL_ONLY is not set # end of OpenThread Spinel # end of OpenThread @@ -2030,6 +2348,7 @@ CONFIG_SPI_FLASH_BROWNOUT_RESET=y # Features here require specific hardware (READ DOCS FIRST!) # CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 +# default: # CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set # end of Optional and Experimental Features (READ DOCS FIRST) # end of Main Flash configuration @@ -2037,20 +2356,27 @@ CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 # # SPI Flash driver # +# default: # CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# default: # CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y # CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set # CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# default: # CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set +# default: # CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# default: # CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# default: # CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# default: # CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set # @@ -2065,7 +2391,9 @@ CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +# default: # CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# default: # CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set # end of Auto-detect flash chips @@ -2082,14 +2410,17 @@ CONFIG_SPIFFS_MAX_PARTITIONS=3 # CONFIG_SPIFFS_CACHE=y CONFIG_SPIFFS_CACHE_WR=y +# default: # CONFIG_SPIFFS_CACHE_STATS is not set # end of SPIFFS Cache Configuration CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 +# default: # CONFIG_SPIFFS_GC_STATS is not set CONFIG_SPIFFS_PAGE_SIZE=256 CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# default: # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y @@ -2099,11 +2430,17 @@ CONFIG_SPIFFS_USE_MTIME=y # # Debug Configuration # +# default: # CONFIG_SPIFFS_DBG is not set +# default: # CONFIG_SPIFFS_API_DBG is not set +# default: # CONFIG_SPIFFS_GC_DBG is not set +# default: # CONFIG_SPIFFS_CACHE_DBG is not set +# default: # CONFIG_SPIFFS_CHECK_DBG is not set +# default: # CONFIG_SPIFFS_TEST_VISUALISATION is not set # end of Debug Configuration # end of SPIFFS Configuration @@ -2117,6 +2454,7 @@ CONFIG_SPIFFS_USE_MTIME=y # CONFIG_WS_TRANSPORT=y CONFIG_WS_BUFFER_SIZE=1024 +# default: # CONFIG_WS_DYNAMIC_BUFFER is not set # end of Websocket # end of TCP Transport @@ -2124,6 +2462,7 @@ CONFIG_WS_BUFFER_SIZE=1024 # # Ultra Low Power (ULP) Co-processor # +# default: # CONFIG_ULP_COPROC_ENABLED is not set # @@ -2137,10 +2476,14 @@ CONFIG_WS_BUFFER_SIZE=1024 # CONFIG_UNITY_ENABLE_FLOAT=y CONFIG_UNITY_ENABLE_DOUBLE=y +# default: # CONFIG_UNITY_ENABLE_64BIT is not set +# default: # CONFIG_UNITY_ENABLE_COLOR is not set CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# default: # CONFIG_UNITY_ENABLE_FIXTURE is not set +# default: # CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set # end of Unity unit testing library @@ -2151,6 +2494,7 @@ CONFIG_VFS_SUPPORT_IO=y CONFIG_VFS_SUPPORT_DIR=y CONFIG_VFS_SUPPORT_SELECT=y CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +# default: # CONFIG_VFS_SELECT_IN_RAM is not set CONFIG_VFS_SUPPORT_TERMIOS=y CONFIG_VFS_MAX_COUNT=8 @@ -2177,10 +2521,14 @@ CONFIG_WL_SECTOR_SIZE=4096 # CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# default: # CONFIG_WIFI_PROV_BLE_BONDING is not set CONFIG_WIFI_PROV_BLE_SEC_CONN=y +# default: # CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set +# default: # CONFIG_WIFI_PROV_BLE_NOTIFY is not set +# default: # CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set @@ -2189,9 +2537,33 @@ CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # # Zigbee # +# default: # CONFIG_ZB_ENABLED is not set # end of Zigbee +# +# esp-modem +# +# default: +CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y +# default: +# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set +# default: +CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 +# default: +# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set +# default: +# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set +# default: +CONFIG_ESP_MODEM_C_API_STR_MAX=128 +# default: +# CONFIG_ESP_MODEM_URC_HANDLER is not set +# default: +# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set +# default: +# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set +# end of esp-modem + # # mDNS # @@ -2210,15 +2582,20 @@ CONFIG_MDNS_TASK_AFFINITY=0x0 # CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y +# default: # CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set # end of MDNS Memory Configuration CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 CONFIG_MDNS_TIMER_PERIOD_MS=100 +# default: # CONFIG_MDNS_NETWORKING_SOCKET is not set +# default: # CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set +# default: # CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set CONFIG_MDNS_ENABLE_CONSOLE_CLI=y +# default: # CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set CONFIG_MDNS_MULTIPLE_INSTANCE=y @@ -2236,9 +2613,12 @@ CONFIG_MDNS_PREDEF_NETIF_AP=y CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 +# default: # CONFIG_NETWORK_PROV_BLE_BONDING is not set CONFIG_NETWORK_PROV_BLE_SEC_CONN=y +# default: # CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set +# default: # CONFIG_NETWORK_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y # CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set @@ -2247,6 +2627,7 @@ CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y # # LittleFS # +# default: # CONFIG_LITTLEFS_SDMMC_SUPPORT is not set CONFIG_LITTLEFS_MAX_PARTITIONS=3 CONFIG_LITTLEFS_PAGE_SIZE=256 @@ -2257,29 +2638,41 @@ CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 CONFIG_LITTLEFS_CACHE_SIZE=512 CONFIG_LITTLEFS_BLOCK_CYCLES=512 CONFIG_LITTLEFS_USE_MTIME=y +# default: # CONFIG_LITTLEFS_USE_ONLY_HASH is not set +# default: # CONFIG_LITTLEFS_HUMAN_READABLE is not set CONFIG_LITTLEFS_MTIME_USE_SECONDS=y # CONFIG_LITTLEFS_MTIME_USE_NONCE is not set +# default: # CONFIG_LITTLEFS_SPIFFS_COMPAT is not set +# default: # CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set +# default: # CONFIG_LITTLEFS_FCNTL_GET_PATH is not set +# default: # CONFIG_LITTLEFS_MULTIVERSION is not set # CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y # CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set CONFIG_LITTLEFS_ASSERTS=y +# default: # CONFIG_LITTLEFS_MMAP_PARTITION is not set # end of LittleFS # end of Component config +# default: # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set # Deprecated options for backward compatibility # CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# default: # CONFIG_NO_BLOBS is not set +# default: # CONFIG_ESP32_NO_BLOBS is not set +# default: # CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# default: # CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set # CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set # CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set @@ -2288,7 +2681,9 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y # CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set # CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set CONFIG_LOG_BOOTLOADER_LEVEL=3 +# default: # CONFIG_APP_ROLLBACK_ENABLE is not set +# default: # CONFIG_FLASH_ENCRYPTION_ENABLED is not set # CONFIG_FLASHMODE_QIO is not set # CONFIG_FLASHMODE_QOUT is not set @@ -2304,11 +2699,13 @@ CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y # CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set # CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# default: # CONFIG_CXX_EXCEPTIONS is not set CONFIG_STACK_CHECK_NONE=y # CONFIG_STACK_CHECK_NORM is not set # CONFIG_STACK_CHECK_STRONG is not set # CONFIG_STACK_CHECK_ALL is not set +# default: # CONFIG_WARN_WRITE_STRINGS is not set # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set CONFIG_ESP32_APPTRACE_DEST_NONE=y @@ -2330,7 +2727,9 @@ CONFIG_NIMBLE_ROLE_CENTRAL=y CONFIG_NIMBLE_ROLE_PERIPHERAL=y CONFIG_NIMBLE_ROLE_BROADCASTER=y CONFIG_NIMBLE_ROLE_OBSERVER=y +# default: # CONFIG_NIMBLE_NVS_PERSIST is not set +# default: # CONFIG_NIMBLE_DEBUG is not set CONFIG_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" CONFIG_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 @@ -2347,6 +2746,7 @@ CONFIG_NIMBLE_HS_FLOW_CTRL_ITVL=1000 CONFIG_NIMBLE_HS_FLOW_CTRL_THRESH=2 CONFIG_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y CONFIG_NIMBLE_RPA_TIMEOUT=900 +# default: # CONFIG_NIMBLE_MESH is not set CONFIG_NIMBLE_CRYPTO_STACK_MBEDTLS=y CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y @@ -2366,6 +2766,7 @@ CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y # CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR is not set CONFIG_SCAN_DUPLICATE_TYPE=0 CONFIG_DUPLICATE_SCAN_CACHE_SIZE=100 +# default: # CONFIG_BLE_MESH_SCAN_DUPLICATE_EN is not set CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED=y @@ -2375,16 +2776,20 @@ CONFIG_ADC2_DISABLE_DAC=y CONFIG_SW_COEXIST_ENABLE=y CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y +# default: # CONFIG_MCPWM_ISR_IN_IRAM is not set +# default: # CONFIG_EVENT_LOOP_PROFILING is not set CONFIG_POST_EVENTS_FROM_ISR=y CONFIG_POST_EVENTS_FROM_IRAM_ISR=y CONFIG_GDBSTUB_SUPPORT_TASKS=y CONFIG_GDBSTUB_MAX_TASKS=32 +# default: # CONFIG_OTA_ALLOW_HTTP is not set # CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 +# default: # CONFIG_ESP_SYSTEM_PD_FLASH is not set CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 @@ -2402,12 +2807,17 @@ CONFIG_ESP32_XTAL_FREQ_40=y # CONFIG_ESP32_XTAL_FREQ_AUTO is not set CONFIG_ESP32_XTAL_FREQ=40 CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# default: # CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# default: # CONFIG_REDUCE_PHY_TX_POWER is not set +# default: # CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set +# default: # CONFIG_SPIRAM_SUPPORT is not set +# default: # CONFIG_ESP32_SPIRAM_SUPPORT is not set # CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y @@ -2433,10 +2843,12 @@ CONFIG_INT_WDT_TIMEOUT_MS=300 CONFIG_INT_WDT_CHECK_CPU1=y CONFIG_TASK_WDT=y CONFIG_ESP_TASK_WDT=y +# default: # CONFIG_TASK_WDT_PANIC is not set CONFIG_TASK_WDT_TIMEOUT_S=5 CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# default: # CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set CONFIG_ESP32_DEBUG_OCDAWARE=y CONFIG_BROWNOUT_DET=y @@ -2459,6 +2871,7 @@ CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set CONFIG_BROWNOUT_DET_LVL=0 CONFIG_ESP32_BROWNOUT_DET_LVL=0 +# default: # CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set CONFIG_IPC_TASK_STACK_SIZE=1024 CONFIG_TIMER_TASK_STACK_SIZE=3584 @@ -2469,6 +2882,7 @@ CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# default: # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP32_WIFI_TX_BA_WIN=6 @@ -2479,20 +2893,31 @@ CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +# default: # CONFIG_ESP32_WIFI_IRAM_OPT is not set +# default: # CONFIG_ESP32_WIFI_RX_IRAM_OPT is not set CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y CONFIG_WPA_MBEDTLS_CRYPTO=y CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# default: # CONFIG_WPA_WAPI_PSK is not set +# default: # CONFIG_WPA_11KV_SUPPORT is not set +# default: # CONFIG_WPA_MBO_SUPPORT is not set +# default: # CONFIG_WPA_DPP_SUPPORT is not set +# default: # CONFIG_WPA_11R_SUPPORT is not set +# default: # CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set +# default: # CONFIG_WPA_WPS_STRICT is not set +# default: # CONFIG_WPA_DEBUG_PRINT is not set +# default: # CONFIG_WPA_TESTING_OPTIONS is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set @@ -2500,8 +2925,10 @@ CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y CONFIG_TIMER_TASK_PRIORITY=1 CONFIG_TIMER_TASK_STACK_DEPTH=2048 CONFIG_TIMER_QUEUE_LENGTH=10 +# default: # CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set # CONFIG_HAL_ASSERTION_SILIENT is not set +# default: # CONFIG_L2_TO_L3_COPY is not set CONFIG_ESP_GRATUITOUS_ARP=y CONFIG_GARP_TMR_INTERVAL=60 @@ -2523,6 +2950,7 @@ CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set # CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# default: # CONFIG_PPP_SUPPORT is not set CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y @@ -2541,6 +2969,7 @@ CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +# default: # CONFIG_ESP32_ULP_COPROC_ENABLED is not set CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y From cc40b5980d73d8c372f8b8a853839aca8599a8cf Mon Sep 17 00:00:00 2001 From: h2zero Date: Wed, 25 Jun 2025 11:05:08 -0600 Subject: [PATCH 249/451] Fix structure and cmake files to build with esp-idf --- .gitignore | 1 + .gitmodules | 6 + CMakeLists.txt | 4 - include/BLE_Fitness_Machine_Service.h | 4 +- lib/ArduinoWebsockets | 1 + lib/TMCStepper | 1 + {src => main}/BLE_Client.cpp | 0 {src => main}/BLE_Common.cpp | 0 {src => main}/BLE_Custom_Characteristic.cpp | 0 {src => main}/BLE_Cycling_Power_Service.cpp | 0 {src => main}/BLE_Cycling_Speed_Cadence.cpp | 0 .../BLE_Device_Information_Service.cpp | 0 {src => main}/BLE_Firmware_Update.cpp | 0 {src => main}/BLE_Fitness_Machine_Service.cpp | 0 {src => main}/BLE_Heart_Service.cpp | 0 {src => main}/BLE_SB20_Service.cpp | 0 {src => main}/BLE_Server.cpp | 0 {src => main}/BLE_Setup.cpp | 0 {src => main}/BLE_Wattbike_Service.cpp | 0 main/CMakeLists.txt | 19 + {src => main}/DirConManager.cpp | 0 {src => main}/DirConMessage.cpp | 0 {src => main}/ERG_Mode.cpp | 0 {src => main}/HTTP_Server_Basic.cpp | 0 {src => main}/Main.cpp | 0 {src => main}/PowerTable_Helpers.cpp | 0 {src => main}/Power_Table.cpp | 0 {src => main}/SS2KLog.cpp | 0 {src => main}/SensorCollector.cpp | 0 {src => main}/SmartSpin_parameters.cpp | 0 {src => main}/UdpAppender.cpp | 0 {src => main}/WebsocketAppender.cpp | 0 {src => main}/gitTracking.md | 0 main/idf_component.yml | 7 + platformio.ini | 119 --- sdkconfig | 717 +++++++++++++++++- sdkconfig.defaults | 10 +- sdkconfig.old | 420 +++++++++- src/CMakeLists.txt | 6 - 39 files changed, 1174 insertions(+), 141 deletions(-) create mode 100644 .gitmodules create mode 160000 lib/ArduinoWebsockets create mode 160000 lib/TMCStepper rename {src => main}/BLE_Client.cpp (100%) rename {src => main}/BLE_Common.cpp (100%) rename {src => main}/BLE_Custom_Characteristic.cpp (100%) rename {src => main}/BLE_Cycling_Power_Service.cpp (100%) rename {src => main}/BLE_Cycling_Speed_Cadence.cpp (100%) rename {src => main}/BLE_Device_Information_Service.cpp (100%) rename {src => main}/BLE_Firmware_Update.cpp (100%) rename {src => main}/BLE_Fitness_Machine_Service.cpp (100%) rename {src => main}/BLE_Heart_Service.cpp (100%) rename {src => main}/BLE_SB20_Service.cpp (100%) rename {src => main}/BLE_Server.cpp (100%) rename {src => main}/BLE_Setup.cpp (100%) rename {src => main}/BLE_Wattbike_Service.cpp (100%) create mode 100644 main/CMakeLists.txt rename {src => main}/DirConManager.cpp (100%) rename {src => main}/DirConMessage.cpp (100%) rename {src => main}/ERG_Mode.cpp (100%) rename {src => main}/HTTP_Server_Basic.cpp (100%) rename {src => main}/Main.cpp (100%) rename {src => main}/PowerTable_Helpers.cpp (100%) rename {src => main}/Power_Table.cpp (100%) rename {src => main}/SS2KLog.cpp (100%) rename {src => main}/SensorCollector.cpp (100%) rename {src => main}/SmartSpin_parameters.cpp (100%) rename {src => main}/UdpAppender.cpp (100%) rename {src => main}/WebsocketAppender.cpp (100%) rename {src => main}/gitTracking.md (100%) create mode 100644 main/idf_component.yml delete mode 100644 platformio.ini delete mode 100644 src/CMakeLists.txt diff --git a/.gitignore b/.gitignore index 7795ffea..a6674331 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ build/CMakeCache.txt C/Users/ /build /managed_components +dependencies.lock \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..d2d2b5fa --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "lib/TMCStepper"] + path = lib/TMCStepper + url = https://github.com/teemuatlut/TMCStepper.git +[submodule "lib/ArduinoWebsockets"] + path = lib/ArduinoWebsockets + url = https://github.com/gilmaimon/ArduinoWebsockets.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a5f975e..fbd39142 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,3 @@ cmake_minimum_required(VERSION 3.16.0) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(SmartSpin2k) -include_directories( - ${PROJECT_SOURCE_DIR}/include - ${PROJECT_SOURCE_DIR}/src -) \ No newline at end of file diff --git a/include/BLE_Fitness_Machine_Service.h b/include/BLE_Fitness_Machine_Service.h index eefbdbe0..adf2184a 100644 --- a/include/BLE_Fitness_Machine_Service.h +++ b/include/BLE_Fitness_Machine_Service.h @@ -21,9 +21,9 @@ class BLE_Fitness_Machine_Service { private: BLEService *pFitnessMachineService; BLECharacteristic *fitnessMachineFeature; - BLECharacteristic *fitnessMachineIndoorBikeData; - BLECharacteristic *fitnessMachineStatusCharacteristic; BLECharacteristic *fitnessMachineControlPoint; + BLECharacteristic *fitnessMachineStatusCharacteristic; + BLECharacteristic *fitnessMachineIndoorBikeData; BLECharacteristic *fitnessMachineResistanceLevelRange; BLECharacteristic *fitnessMachinePowerRange; BLECharacteristic *fitnessMachineInclinationRange; diff --git a/lib/ArduinoWebsockets b/lib/ArduinoWebsockets new file mode 160000 index 00000000..26eecea6 --- /dev/null +++ b/lib/ArduinoWebsockets @@ -0,0 +1 @@ +Subproject commit 26eecea6d3d38224d1ee9c354cffa2eae50c786f diff --git a/lib/TMCStepper b/lib/TMCStepper new file mode 160000 index 00000000..c425c40f --- /dev/null +++ b/lib/TMCStepper @@ -0,0 +1 @@ +Subproject commit c425c40f0adfa24c1c21ce7d6428bcffc2c921ae diff --git a/src/BLE_Client.cpp b/main/BLE_Client.cpp similarity index 100% rename from src/BLE_Client.cpp rename to main/BLE_Client.cpp diff --git a/src/BLE_Common.cpp b/main/BLE_Common.cpp similarity index 100% rename from src/BLE_Common.cpp rename to main/BLE_Common.cpp diff --git a/src/BLE_Custom_Characteristic.cpp b/main/BLE_Custom_Characteristic.cpp similarity index 100% rename from src/BLE_Custom_Characteristic.cpp rename to main/BLE_Custom_Characteristic.cpp diff --git a/src/BLE_Cycling_Power_Service.cpp b/main/BLE_Cycling_Power_Service.cpp similarity index 100% rename from src/BLE_Cycling_Power_Service.cpp rename to main/BLE_Cycling_Power_Service.cpp diff --git a/src/BLE_Cycling_Speed_Cadence.cpp b/main/BLE_Cycling_Speed_Cadence.cpp similarity index 100% rename from src/BLE_Cycling_Speed_Cadence.cpp rename to main/BLE_Cycling_Speed_Cadence.cpp diff --git a/src/BLE_Device_Information_Service.cpp b/main/BLE_Device_Information_Service.cpp similarity index 100% rename from src/BLE_Device_Information_Service.cpp rename to main/BLE_Device_Information_Service.cpp diff --git a/src/BLE_Firmware_Update.cpp b/main/BLE_Firmware_Update.cpp similarity index 100% rename from src/BLE_Firmware_Update.cpp rename to main/BLE_Firmware_Update.cpp diff --git a/src/BLE_Fitness_Machine_Service.cpp b/main/BLE_Fitness_Machine_Service.cpp similarity index 100% rename from src/BLE_Fitness_Machine_Service.cpp rename to main/BLE_Fitness_Machine_Service.cpp diff --git a/src/BLE_Heart_Service.cpp b/main/BLE_Heart_Service.cpp similarity index 100% rename from src/BLE_Heart_Service.cpp rename to main/BLE_Heart_Service.cpp diff --git a/src/BLE_SB20_Service.cpp b/main/BLE_SB20_Service.cpp similarity index 100% rename from src/BLE_SB20_Service.cpp rename to main/BLE_SB20_Service.cpp diff --git a/src/BLE_Server.cpp b/main/BLE_Server.cpp similarity index 100% rename from src/BLE_Server.cpp rename to main/BLE_Server.cpp diff --git a/src/BLE_Setup.cpp b/main/BLE_Setup.cpp similarity index 100% rename from src/BLE_Setup.cpp rename to main/BLE_Setup.cpp diff --git a/src/BLE_Wattbike_Service.cpp b/main/BLE_Wattbike_Service.cpp similarity index 100% rename from src/BLE_Wattbike_Service.cpp rename to main/BLE_Wattbike_Service.cpp diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt new file mode 100644 index 00000000..c122670e --- /dev/null +++ b/main/CMakeLists.txt @@ -0,0 +1,19 @@ +# This file was automatically generated for projects +# without default 'CMakeLists.txt' file. + +FILE(GLOB_RECURSE app_sources *.cpp) +FILE(GLOB_RECURSE ss2k_sources ${CMAKE_SOURCE_DIR}/lib/SS2K/src/sensors) +FILE(GLOB_RECURSE aws_sources ${CMAKE_SOURCE_DIR}/lib/ArduinoWebsockets/src) +FILE(GLOB_RECURSE tmcs_sources ${CMAKE_SOURCE_DIR}/lib/TMCStepper/src/source) +set(srcs ${app_sources} ${ss2k_sources} ${aws_sources} ${tmcs_sources}) + +set(include_dirs + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/lib/SS2K/include + ${CMAKE_SOURCE_DIR}/lib/SS2K/include/sensors + ${CMAKE_SOURCE_DIR}/lib/ArduinoWebsockets + ${CMAKE_SOURCE_DIR}/lib/TMCStepper/src + ${CMAKE_SOURCE_DIR}/lib/TMCStepper/src/source +) + +idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "${include_dirs}") diff --git a/src/DirConManager.cpp b/main/DirConManager.cpp similarity index 100% rename from src/DirConManager.cpp rename to main/DirConManager.cpp diff --git a/src/DirConMessage.cpp b/main/DirConMessage.cpp similarity index 100% rename from src/DirConMessage.cpp rename to main/DirConMessage.cpp diff --git a/src/ERG_Mode.cpp b/main/ERG_Mode.cpp similarity index 100% rename from src/ERG_Mode.cpp rename to main/ERG_Mode.cpp diff --git a/src/HTTP_Server_Basic.cpp b/main/HTTP_Server_Basic.cpp similarity index 100% rename from src/HTTP_Server_Basic.cpp rename to main/HTTP_Server_Basic.cpp diff --git a/src/Main.cpp b/main/Main.cpp similarity index 100% rename from src/Main.cpp rename to main/Main.cpp diff --git a/src/PowerTable_Helpers.cpp b/main/PowerTable_Helpers.cpp similarity index 100% rename from src/PowerTable_Helpers.cpp rename to main/PowerTable_Helpers.cpp diff --git a/src/Power_Table.cpp b/main/Power_Table.cpp similarity index 100% rename from src/Power_Table.cpp rename to main/Power_Table.cpp diff --git a/src/SS2KLog.cpp b/main/SS2KLog.cpp similarity index 100% rename from src/SS2KLog.cpp rename to main/SS2KLog.cpp diff --git a/src/SensorCollector.cpp b/main/SensorCollector.cpp similarity index 100% rename from src/SensorCollector.cpp rename to main/SensorCollector.cpp diff --git a/src/SmartSpin_parameters.cpp b/main/SmartSpin_parameters.cpp similarity index 100% rename from src/SmartSpin_parameters.cpp rename to main/SmartSpin_parameters.cpp diff --git a/src/UdpAppender.cpp b/main/UdpAppender.cpp similarity index 100% rename from src/UdpAppender.cpp rename to main/UdpAppender.cpp diff --git a/src/WebsocketAppender.cpp b/main/WebsocketAppender.cpp similarity index 100% rename from src/WebsocketAppender.cpp rename to main/WebsocketAppender.cpp diff --git a/src/gitTracking.md b/main/gitTracking.md similarity index 100% rename from src/gitTracking.md rename to main/gitTracking.md diff --git a/main/idf_component.yml b/main/idf_component.yml new file mode 100644 index 00000000..d614a01a --- /dev/null +++ b/main/idf_component.yml @@ -0,0 +1,7 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/arduino-esp32: ^3.2.0 + h2zero/esp-nimble-cpp: ^2.3.1 + bblanchon/arduinojson: 7.3.1 + doudar/FastAccelStepper: + git: https://github.com/doudar/FastAccelStepper diff --git a/platformio.ini b/platformio.ini deleted file mode 100644 index cf55353b..00000000 --- a/platformio.ini +++ /dev/null @@ -1,119 +0,0 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; https://docs.platformio.org/page/projectconf.html -[platformio] -default_envs = release - -[esp32doit] -lib_ldf_mode = chain -lib_compat_mode = strict -platform = https://github.com/pioarduino/platform-espressif32/releases/download/54.03.20/platform-espressif32.zip -;platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10/platform-espressif32.zip -;platform = espressif32 -;platform_packages = -; framework-espidf @ https://github.com/espressif/esp-idf/releases/download/v5.3.2/esp-idf-v5.3.2.zip -board = esp32doit-devkit-v1 -framework = arduino, espidf -board_build.partitions = min_spiffs.csv -board_build.filesystem = littlefs -upload_speed = 921600 -monitor_speed = 115200 -monitor_filters = esp32_exception_decoder -board_build.embed_txtfiles = - ;managed_components/espressif__esp_insights/server_certs/https_server.crt - ;managed_components/espressif__esp_rainmaker/server_certs/rmaker_mqtt_server.crt - ;managed_components/espressif__esp_rainmaker/server_certs/rmaker_claim_service_server.crt - ;managed_components/espressif__esp_rainmaker/server_certs/rmaker_ota_server.crt -custom_component_remove = - espressif/esp_hosted - espressif/esp_wifi_remote - espressif/esp-dsp - espressif/esp32-camera - espressif/libsodium - espressif/esp-modbus - espressif/qrcode - espressif/esp_insights - espressif/esp_diag_data_store - espressif/esp_diagnostics - espressif/esp_rainmaker - espressif/zigbee - espressif/rmaker_common -build_flags = - !python git_tag_macro.py - !python build_date_macro.py - !python cert_updater.py - ;-DCONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y - ;-D CONFIG_SPI_SLAVE_ISR_IN_IRAM=n - ;-D CONFIG_NEWLIB_NANO_FORMAT=y - ;-D CONFIG_LWIP_IRAM_OPTIMIZATION=y - ;-D CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM=y - ;-D CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 - ;-D CONFIG_BT_NIMBLE_WHITELIST_SIZE=0 - ;-D CONFIG_MDNS_STRICT_MODE=1 - ;-D CORE_DEBUG_LEVEL=1 - -D ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=3500 - ;-D CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=8000 - ;-D CONFIG_BT_NIMBLE_MAX_CCCDS=0 - ;-D CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=1 - ;-D CONFIG_NIMBLE_STACK_USE_MEM_POOLS=1 - ;-D CONFIG_BT_NIMBLE_MAX_BONDS=1 - ;-D CONFIG_BT_NIMBLE_BLOCK_COUNT=20 - -std=gnu++17 -lib_deps = - https://github.com/h2zero/esp-nimble-cpp/ - https://github.com/teemuatlut/TMCStepper/archive/refs/tags/v0.7.3.zip - https://github.com/bblanchon/ArduinoJson/archive/refs/tags/v7.3.1.zip - ;https://github.com/gin66/FastAccelStepper/archive/refs/tags/0.31.2.zip - https://github.com/doudar/FastAccelStepper/ - https://github.com/gilmaimon/ArduinoWebsockets/archive/refs/tags/0.5.4.zip - ;https://github.com/Links2004/arduinoWebSockets - ;https://github.com/doudar/NimBLE-Arduino/ - -[env:release] -extends = esp32doit - -[env:debug] -extends = esp32doit -build_type = debug -build_flags = ${esp32doit.build_flags} -D__DEBUG__=1 -debug_tool = esp-prog -debug_init_break = tbreak setup -check_tool = cppcheck -check_flags = - --enable=all - --suppress=*:*/.pio/* - --suppress=*:*/lib/NimBLE-Arduino/* - --suppress=unmatchedSuppression - --suppress=missingIncludeSystem -check_severity = medium, high -check_skip_packages = true - -[env:native] -platform = native -lib_deps = - ArduinoFake - lib/ArduinoCompat - lib/SS2K -build_flags = - -Wunused - -Wunused-function - -Wunused-variable - -Wunreachable-code - -std=c++11 - -D PLATFORMIO_ENV_NATIVE -lib_ldf_mode = chain+ -lib_compat_mode = soft -check_tool = cppcheck -check_flags = - --enable=all - --suppress=*:*/.pio/*P - --suppress=unmatchedSuppression - --suppress=missingIncludeSystem -check_severity = medium, high -check_skip_packages = true diff --git a/sdkconfig b/sdkconfig index 1287da4d..4be13f57 100644 --- a/sdkconfig +++ b/sdkconfig @@ -406,6 +406,124 @@ CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table +# +# Arduino Configuration +# +CONFIG_ARDUINO_VARIANT="esp32" +CONFIG_ENABLE_ARDUINO_DEPENDS=y +CONFIG_AUTOSTART_ARDUINO=y +# CONFIG_ARDUINO_RUN_CORE0 is not set +CONFIG_ARDUINO_RUN_CORE1=y +# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_RUNNING_CORE=1 +CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 +# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set +CONFIG_ARDUINO_EVENT_RUN_CORE1=y +# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set +CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y +CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=2048 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 +CONFIG_ARDUINO_UDP_RUN_CORE0=y +# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set +# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_UDP_RUNNING_CORE=0 +CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 +# CONFIG_ARDUINO_ISR_IRAM is not set +# CONFIG_DISABLE_HAL_LOCKS is not set + +# +# Debug Log Configuration +# +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE is not set +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR=y +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=1 +# CONFIG_ARDUHAL_LOG_COLORS is not set +# CONFIG_ARDUHAL_ESP_LOG is not set +# end of Debug Log Configuration + +CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT=y +# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS is not set +CONFIG_ARDUHAL_PARTITION_SCHEME="default" +# CONFIG_AUTOCONNECT_WIFI is not set +# CONFIG_ARDUINO_SELECTIVE_COMPILATION is not set +# end of Arduino Configuration + +# +# ESP RainMaker Config +# +CONFIG_ESP_RMAKER_NO_CLAIM=y +# CONFIG_ESP_RMAKER_ASSISTED_CLAIM is not set +# CONFIG_ESP_RMAKER_USE_ESP_SECURE_CERT_MGR is not set +CONFIG_ESP_RMAKER_USE_NVS=y +CONFIG_ESP_RMAKER_CLAIM_TYPE=0 +# CONFIG_ESP_RMAKER_READ_MQTT_HOST_FROM_CONFIG is not set +# CONFIG_ESP_RMAKER_READ_NODE_ID_FROM_CERT_CN is not set +CONFIG_ESP_RMAKER_MQTT_USE_BASIC_INGEST_TOPICS=y +CONFIG_ESP_RMAKER_MQTT_ENABLE_BUDGETING=y +CONFIG_ESP_RMAKER_MQTT_DEFAULT_BUDGET=100 +CONFIG_ESP_RMAKER_MQTT_MAX_BUDGET=1024 +CONFIG_ESP_RMAKER_MQTT_BUDGET_REVIVE_PERIOD=5 +CONFIG_ESP_RMAKER_MQTT_BUDGET_REVIVE_COUNT=1 +CONFIG_ESP_RMAKER_MAX_PARAM_DATA_SIZE=1024 +# CONFIG_ESP_RMAKER_DISABLE_USER_MAPPING_PROV is not set +# CONFIG_ESP_RMAKER_USER_ID_CHECK is not set +# CONFIG_RMAKER_NAME_PARAM_CB is not set +# CONFIG_ESP_RMAKER_LOCAL_CTRL_FEATURE_ENABLE is not set +# CONFIG_ESP_RMAKER_LOCAL_CTRL_AUTO_ENABLE is not set +CONFIG_ESP_RMAKER_CONSOLE_UART_NUM_0=y +# CONFIG_ESP_RMAKER_CONSOLE_UART_NUM_1 is not set +CONFIG_ESP_RMAKER_CONSOLE_UART_NUM=0 +CONFIG_ESP_RMAKER_USE_CERT_BUNDLE=y + +# +# ESP RainMaker OTA Config +# +CONFIG_ESP_RMAKER_OTA_AUTOFETCH=y +CONFIG_ESP_RMAKER_OTA_AUTOFETCH_PERIOD=0 +# CONFIG_ESP_RMAKER_SKIP_COMMON_NAME_CHECK is not set +# CONFIG_ESP_RMAKER_SKIP_VERSION_CHECK is not set +# CONFIG_ESP_RMAKER_SKIP_SECURE_VERSION_CHECK is not set +# CONFIG_ESP_RMAKER_SKIP_PROJECT_NAME_CHECK is not set +CONFIG_ESP_RMAKER_OTA_HTTP_RX_BUFFER_SIZE=1024 +CONFIG_ESP_RMAKER_OTA_ROLLBACK_WAIT_PERIOD=90 +# CONFIG_ESP_RMAKER_OTA_DISABLE_AUTO_REBOOT is not set +CONFIG_ESP_RMAKER_OTA_TIME_SUPPORT=y +# end of ESP RainMaker OTA Config + +# +# ESP RainMaker Scheduling +# +CONFIG_ESP_RMAKER_SCHEDULING_MAX_SCHEDULES=10 +# end of ESP RainMaker Scheduling + +# +# ESP RainMaker Scenes +# +CONFIG_ESP_RMAKER_SCENES_MAX_SCENES=10 +# CONFIG_ESP_RMAKER_SCENES_DEACTIVATE_SUPPORT is not set +# end of ESP RainMaker Scenes + +# +# ESP RainMaker Command-Response +# +CONFIG_ESP_RMAKER_CMD_RESP_ENABLE=y +# CONFIG_ESP_RMAKER_CMD_RESP_TEST_ENABLE is not set +# end of ESP RainMaker Command-Response + +CONFIG_ESP_RMAKER_USING_NETWORK_PROV=y +# end of ESP RainMaker Config + # # Compiler options # @@ -460,10 +578,234 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # # Bluetooth # -# CONFIG_BT_ENABLED is not set +CONFIG_BT_ENABLED=y +# CONFIG_BT_BLUEDROID_ENABLED is not set +CONFIG_BT_NIMBLE_ENABLED=y +# CONFIG_BT_CONTROLLER_ONLY is not set +CONFIG_BT_CONTROLLER_ENABLED=y +# CONFIG_BT_CONTROLLER_DISABLED is not set + +# +# NimBLE Options +# +CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y +# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set +CONFIG_BT_NIMBLE_LOG_LEVEL_NONE=y +# CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_WARNING is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_INFO is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_DEBUG is not set +CONFIG_BT_NIMBLE_LOG_LEVEL=4 +CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 +CONFIG_BT_NIMBLE_MAX_BONDS=3 +CONFIG_BT_NIMBLE_MAX_CCCDS=8 +CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM=0 +CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y +# CONFIG_BT_NIMBLE_PINNED_TO_CORE_1 is not set +CONFIG_BT_NIMBLE_PINNED_TO_CORE=0 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=4096 +CONFIG_BT_NIMBLE_ROLE_CENTRAL=y +CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y +CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y +CONFIG_BT_NIMBLE_ROLE_OBSERVER=y +# CONFIG_BT_NIMBLE_NVS_PERSIST is not set +# CONFIG_BT_NIMBLE_SMP_ID_RESET is not set +CONFIG_BT_NIMBLE_SECURITY_ENABLE=y +CONFIG_BT_NIMBLE_SM_LEGACY=y +CONFIG_BT_NIMBLE_SM_SC=y +# CONFIG_BT_NIMBLE_SM_SC_DEBUG_KEYS is not set +CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_ENCRYPTION=y +CONFIG_BT_NIMBLE_SM_LVL=0 +CONFIG_BT_NIMBLE_SM_SC_ONLY=0 +# CONFIG_BT_NIMBLE_DEBUG is not set +# CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set +CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" +CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 +CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=256 +CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE=0 + +# +# Memory Settings +# +CONFIG_BT_NIMBLE_MSYS_1_BLOCK_COUNT=12 +CONFIG_BT_NIMBLE_MSYS_1_BLOCK_SIZE=256 +CONFIG_BT_NIMBLE_MSYS_2_BLOCK_COUNT=24 +CONFIG_BT_NIMBLE_MSYS_2_BLOCK_SIZE=320 +CONFIG_BT_NIMBLE_TRANSPORT_ACL_FROM_LL_COUNT=24 +CONFIG_BT_NIMBLE_TRANSPORT_ACL_SIZE=255 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_COUNT=30 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_DISCARD_COUNT=8 +CONFIG_BT_NIMBLE_L2CAP_COC_SDU_BUFF_COUNT=1 +# end of Memory Settings + +CONFIG_BT_NIMBLE_GATT_MAX_PROCS=4 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL=y +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y +CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 +# CONFIG_BT_NIMBLE_MESH is not set +CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y +CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 +# CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set +# CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set +CONFIG_BT_NIMBLE_WHITELIST_SIZE=12 +# CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set +# CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set +CONFIG_BT_NIMBLE_USE_ESP_TIMER=y +CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y +# CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set + +# +# GAP Service +# + +# +# GAP Appearance write permissions +# +# CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set +# end of GAP Appearance write permissions + +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ENC=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHN=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHR=0 +CONFIG_BT_NIMBLE_SVC_GAP_CAR_CHAR_NOT_SUPP=y +# CONFIG_BT_NIMBLE_SVC_GAP_CAR_NOT_SUPP is not set +# CONFIG_BT_NIMBLE_SVC_GAP_CAR_SUPP is not set +CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 + +# +# GAP device name write permissions +# +# CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set +# end of GAP device name write permissions + +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_ENC=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHEN=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHOR=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 +# CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL is not set +# end of GAP Service + +# +# BLE Services +# +# CONFIG_BT_NIMBLE_HID_SERVICE is not set +# CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY is not set + +# +# Device Information Service +# +# CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME is not set +# CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER is not set +# CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION is not set +# CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION is not set +# CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION is not set +# CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID is not set +# CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID is not set +# CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED is not set +# end of Device Information Service +# end of BLE Services + +# CONFIG_BT_NIMBLE_VS_SUPPORT is not set +# CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set +# CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set +# CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set +# CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT is not set + +# +# Host-controller Transport +# +CONFIG_UART_HW_FLOWCTRL_DISABLE=y +# CONFIG_UART_HW_FLOWCTRL_CTS_RTS is not set +CONFIG_BT_NIMBLE_HCI_UART_FLOW_CTRL=0 +CONFIG_BT_NIMBLE_HCI_UART_RTS_PIN=19 +CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 +# end of Host-controller Transport + +CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 +# CONFIG_BT_NIMBLE_SUBRATE is not set +# end of NimBLE Options + +# +# Controller Options +# +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +# CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set +# CONFIG_BTDM_CTRL_MODE_BTDM is not set +CONFIG_BTDM_CTRL_BLE_MAX_CONN=3 +CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 +CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 +CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 +CONFIG_BTDM_CTRL_PCM_FSYNCSHP_EFF=0 +CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=3 +CONFIG_BTDM_CTRL_BR_EDR_MIN_ENC_KEY_SZ_DFT_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CTRL_PINNED_TO_CORE_0=y +# CONFIG_BTDM_CTRL_PINNED_TO_CORE_1 is not set +CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 +CONFIG_BTDM_CTRL_HCI_MODE_VHCI=y +# CONFIG_BTDM_CTRL_HCI_MODE_UART_H4 is not set + +# +# MODEM SLEEP Options +# +CONFIG_BTDM_CTRL_MODEM_SLEEP=y +CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG=y +# CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_EVED is not set +CONFIG_BTDM_CTRL_LPCLK_SEL_MAIN_XTAL=y +# end of MODEM SLEEP Options + +CONFIG_BTDM_BLE_DEFAULT_SCA_250PPM=y +CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 +CONFIG_BTDM_BLE_SCAN_DUPL=y +CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y +# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA is not set +# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE is not set +CONFIG_BTDM_SCAN_DUPL_TYPE=0 +CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 +CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 +# CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set +CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y +# CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set +# CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set +CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y +CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 +CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 + +# +# BLE disconnects when Instant Passed (0x28) occurs +# +# CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set +# CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set +# end of BLE disconnects when Instant Passed (0x28) occurs + +CONFIG_BTDM_BLE_CHAN_ASS_EN=y +CONFIG_BTDM_BLE_PING_EN=y +# CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 is not set +CONFIG_BTDM_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_CTRL_HLI=y +# end of Controller Options + +# +# Common Options +# CONFIG_BT_ALARM_MAX_NUM=50 +# CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set +# end of Common Options + +# CONFIG_BT_HCI_LOG_DEBUG_EN is not set # end of Bluetooth +# CONFIG_BLE_MESH is not set + # # Console Library # @@ -598,6 +940,8 @@ CONFIG_ADC_DISABLE_DAC_OUTPUT=y # Wireless Coexistence # CONFIG_ESP_COEX_ENABLED=y +CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y +# CONFIG_ESP_COEX_POWER_MANAGEMENT is not set # CONFIG_ESP_COEX_GPIO_DEBUG is not set # end of Wireless Coexistence @@ -1017,8 +1361,7 @@ CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y # CONFIG_ESP_PANIC_HANDLER_IRAM is not set # CONFIG_ESP_DEBUG_STUBS_ENABLE is not set CONFIG_ESP_DEBUG_OCDAWARE=y -# CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set -CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y # # Brownout Detector @@ -1339,7 +1682,7 @@ CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -# CONFIG_LWIP_SO_RCVBUF is not set +CONFIG_LWIP_SO_RCVBUF=y # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP_DEFAULT_TTL=64 CONFIG_LWIP_IP4_FRAG=y @@ -1884,9 +2227,295 @@ CONFIG_WL_SECTOR_SIZE=4096 # CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_WIFI_PROV_BLE_BONDING is not set +CONFIG_WIFI_PROV_BLE_SEC_CONN=y +# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set +# CONFIG_WIFI_PROV_BLE_NOTIFY is not set +# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set # end of Wi-Fi Provisioning Manager + +# +# DSP Library +# +CONFIG_DSP_OPTIMIZATIONS_SUPPORTED=y +# CONFIG_DSP_ANSI is not set +CONFIG_DSP_OPTIMIZED=y +CONFIG_DSP_OPTIMIZATION=1 +# CONFIG_DSP_MAX_FFT_SIZE_512 is not set +# CONFIG_DSP_MAX_FFT_SIZE_1024 is not set +# CONFIG_DSP_MAX_FFT_SIZE_2048 is not set +CONFIG_DSP_MAX_FFT_SIZE_4096=y +# CONFIG_DSP_MAX_FFT_SIZE_8192 is not set +# CONFIG_DSP_MAX_FFT_SIZE_16384 is not set +# CONFIG_DSP_MAX_FFT_SIZE_32768 is not set +CONFIG_DSP_MAX_FFT_SIZE=4096 +# end of DSP Library + +# +# Modbus configuration +# +CONFIG_FMB_COMM_MODE_TCP_EN=y +CONFIG_FMB_TCP_PORT_DEFAULT=502 +CONFIG_FMB_TCP_PORT_MAX_CONN=5 +CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 +# CONFIG_FMB_TCP_UID_ENABLED is not set +CONFIG_FMB_COMM_MODE_RTU_EN=y +CONFIG_FMB_COMM_MODE_ASCII_EN=y +CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=3000 +CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_FMB_QUEUE_LENGTH=20 +CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 +CONFIG_FMB_SERIAL_BUF_SIZE=256 +CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 +CONFIG_FMB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS=0 +CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 +CONFIG_FMB_PORT_TASK_PRIO=10 +# CONFIG_FMB_PORT_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_FMB_PORT_TASK_AFFINITY_CPU0=y +# CONFIG_FMB_PORT_TASK_AFFINITY_CPU1 is not set +CONFIG_FMB_PORT_TASK_AFFINITY=0x0 +CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_FMB_CONTROLLER_SLAVE_ID_MAX_SIZE=32 +CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 +CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 +# CONFIG_FMB_TIMER_PORT_ENABLED is not set +# CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD is not set +# CONFIG_FMB_EXT_TYPE_SUPPORT is not set +# end of Modbus configuration + +# +# ESP serial flasher +# +CONFIG_SERIAL_FLASHER_MD5_ENABLED=y +CONFIG_SERIAL_FLASHER_RESET_HOLD_TIME_MS=100 +CONFIG_SERIAL_FLASHER_BOOT_HOLD_TIME_MS=50 +# end of ESP serial flasher + +# +# Zigbee +# +# CONFIG_ZB_ENABLED is not set +# end of Zigbee + +# +# Diagnostics data store +# +CONFIG_DIAG_DATA_STORE_RTC=y +# CONFIG_DIAG_DATA_STORE_FLASH is not set +# CONFIG_DIAG_DATA_STORE_DBG_PRINTS is not set +CONFIG_DIAG_DATA_STORE_REPORTING_WATERMARK_PERCENT=80 + +# +# RTC Store +# +CONFIG_RTC_STORE_DATA_SIZE=3072 +CONFIG_RTC_STORE_CRITICAL_DATA_SIZE=2048 +# end of RTC Store +# end of Diagnostics data store + +# +# Diagnostics +# +CONFIG_DIAG_LOG_MSG_ARG_FORMAT_TLV=y +# CONFIG_DIAG_LOG_MSG_ARG_FORMAT_STRING is not set +CONFIG_DIAG_LOG_MSG_ARG_MAX_SIZE=64 +CONFIG_DIAG_LOG_DROP_WIFI_LOGS=y +CONFIG_DIAG_ENABLE_METRICS=y +CONFIG_DIAG_METRICS_MAX_COUNT=20 +CONFIG_DIAG_ENABLE_HEAP_METRICS=y +CONFIG_DIAG_ENABLE_WIFI_METRICS=y +CONFIG_DIAG_ENABLE_VARIABLES=y +CONFIG_DIAG_VARIABLES_MAX_COUNT=20 +CONFIG_DIAG_ENABLE_NETWORK_VARIABLES=y +# CONFIG_DIAG_MORE_NETWORK_VARS is not set +# CONFIG_DIAG_USE_EXTERNAL_LOG_WRAP is not set +# end of Diagnostics + +# +# ESP Insights +# +# CONFIG_ESP_INSIGHTS_ENABLED is not set +# CONFIG_ESP_INSIGHTS_TRANSPORT_MQTT is not set +CONFIG_ESP_INSIGHTS_TRANSPORT_HTTPS=y +CONFIG_ESP_INSIGHTS_TRANSPORT_HTTPS_HOST="https://client.insights.espressif.com" +CONFIG_ESP_INSIGHTS_CLOUD_POST_MIN_INTERVAL_SEC=60 +CONFIG_ESP_INSIGHTS_CLOUD_POST_MAX_INTERVAL_SEC=240 +CONFIG_ESP_INSIGHTS_META_VERSION_10=y +# end of ESP Insights + +# +# esp-modem +# +CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y +# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set +CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 +# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set +# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set +CONFIG_ESP_MODEM_C_API_STR_MAX=128 +# CONFIG_ESP_MODEM_URC_HANDLER is not set +# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set +# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set +# end of esp-modem + +# +# OpenThread RCP Update +# +# CONFIG_AUTO_UPDATE_RCP is not set +# CONFIG_CREATE_OTA_IMAGE_WITH_RCP_FW is not set +# end of OpenThread RCP Update + +# +# ESP Secure Cert Manager +# +# CONFIG_ESP_SECURE_CERT_SUPPORT_LEGACY_FORMATS is not set +# end of ESP Secure Cert Manager + +# +# jsmn +# +# CONFIG_JSMN_PARENT_LINKS is not set +# CONFIG_JSMN_STRICT is not set +# CONFIG_JSMN_STATIC is not set +# end of jsmn + +# +# libsodium +# +# end of libsodium + +# +# mDNS +# +CONFIG_MDNS_MAX_INTERFACES=3 +CONFIG_MDNS_MAX_SERVICES=10 +CONFIG_MDNS_TASK_PRIORITY=1 +CONFIG_MDNS_ACTION_QUEUE_LEN=16 +CONFIG_MDNS_TASK_STACK_SIZE=4096 +# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_MDNS_TASK_AFFINITY_CPU0=y +# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set +CONFIG_MDNS_TASK_AFFINITY=0x0 + +# +# MDNS Memory Configuration +# +CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y +CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y +# CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set +# end of MDNS Memory Configuration + +CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 +CONFIG_MDNS_TIMER_PERIOD_MS=100 +# CONFIG_MDNS_NETWORKING_SOCKET is not set +# CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set +# CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set +CONFIG_MDNS_ENABLE_CONSOLE_CLI=y +# CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set +CONFIG_MDNS_MULTIPLE_INSTANCE=y + +# +# MDNS Predefined interfaces +# +CONFIG_MDNS_PREDEF_NETIF_STA=y +CONFIG_MDNS_PREDEF_NETIF_AP=y +CONFIG_MDNS_PREDEF_NETIF_ETH=y +# end of MDNS Predefined interfaces +# end of mDNS + +# +# Network Provisioning Manager +# +CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y +CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_NETWORK_PROV_BLE_BONDING is not set +CONFIG_NETWORK_PROV_BLE_SEC_CONN=y +# CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set +# CONFIG_NETWORK_PROV_KEEP_BLE_ON_AFTER_PROV is not set +CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y +# CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set +# end of Network Provisioning Manager + +# +# ESP RainMaker Common +# +CONFIG_ESP_RMAKER_LIB_ESP_MQTT=y +# CONFIG_ESP_RMAKER_LIB_AWS_IOT is not set +CONFIG_ESP_RMAKER_MQTT_GLUE_LIB=1 +CONFIG_ESP_RMAKER_MQTT_PORT_443=y +# CONFIG_ESP_RMAKER_MQTT_PORT_8883 is not set +CONFIG_ESP_RMAKER_MQTT_PORT=1 +# CONFIG_ESP_RMAKER_MQTT_PERSISTENT_SESSION is not set +CONFIG_ESP_RMAKER_MQTT_SEND_USERNAME=y +CONFIG_ESP_RMAKER_MQTT_PRODUCT_NAME="RMDev" +CONFIG_ESP_RMAKER_MQTT_PRODUCT_VERSION="1x0" +CONFIG_ESP_RMAKER_MQTT_PRODUCT_SKU="EX00" +CONFIG_ESP_RMAKER_MQTT_USE_CERT_BUNDLE=y +CONFIG_ESP_RMAKER_MAX_MQTT_SUBSCRIPTIONS=10 +CONFIG_ESP_RMAKER_MQTT_KEEP_ALIVE_INTERVAL=120 +CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI=y +CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_STACK=4096 +CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_PRIORITY=5 +CONFIG_ESP_RMAKER_FACTORY_PARTITION_NAME="fctry" +CONFIG_ESP_RMAKER_FACTORY_NAMESPACE="rmaker_creds" +CONFIG_ESP_RMAKER_DEF_TIMEZONE="Asia/Shanghai" +CONFIG_ESP_RMAKER_SNTP_SERVER_NAME="pool.ntp.org" +CONFIG_ESP_RMAKER_MAX_COMMANDS=10 +# end of ESP RainMaker Common + +# +# ESP-NimBLE-CPP configuration +# +CONFIG_NIMBLE_CPP_LOG_LEVEL_NONE=y +# CONFIG_NIMBLE_CPP_LOG_LEVEL_ERROR is not set +# CONFIG_NIMBLE_CPP_LOG_LEVEL_WARNING is not set +# CONFIG_NIMBLE_CPP_LOG_LEVEL_INFO is not set +# CONFIG_NIMBLE_CPP_LOG_LEVEL_DEBUG is not set +CONFIG_NIMBLE_CPP_LOG_LEVEL=0 +# CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR is not set +# CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT is not set +# CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT is not set +# CONFIG_NIMBLE_CPP_ENABLE_ADVERTISEMENT_TYPE_TEXT is not set +# CONFIG_NIMBLE_CPP_ADDR_FMT_EXCLUDE_DELIMITER is not set +# CONFIG_NIMBLE_CPP_ADDR_FMT_UPPERCASE is not set +# CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED is not set +CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH=20 +# CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED is not set +CONFIG_NIMBLE_CPP_FREERTOS_TASK_BLOCK_BIT=31 +# end of ESP-NimBLE-CPP configuration + +# +# LittleFS +# +# CONFIG_LITTLEFS_SDMMC_SUPPORT is not set +CONFIG_LITTLEFS_MAX_PARTITIONS=3 +CONFIG_LITTLEFS_PAGE_SIZE=256 +CONFIG_LITTLEFS_OBJ_NAME_LEN=64 +CONFIG_LITTLEFS_READ_SIZE=128 +CONFIG_LITTLEFS_WRITE_SIZE=128 +CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 +CONFIG_LITTLEFS_CACHE_SIZE=512 +CONFIG_LITTLEFS_BLOCK_CYCLES=512 +CONFIG_LITTLEFS_USE_MTIME=y +# CONFIG_LITTLEFS_USE_ONLY_HASH is not set +# CONFIG_LITTLEFS_HUMAN_READABLE is not set +CONFIG_LITTLEFS_MTIME_USE_SECONDS=y +# CONFIG_LITTLEFS_MTIME_USE_NONCE is not set +# CONFIG_LITTLEFS_SPIFFS_COMPAT is not set +# CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set +# CONFIG_LITTLEFS_FCNTL_GET_PATH is not set +# CONFIG_LITTLEFS_MULTIVERSION is not set +# CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set +CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y +# CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set +CONFIG_LITTLEFS_ASSERTS=y +# CONFIG_LITTLEFS_MMAP_PARTITION is not set +# end of LittleFS # end of Component config # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set @@ -1911,6 +2540,7 @@ CONFIG_LOG_BOOTLOADER_LEVEL=3 CONFIG_FLASHMODE_DIO=y # CONFIG_FLASHMODE_DOUT is not set CONFIG_MONITOR_BAUD=115200 +# CONFIG_ESP_RMAKER_LOCAL_CTRL_ENABLE is not set CONFIG_OPTIMIZATION_LEVEL_DEBUG=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y @@ -1929,7 +2559,72 @@ CONFIG_STACK_CHECK_NONE=y # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set CONFIG_ESP32_APPTRACE_DEST_NONE=y CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +# CONFIG_BLUEDROID_ENABLED is not set +CONFIG_NIMBLE_ENABLED=y +CONFIG_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y +# CONFIG_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set +CONFIG_NIMBLE_MAX_CONNECTIONS=7 +CONFIG_NIMBLE_MAX_BONDS=3 +CONFIG_NIMBLE_MAX_CCCDS=8 +CONFIG_NIMBLE_L2CAP_COC_MAX_NUM=0 +CONFIG_NIMBLE_PINNED_TO_CORE_0=y +# CONFIG_NIMBLE_PINNED_TO_CORE_1 is not set +CONFIG_NIMBLE_PINNED_TO_CORE=0 +CONFIG_NIMBLE_TASK_STACK_SIZE=4096 +CONFIG_BT_NIMBLE_TASK_STACK_SIZE=4096 +CONFIG_NIMBLE_ROLE_CENTRAL=y +CONFIG_NIMBLE_ROLE_PERIPHERAL=y +CONFIG_NIMBLE_ROLE_BROADCASTER=y +CONFIG_NIMBLE_ROLE_OBSERVER=y +# CONFIG_NIMBLE_NVS_PERSIST is not set +CONFIG_NIMBLE_SM_LEGACY=y +CONFIG_NIMBLE_SM_SC=y +# CONFIG_NIMBLE_SM_SC_DEBUG_KEYS is not set +CONFIG_BT_NIMBLE_SM_SC_LVL=0 +# CONFIG_NIMBLE_DEBUG is not set +CONFIG_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" +CONFIG_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 +CONFIG_NIMBLE_ATT_PREFERRED_MTU=256 +CONFIG_NIMBLE_SVC_GAP_APPEARANCE=0 +CONFIG_BT_NIMBLE_MSYS1_BLOCK_COUNT=12 +CONFIG_BT_NIMBLE_ACL_BUF_COUNT=24 +CONFIG_BT_NIMBLE_ACL_BUF_SIZE=255 +CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70 +CONFIG_BT_NIMBLE_HCI_EVT_HI_BUF_COUNT=30 +CONFIG_BT_NIMBLE_HCI_EVT_LO_BUF_COUNT=8 +CONFIG_NIMBLE_HS_FLOW_CTRL=y +CONFIG_NIMBLE_HS_FLOW_CTRL_ITVL=1000 +CONFIG_NIMBLE_HS_FLOW_CTRL_THRESH=2 +CONFIG_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y +CONFIG_NIMBLE_RPA_TIMEOUT=900 +# CONFIG_NIMBLE_MESH is not set +CONFIG_NIMBLE_CRYPTO_STACK_MBEDTLS=y +CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y +# CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY is not set +# CONFIG_BTDM_CONTROLLER_MODE_BTDM is not set +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=3 +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=3 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 +CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI=y +# CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4 is not set +CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=y +CONFIG_BLE_SCAN_DUPLICATE=y +CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y +# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA is not set +# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR is not set +CONFIG_SCAN_DUPLICATE_TYPE=0 +CONFIG_DUPLICATE_SCAN_CACHE_SIZE=100 +# CONFIG_BLE_MESH_SCAN_DUPLICATE_EN is not set +CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y +CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED=y +CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM=100 +CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 CONFIG_ADC2_DISABLE_DAC=y +CONFIG_SW_COEXIST_ENABLE=y +CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y +CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y # CONFIG_MCPWM_ISR_IN_IRAM is not set # CONFIG_EVENT_LOOP_PROFILING is not set CONFIG_POST_EVENTS_FROM_ISR=y @@ -2100,4 +2795,18 @@ CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=3000 +CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_MB_QUEUE_LENGTH=20 +CONFIG_MB_SERIAL_TASK_STACK_SIZE=4096 +CONFIG_MB_SERIAL_BUF_SIZE=256 +CONFIG_MB_SERIAL_TASK_PRIO=10 +CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_MB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_MB_CONTROLLER_STACK_SIZE=4096 +CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 +# CONFIG_MB_TIMER_PORT_ENABLED is not set +CONFIG_NIMBLE_ENABLED=y # End of deprecated options diff --git a/sdkconfig.defaults b/sdkconfig.defaults index d50929ea..75cef2f8 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -1,6 +1,12 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) 5.4.1 Project Minimal Configuration +# +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_AUTOSTART_ARDUINO=y -# CONFIG_WS2812_LED_ENABLE is not set +CONFIG_ESP_RMAKER_NO_CLAIM=y +CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_BT_NIMBLE_LOG_LEVEL_NONE=y +CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 CONFIG_FREERTOS_HZ=1000 CONFIG_MBEDTLS_PSK_MODES=y CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y -CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y \ No newline at end of file diff --git a/sdkconfig.old b/sdkconfig.old index 07c9dd84..2ed7e033 100644 --- a/sdkconfig.old +++ b/sdkconfig.old @@ -374,14 +374,14 @@ CONFIG_ESPTOOLPY_FLASHFREQ_40M=y # CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set CONFIG_ESPTOOLPY_FLASHFREQ="40m" # CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y -# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y # CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="2MB" +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set @@ -406,6 +406,123 @@ CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table +# +# Arduino Configuration +# +CONFIG_ARDUINO_VARIANT="esp32" +CONFIG_ENABLE_ARDUINO_DEPENDS=y +CONFIG_AUTOSTART_ARDUINO=y +# CONFIG_ARDUINO_RUN_CORE0 is not set +CONFIG_ARDUINO_RUN_CORE1=y +# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_RUNNING_CORE=1 +CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 +# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set +CONFIG_ARDUINO_EVENT_RUN_CORE1=y +# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set +CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y +CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=2048 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 +CONFIG_ARDUINO_UDP_RUN_CORE0=y +# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set +# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_UDP_RUNNING_CORE=0 +CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 +# CONFIG_ARDUINO_ISR_IRAM is not set +# CONFIG_DISABLE_HAL_LOCKS is not set + +# +# Debug Log Configuration +# +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE is not set +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR=y +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=1 +# CONFIG_ARDUHAL_LOG_COLORS is not set +# CONFIG_ARDUHAL_ESP_LOG is not set +# end of Debug Log Configuration + +CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT=y +# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS is not set +CONFIG_ARDUHAL_PARTITION_SCHEME="default" +# CONFIG_AUTOCONNECT_WIFI is not set +# CONFIG_ARDUINO_SELECTIVE_COMPILATION is not set +# end of Arduino Configuration + +# +# ESP RainMaker Config +# +CONFIG_ESP_RMAKER_NO_CLAIM=y +# CONFIG_ESP_RMAKER_USE_ESP_SECURE_CERT_MGR is not set +CONFIG_ESP_RMAKER_USE_NVS=y +CONFIG_ESP_RMAKER_CLAIM_TYPE=0 +# CONFIG_ESP_RMAKER_READ_MQTT_HOST_FROM_CONFIG is not set +# CONFIG_ESP_RMAKER_READ_NODE_ID_FROM_CERT_CN is not set +CONFIG_ESP_RMAKER_MQTT_USE_BASIC_INGEST_TOPICS=y +CONFIG_ESP_RMAKER_MQTT_ENABLE_BUDGETING=y +CONFIG_ESP_RMAKER_MQTT_DEFAULT_BUDGET=100 +CONFIG_ESP_RMAKER_MQTT_MAX_BUDGET=1024 +CONFIG_ESP_RMAKER_MQTT_BUDGET_REVIVE_PERIOD=5 +CONFIG_ESP_RMAKER_MQTT_BUDGET_REVIVE_COUNT=1 +CONFIG_ESP_RMAKER_MAX_PARAM_DATA_SIZE=1024 +# CONFIG_ESP_RMAKER_DISABLE_USER_MAPPING_PROV is not set +# CONFIG_ESP_RMAKER_USER_ID_CHECK is not set +# CONFIG_RMAKER_NAME_PARAM_CB is not set +# CONFIG_ESP_RMAKER_LOCAL_CTRL_FEATURE_ENABLE is not set +# CONFIG_ESP_RMAKER_LOCAL_CTRL_AUTO_ENABLE is not set +CONFIG_ESP_RMAKER_CONSOLE_UART_NUM_0=y +# CONFIG_ESP_RMAKER_CONSOLE_UART_NUM_1 is not set +CONFIG_ESP_RMAKER_CONSOLE_UART_NUM=0 +CONFIG_ESP_RMAKER_USE_CERT_BUNDLE=y + +# +# ESP RainMaker OTA Config +# +CONFIG_ESP_RMAKER_OTA_AUTOFETCH=y +CONFIG_ESP_RMAKER_OTA_AUTOFETCH_PERIOD=0 +# CONFIG_ESP_RMAKER_SKIP_COMMON_NAME_CHECK is not set +# CONFIG_ESP_RMAKER_SKIP_VERSION_CHECK is not set +# CONFIG_ESP_RMAKER_SKIP_SECURE_VERSION_CHECK is not set +# CONFIG_ESP_RMAKER_SKIP_PROJECT_NAME_CHECK is not set +CONFIG_ESP_RMAKER_OTA_HTTP_RX_BUFFER_SIZE=1024 +CONFIG_ESP_RMAKER_OTA_ROLLBACK_WAIT_PERIOD=90 +# CONFIG_ESP_RMAKER_OTA_DISABLE_AUTO_REBOOT is not set +CONFIG_ESP_RMAKER_OTA_TIME_SUPPORT=y +# end of ESP RainMaker OTA Config + +# +# ESP RainMaker Scheduling +# +CONFIG_ESP_RMAKER_SCHEDULING_MAX_SCHEDULES=10 +# end of ESP RainMaker Scheduling + +# +# ESP RainMaker Scenes +# +CONFIG_ESP_RMAKER_SCENES_MAX_SCENES=10 +# CONFIG_ESP_RMAKER_SCENES_DEACTIVATE_SUPPORT is not set +# end of ESP RainMaker Scenes + +# +# ESP RainMaker Command-Response +# +CONFIG_ESP_RMAKER_CMD_RESP_ENABLE=y +# CONFIG_ESP_RMAKER_CMD_RESP_TEST_ENABLE is not set +# end of ESP RainMaker Command-Response + +CONFIG_ESP_RMAKER_USING_NETWORK_PROV=y +# end of ESP RainMaker Config + # # Compiler options # @@ -461,6 +578,7 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # Bluetooth # # CONFIG_BT_ENABLED is not set +# CONFIG_BT_NIMBLE_ENABLED is not set CONFIG_BT_ALARM_MAX_NUM=50 # end of Bluetooth @@ -1339,7 +1457,7 @@ CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -# CONFIG_LWIP_SO_RCVBUF is not set +CONFIG_LWIP_SO_RCVBUF=y # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP_DEFAULT_TTL=64 CONFIG_LWIP_IP4_FRAG=y @@ -1887,6 +2005,284 @@ CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set # end of Wi-Fi Provisioning Manager + +# +# DSP Library +# +CONFIG_DSP_OPTIMIZATIONS_SUPPORTED=y +# CONFIG_DSP_ANSI is not set +CONFIG_DSP_OPTIMIZED=y +CONFIG_DSP_OPTIMIZATION=1 +# CONFIG_DSP_MAX_FFT_SIZE_512 is not set +# CONFIG_DSP_MAX_FFT_SIZE_1024 is not set +# CONFIG_DSP_MAX_FFT_SIZE_2048 is not set +CONFIG_DSP_MAX_FFT_SIZE_4096=y +# CONFIG_DSP_MAX_FFT_SIZE_8192 is not set +# CONFIG_DSP_MAX_FFT_SIZE_16384 is not set +# CONFIG_DSP_MAX_FFT_SIZE_32768 is not set +CONFIG_DSP_MAX_FFT_SIZE=4096 +# end of DSP Library + +# +# Modbus configuration +# +CONFIG_FMB_COMM_MODE_TCP_EN=y +CONFIG_FMB_TCP_PORT_DEFAULT=502 +CONFIG_FMB_TCP_PORT_MAX_CONN=5 +CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 +# CONFIG_FMB_TCP_UID_ENABLED is not set +CONFIG_FMB_COMM_MODE_RTU_EN=y +CONFIG_FMB_COMM_MODE_ASCII_EN=y +CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=3000 +CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_FMB_QUEUE_LENGTH=20 +CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 +CONFIG_FMB_SERIAL_BUF_SIZE=256 +CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 +CONFIG_FMB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS=0 +CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 +CONFIG_FMB_PORT_TASK_PRIO=10 +# CONFIG_FMB_PORT_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_FMB_PORT_TASK_AFFINITY_CPU0=y +# CONFIG_FMB_PORT_TASK_AFFINITY_CPU1 is not set +CONFIG_FMB_PORT_TASK_AFFINITY=0x0 +CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_FMB_CONTROLLER_SLAVE_ID_MAX_SIZE=32 +CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 +CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 +# CONFIG_FMB_TIMER_PORT_ENABLED is not set +# CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD is not set +# CONFIG_FMB_EXT_TYPE_SUPPORT is not set +# end of Modbus configuration + +# +# ESP serial flasher +# +CONFIG_SERIAL_FLASHER_MD5_ENABLED=y +CONFIG_SERIAL_FLASHER_RESET_HOLD_TIME_MS=100 +CONFIG_SERIAL_FLASHER_BOOT_HOLD_TIME_MS=50 +# end of ESP serial flasher + +# +# Zigbee +# +# CONFIG_ZB_ENABLED is not set +# end of Zigbee + +# +# Diagnostics data store +# +CONFIG_DIAG_DATA_STORE_RTC=y +# CONFIG_DIAG_DATA_STORE_FLASH is not set +# CONFIG_DIAG_DATA_STORE_DBG_PRINTS is not set +CONFIG_DIAG_DATA_STORE_REPORTING_WATERMARK_PERCENT=80 + +# +# RTC Store +# +CONFIG_RTC_STORE_DATA_SIZE=3072 +CONFIG_RTC_STORE_CRITICAL_DATA_SIZE=2048 +# end of RTC Store +# end of Diagnostics data store + +# +# Diagnostics +# +CONFIG_DIAG_LOG_MSG_ARG_FORMAT_TLV=y +# CONFIG_DIAG_LOG_MSG_ARG_FORMAT_STRING is not set +CONFIG_DIAG_LOG_MSG_ARG_MAX_SIZE=64 +CONFIG_DIAG_LOG_DROP_WIFI_LOGS=y +CONFIG_DIAG_ENABLE_METRICS=y +CONFIG_DIAG_METRICS_MAX_COUNT=20 +CONFIG_DIAG_ENABLE_HEAP_METRICS=y +CONFIG_DIAG_ENABLE_WIFI_METRICS=y +CONFIG_DIAG_ENABLE_VARIABLES=y +CONFIG_DIAG_VARIABLES_MAX_COUNT=20 +CONFIG_DIAG_ENABLE_NETWORK_VARIABLES=y +# CONFIG_DIAG_MORE_NETWORK_VARS is not set +# CONFIG_DIAG_USE_EXTERNAL_LOG_WRAP is not set +# end of Diagnostics + +# +# ESP Insights +# +# CONFIG_ESP_INSIGHTS_ENABLED is not set +# CONFIG_ESP_INSIGHTS_TRANSPORT_MQTT is not set +CONFIG_ESP_INSIGHTS_TRANSPORT_HTTPS=y +CONFIG_ESP_INSIGHTS_TRANSPORT_HTTPS_HOST="https://client.insights.espressif.com" +CONFIG_ESP_INSIGHTS_CLOUD_POST_MIN_INTERVAL_SEC=60 +CONFIG_ESP_INSIGHTS_CLOUD_POST_MAX_INTERVAL_SEC=240 +CONFIG_ESP_INSIGHTS_META_VERSION_10=y +# end of ESP Insights + +# +# esp-modem +# +CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y +# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set +CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 +# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set +# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set +CONFIG_ESP_MODEM_C_API_STR_MAX=128 +# CONFIG_ESP_MODEM_URC_HANDLER is not set +# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set +# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set +# end of esp-modem + +# +# OpenThread RCP Update +# +# CONFIG_AUTO_UPDATE_RCP is not set +# CONFIG_CREATE_OTA_IMAGE_WITH_RCP_FW is not set +# end of OpenThread RCP Update + +# +# ESP Secure Cert Manager +# +# CONFIG_ESP_SECURE_CERT_SUPPORT_LEGACY_FORMATS is not set +# end of ESP Secure Cert Manager + +# +# jsmn +# +# CONFIG_JSMN_PARENT_LINKS is not set +# CONFIG_JSMN_STRICT is not set +# CONFIG_JSMN_STATIC is not set +# end of jsmn + +# +# libsodium +# +# end of libsodium + +# +# mDNS +# +CONFIG_MDNS_MAX_INTERFACES=3 +CONFIG_MDNS_MAX_SERVICES=10 +CONFIG_MDNS_TASK_PRIORITY=1 +CONFIG_MDNS_ACTION_QUEUE_LEN=16 +CONFIG_MDNS_TASK_STACK_SIZE=4096 +# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_MDNS_TASK_AFFINITY_CPU0=y +# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set +CONFIG_MDNS_TASK_AFFINITY=0x0 + +# +# MDNS Memory Configuration +# +CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y +CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y +# CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set +# end of MDNS Memory Configuration + +CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 +CONFIG_MDNS_TIMER_PERIOD_MS=100 +# CONFIG_MDNS_NETWORKING_SOCKET is not set +# CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set +# CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set +CONFIG_MDNS_ENABLE_CONSOLE_CLI=y +# CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set +CONFIG_MDNS_MULTIPLE_INSTANCE=y + +# +# MDNS Predefined interfaces +# +CONFIG_MDNS_PREDEF_NETIF_STA=y +CONFIG_MDNS_PREDEF_NETIF_AP=y +CONFIG_MDNS_PREDEF_NETIF_ETH=y +# end of MDNS Predefined interfaces +# end of mDNS + +# +# Network Provisioning Manager +# +CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y +CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set +CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y +# CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set +# end of Network Provisioning Manager + +# +# ESP RainMaker Common +# +CONFIG_ESP_RMAKER_LIB_ESP_MQTT=y +# CONFIG_ESP_RMAKER_LIB_AWS_IOT is not set +CONFIG_ESP_RMAKER_MQTT_GLUE_LIB=1 +CONFIG_ESP_RMAKER_MQTT_PORT_443=y +# CONFIG_ESP_RMAKER_MQTT_PORT_8883 is not set +CONFIG_ESP_RMAKER_MQTT_PORT=1 +# CONFIG_ESP_RMAKER_MQTT_PERSISTENT_SESSION is not set +CONFIG_ESP_RMAKER_MQTT_SEND_USERNAME=y +CONFIG_ESP_RMAKER_MQTT_PRODUCT_NAME="RMDev" +CONFIG_ESP_RMAKER_MQTT_PRODUCT_VERSION="1x0" +CONFIG_ESP_RMAKER_MQTT_PRODUCT_SKU="EX00" +CONFIG_ESP_RMAKER_MQTT_USE_CERT_BUNDLE=y +CONFIG_ESP_RMAKER_MAX_MQTT_SUBSCRIPTIONS=10 +CONFIG_ESP_RMAKER_MQTT_KEEP_ALIVE_INTERVAL=120 +CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI=y +CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_STACK=4096 +CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_PRIORITY=5 +CONFIG_ESP_RMAKER_FACTORY_PARTITION_NAME="fctry" +CONFIG_ESP_RMAKER_FACTORY_NAMESPACE="rmaker_creds" +CONFIG_ESP_RMAKER_DEF_TIMEZONE="Asia/Shanghai" +CONFIG_ESP_RMAKER_SNTP_SERVER_NAME="pool.ntp.org" +CONFIG_ESP_RMAKER_MAX_COMMANDS=10 +# end of ESP RainMaker Common + +# +# ESP-NimBLE-CPP configuration +# +CONFIG_NIMBLE_CPP_LOG_LEVEL_NONE=y +# CONFIG_NIMBLE_CPP_LOG_LEVEL_ERROR is not set +# CONFIG_NIMBLE_CPP_LOG_LEVEL_WARNING is not set +# CONFIG_NIMBLE_CPP_LOG_LEVEL_INFO is not set +# CONFIG_NIMBLE_CPP_LOG_LEVEL_DEBUG is not set +CONFIG_NIMBLE_CPP_LOG_LEVEL=0 +# CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR is not set +# CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT is not set +# CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT is not set +# CONFIG_NIMBLE_CPP_ENABLE_ADVERTISEMENT_TYPE_TEXT is not set +# CONFIG_NIMBLE_CPP_ADDR_FMT_EXCLUDE_DELIMITER is not set +# CONFIG_NIMBLE_CPP_ADDR_FMT_UPPERCASE is not set +# CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED is not set +CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH=20 +# CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED is not set +CONFIG_NIMBLE_CPP_FREERTOS_TASK_BLOCK_BIT=31 +# end of ESP-NimBLE-CPP configuration + +# +# LittleFS +# +# CONFIG_LITTLEFS_SDMMC_SUPPORT is not set +CONFIG_LITTLEFS_MAX_PARTITIONS=3 +CONFIG_LITTLEFS_PAGE_SIZE=256 +CONFIG_LITTLEFS_OBJ_NAME_LEN=64 +CONFIG_LITTLEFS_READ_SIZE=128 +CONFIG_LITTLEFS_WRITE_SIZE=128 +CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 +CONFIG_LITTLEFS_CACHE_SIZE=512 +CONFIG_LITTLEFS_BLOCK_CYCLES=512 +CONFIG_LITTLEFS_USE_MTIME=y +# CONFIG_LITTLEFS_USE_ONLY_HASH is not set +# CONFIG_LITTLEFS_HUMAN_READABLE is not set +CONFIG_LITTLEFS_MTIME_USE_SECONDS=y +# CONFIG_LITTLEFS_MTIME_USE_NONCE is not set +# CONFIG_LITTLEFS_SPIFFS_COMPAT is not set +# CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set +# CONFIG_LITTLEFS_FCNTL_GET_PATH is not set +# CONFIG_LITTLEFS_MULTIVERSION is not set +# CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set +CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y +# CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set +CONFIG_LITTLEFS_ASSERTS=y +# CONFIG_LITTLEFS_MMAP_PARTITION is not set +# end of LittleFS # end of Component config # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set @@ -1911,6 +2307,7 @@ CONFIG_LOG_BOOTLOADER_LEVEL=3 CONFIG_FLASHMODE_DIO=y # CONFIG_FLASHMODE_DOUT is not set CONFIG_MONITOR_BAUD=115200 +# CONFIG_ESP_RMAKER_LOCAL_CTRL_ENABLE is not set CONFIG_OPTIMIZATION_LEVEL_DEBUG=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y @@ -1929,6 +2326,7 @@ CONFIG_STACK_CHECK_NONE=y # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set CONFIG_ESP32_APPTRACE_DEST_NONE=y CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +# CONFIG_NIMBLE_ENABLED is not set CONFIG_ADC2_DISABLE_DAC=y # CONFIG_MCPWM_ISR_IN_IRAM is not set # CONFIG_EVENT_LOOP_PROFILING is not set @@ -2100,4 +2498,18 @@ CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=3000 +CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_MB_QUEUE_LENGTH=20 +CONFIG_MB_SERIAL_TASK_STACK_SIZE=4096 +CONFIG_MB_SERIAL_BUF_SIZE=256 +CONFIG_MB_SERIAL_TASK_PRIO=10 +CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_MB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_MB_CONTROLLER_STACK_SIZE=4096 +CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 +# CONFIG_MB_TIMER_PORT_ENABLED is not set +# CONFIG_NIMBLE_ENABLED is not set # End of deprecated options diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index 483bc0cf..00000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# This file was automatically generated for projects -# without default 'CMakeLists.txt' file. - -FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*) - -idf_component_register(SRCS ${app_sources}) From a8926a2ad2965d92001d7f826db353fe725be592 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 25 Jun 2025 12:52:30 -0500 Subject: [PATCH 250/451] Revert "Fix structure and cmake files to build with esp-idf" --- .gitignore | 1 - .gitmodules | 6 - CMakeLists.txt | 4 + include/BLE_Fitness_Machine_Service.h | 4 +- lib/ArduinoWebsockets | 1 - lib/TMCStepper | 1 - main/CMakeLists.txt | 19 - main/idf_component.yml | 7 - platformio.ini | 119 +++ sdkconfig | 717 +----------------- sdkconfig.defaults | 10 +- sdkconfig.old | 420 +--------- {main => src}/BLE_Client.cpp | 0 {main => src}/BLE_Common.cpp | 0 {main => src}/BLE_Custom_Characteristic.cpp | 0 {main => src}/BLE_Cycling_Power_Service.cpp | 0 {main => src}/BLE_Cycling_Speed_Cadence.cpp | 0 .../BLE_Device_Information_Service.cpp | 0 {main => src}/BLE_Firmware_Update.cpp | 0 {main => src}/BLE_Fitness_Machine_Service.cpp | 0 {main => src}/BLE_Heart_Service.cpp | 0 {main => src}/BLE_SB20_Service.cpp | 0 {main => src}/BLE_Server.cpp | 0 {main => src}/BLE_Setup.cpp | 0 {main => src}/BLE_Wattbike_Service.cpp | 0 src/CMakeLists.txt | 6 + {main => src}/DirConManager.cpp | 0 {main => src}/DirConMessage.cpp | 0 {main => src}/ERG_Mode.cpp | 0 {main => src}/HTTP_Server_Basic.cpp | 0 {main => src}/Main.cpp | 0 {main => src}/PowerTable_Helpers.cpp | 0 {main => src}/Power_Table.cpp | 0 {main => src}/SS2KLog.cpp | 0 {main => src}/SensorCollector.cpp | 0 {main => src}/SmartSpin_parameters.cpp | 0 {main => src}/UdpAppender.cpp | 0 {main => src}/WebsocketAppender.cpp | 0 {main => src}/gitTracking.md | 0 39 files changed, 141 insertions(+), 1174 deletions(-) delete mode 100644 .gitmodules delete mode 160000 lib/ArduinoWebsockets delete mode 160000 lib/TMCStepper delete mode 100644 main/CMakeLists.txt delete mode 100644 main/idf_component.yml create mode 100644 platformio.ini rename {main => src}/BLE_Client.cpp (100%) rename {main => src}/BLE_Common.cpp (100%) rename {main => src}/BLE_Custom_Characteristic.cpp (100%) rename {main => src}/BLE_Cycling_Power_Service.cpp (100%) rename {main => src}/BLE_Cycling_Speed_Cadence.cpp (100%) rename {main => src}/BLE_Device_Information_Service.cpp (100%) rename {main => src}/BLE_Firmware_Update.cpp (100%) rename {main => src}/BLE_Fitness_Machine_Service.cpp (100%) rename {main => src}/BLE_Heart_Service.cpp (100%) rename {main => src}/BLE_SB20_Service.cpp (100%) rename {main => src}/BLE_Server.cpp (100%) rename {main => src}/BLE_Setup.cpp (100%) rename {main => src}/BLE_Wattbike_Service.cpp (100%) create mode 100644 src/CMakeLists.txt rename {main => src}/DirConManager.cpp (100%) rename {main => src}/DirConMessage.cpp (100%) rename {main => src}/ERG_Mode.cpp (100%) rename {main => src}/HTTP_Server_Basic.cpp (100%) rename {main => src}/Main.cpp (100%) rename {main => src}/PowerTable_Helpers.cpp (100%) rename {main => src}/Power_Table.cpp (100%) rename {main => src}/SS2KLog.cpp (100%) rename {main => src}/SensorCollector.cpp (100%) rename {main => src}/SmartSpin_parameters.cpp (100%) rename {main => src}/UdpAppender.cpp (100%) rename {main => src}/WebsocketAppender.cpp (100%) rename {main => src}/gitTracking.md (100%) diff --git a/.gitignore b/.gitignore index a6674331..7795ffea 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,3 @@ build/CMakeCache.txt C/Users/ /build /managed_components -dependencies.lock \ No newline at end of file diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index d2d2b5fa..00000000 --- a/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "lib/TMCStepper"] - path = lib/TMCStepper - url = https://github.com/teemuatlut/TMCStepper.git -[submodule "lib/ArduinoWebsockets"] - path = lib/ArduinoWebsockets - url = https://github.com/gilmaimon/ArduinoWebsockets.git diff --git a/CMakeLists.txt b/CMakeLists.txt index fbd39142..9a5f975e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,7 @@ cmake_minimum_required(VERSION 3.16.0) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(SmartSpin2k) +include_directories( + ${PROJECT_SOURCE_DIR}/include + ${PROJECT_SOURCE_DIR}/src +) \ No newline at end of file diff --git a/include/BLE_Fitness_Machine_Service.h b/include/BLE_Fitness_Machine_Service.h index adf2184a..eefbdbe0 100644 --- a/include/BLE_Fitness_Machine_Service.h +++ b/include/BLE_Fitness_Machine_Service.h @@ -21,9 +21,9 @@ class BLE_Fitness_Machine_Service { private: BLEService *pFitnessMachineService; BLECharacteristic *fitnessMachineFeature; - BLECharacteristic *fitnessMachineControlPoint; - BLECharacteristic *fitnessMachineStatusCharacteristic; BLECharacteristic *fitnessMachineIndoorBikeData; + BLECharacteristic *fitnessMachineStatusCharacteristic; + BLECharacteristic *fitnessMachineControlPoint; BLECharacteristic *fitnessMachineResistanceLevelRange; BLECharacteristic *fitnessMachinePowerRange; BLECharacteristic *fitnessMachineInclinationRange; diff --git a/lib/ArduinoWebsockets b/lib/ArduinoWebsockets deleted file mode 160000 index 26eecea6..00000000 --- a/lib/ArduinoWebsockets +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 26eecea6d3d38224d1ee9c354cffa2eae50c786f diff --git a/lib/TMCStepper b/lib/TMCStepper deleted file mode 160000 index c425c40f..00000000 --- a/lib/TMCStepper +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c425c40f0adfa24c1c21ce7d6428bcffc2c921ae diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt deleted file mode 100644 index c122670e..00000000 --- a/main/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# This file was automatically generated for projects -# without default 'CMakeLists.txt' file. - -FILE(GLOB_RECURSE app_sources *.cpp) -FILE(GLOB_RECURSE ss2k_sources ${CMAKE_SOURCE_DIR}/lib/SS2K/src/sensors) -FILE(GLOB_RECURSE aws_sources ${CMAKE_SOURCE_DIR}/lib/ArduinoWebsockets/src) -FILE(GLOB_RECURSE tmcs_sources ${CMAKE_SOURCE_DIR}/lib/TMCStepper/src/source) -set(srcs ${app_sources} ${ss2k_sources} ${aws_sources} ${tmcs_sources}) - -set(include_dirs - ${CMAKE_SOURCE_DIR}/include - ${CMAKE_SOURCE_DIR}/lib/SS2K/include - ${CMAKE_SOURCE_DIR}/lib/SS2K/include/sensors - ${CMAKE_SOURCE_DIR}/lib/ArduinoWebsockets - ${CMAKE_SOURCE_DIR}/lib/TMCStepper/src - ${CMAKE_SOURCE_DIR}/lib/TMCStepper/src/source -) - -idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "${include_dirs}") diff --git a/main/idf_component.yml b/main/idf_component.yml deleted file mode 100644 index d614a01a..00000000 --- a/main/idf_component.yml +++ /dev/null @@ -1,7 +0,0 @@ -## IDF Component Manager Manifest File -dependencies: - espressif/arduino-esp32: ^3.2.0 - h2zero/esp-nimble-cpp: ^2.3.1 - bblanchon/arduinojson: 7.3.1 - doudar/FastAccelStepper: - git: https://github.com/doudar/FastAccelStepper diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 00000000..cf55353b --- /dev/null +++ b/platformio.ini @@ -0,0 +1,119 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html +[platformio] +default_envs = release + +[esp32doit] +lib_ldf_mode = chain +lib_compat_mode = strict +platform = https://github.com/pioarduino/platform-espressif32/releases/download/54.03.20/platform-espressif32.zip +;platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10/platform-espressif32.zip +;platform = espressif32 +;platform_packages = +; framework-espidf @ https://github.com/espressif/esp-idf/releases/download/v5.3.2/esp-idf-v5.3.2.zip +board = esp32doit-devkit-v1 +framework = arduino, espidf +board_build.partitions = min_spiffs.csv +board_build.filesystem = littlefs +upload_speed = 921600 +monitor_speed = 115200 +monitor_filters = esp32_exception_decoder +board_build.embed_txtfiles = + ;managed_components/espressif__esp_insights/server_certs/https_server.crt + ;managed_components/espressif__esp_rainmaker/server_certs/rmaker_mqtt_server.crt + ;managed_components/espressif__esp_rainmaker/server_certs/rmaker_claim_service_server.crt + ;managed_components/espressif__esp_rainmaker/server_certs/rmaker_ota_server.crt +custom_component_remove = + espressif/esp_hosted + espressif/esp_wifi_remote + espressif/esp-dsp + espressif/esp32-camera + espressif/libsodium + espressif/esp-modbus + espressif/qrcode + espressif/esp_insights + espressif/esp_diag_data_store + espressif/esp_diagnostics + espressif/esp_rainmaker + espressif/zigbee + espressif/rmaker_common +build_flags = + !python git_tag_macro.py + !python build_date_macro.py + !python cert_updater.py + ;-DCONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y + ;-D CONFIG_SPI_SLAVE_ISR_IN_IRAM=n + ;-D CONFIG_NEWLIB_NANO_FORMAT=y + ;-D CONFIG_LWIP_IRAM_OPTIMIZATION=y + ;-D CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM=y + ;-D CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 + ;-D CONFIG_BT_NIMBLE_WHITELIST_SIZE=0 + ;-D CONFIG_MDNS_STRICT_MODE=1 + ;-D CORE_DEBUG_LEVEL=1 + -D ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=3500 + ;-D CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=8000 + ;-D CONFIG_BT_NIMBLE_MAX_CCCDS=0 + ;-D CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=1 + ;-D CONFIG_NIMBLE_STACK_USE_MEM_POOLS=1 + ;-D CONFIG_BT_NIMBLE_MAX_BONDS=1 + ;-D CONFIG_BT_NIMBLE_BLOCK_COUNT=20 + -std=gnu++17 +lib_deps = + https://github.com/h2zero/esp-nimble-cpp/ + https://github.com/teemuatlut/TMCStepper/archive/refs/tags/v0.7.3.zip + https://github.com/bblanchon/ArduinoJson/archive/refs/tags/v7.3.1.zip + ;https://github.com/gin66/FastAccelStepper/archive/refs/tags/0.31.2.zip + https://github.com/doudar/FastAccelStepper/ + https://github.com/gilmaimon/ArduinoWebsockets/archive/refs/tags/0.5.4.zip + ;https://github.com/Links2004/arduinoWebSockets + ;https://github.com/doudar/NimBLE-Arduino/ + +[env:release] +extends = esp32doit + +[env:debug] +extends = esp32doit +build_type = debug +build_flags = ${esp32doit.build_flags} -D__DEBUG__=1 +debug_tool = esp-prog +debug_init_break = tbreak setup +check_tool = cppcheck +check_flags = + --enable=all + --suppress=*:*/.pio/* + --suppress=*:*/lib/NimBLE-Arduino/* + --suppress=unmatchedSuppression + --suppress=missingIncludeSystem +check_severity = medium, high +check_skip_packages = true + +[env:native] +platform = native +lib_deps = + ArduinoFake + lib/ArduinoCompat + lib/SS2K +build_flags = + -Wunused + -Wunused-function + -Wunused-variable + -Wunreachable-code + -std=c++11 + -D PLATFORMIO_ENV_NATIVE +lib_ldf_mode = chain+ +lib_compat_mode = soft +check_tool = cppcheck +check_flags = + --enable=all + --suppress=*:*/.pio/*P + --suppress=unmatchedSuppression + --suppress=missingIncludeSystem +check_severity = medium, high +check_skip_packages = true diff --git a/sdkconfig b/sdkconfig index 4be13f57..1287da4d 100644 --- a/sdkconfig +++ b/sdkconfig @@ -406,124 +406,6 @@ CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table -# -# Arduino Configuration -# -CONFIG_ARDUINO_VARIANT="esp32" -CONFIG_ENABLE_ARDUINO_DEPENDS=y -CONFIG_AUTOSTART_ARDUINO=y -# CONFIG_ARDUINO_RUN_CORE0 is not set -CONFIG_ARDUINO_RUN_CORE1=y -# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_RUNNING_CORE=1 -CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 -# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set -CONFIG_ARDUINO_EVENT_RUN_CORE1=y -# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 -# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set -# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set -CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y -CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 -CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=2048 -CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 -CONFIG_ARDUINO_UDP_RUN_CORE0=y -# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set -# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_UDP_RUNNING_CORE=0 -CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 -# CONFIG_ARDUINO_ISR_IRAM is not set -# CONFIG_DISABLE_HAL_LOCKS is not set - -# -# Debug Log Configuration -# -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE is not set -CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR=y -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=1 -# CONFIG_ARDUHAL_LOG_COLORS is not set -# CONFIG_ARDUHAL_ESP_LOG is not set -# end of Debug Log Configuration - -CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT=y -# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS is not set -CONFIG_ARDUHAL_PARTITION_SCHEME="default" -# CONFIG_AUTOCONNECT_WIFI is not set -# CONFIG_ARDUINO_SELECTIVE_COMPILATION is not set -# end of Arduino Configuration - -# -# ESP RainMaker Config -# -CONFIG_ESP_RMAKER_NO_CLAIM=y -# CONFIG_ESP_RMAKER_ASSISTED_CLAIM is not set -# CONFIG_ESP_RMAKER_USE_ESP_SECURE_CERT_MGR is not set -CONFIG_ESP_RMAKER_USE_NVS=y -CONFIG_ESP_RMAKER_CLAIM_TYPE=0 -# CONFIG_ESP_RMAKER_READ_MQTT_HOST_FROM_CONFIG is not set -# CONFIG_ESP_RMAKER_READ_NODE_ID_FROM_CERT_CN is not set -CONFIG_ESP_RMAKER_MQTT_USE_BASIC_INGEST_TOPICS=y -CONFIG_ESP_RMAKER_MQTT_ENABLE_BUDGETING=y -CONFIG_ESP_RMAKER_MQTT_DEFAULT_BUDGET=100 -CONFIG_ESP_RMAKER_MQTT_MAX_BUDGET=1024 -CONFIG_ESP_RMAKER_MQTT_BUDGET_REVIVE_PERIOD=5 -CONFIG_ESP_RMAKER_MQTT_BUDGET_REVIVE_COUNT=1 -CONFIG_ESP_RMAKER_MAX_PARAM_DATA_SIZE=1024 -# CONFIG_ESP_RMAKER_DISABLE_USER_MAPPING_PROV is not set -# CONFIG_ESP_RMAKER_USER_ID_CHECK is not set -# CONFIG_RMAKER_NAME_PARAM_CB is not set -# CONFIG_ESP_RMAKER_LOCAL_CTRL_FEATURE_ENABLE is not set -# CONFIG_ESP_RMAKER_LOCAL_CTRL_AUTO_ENABLE is not set -CONFIG_ESP_RMAKER_CONSOLE_UART_NUM_0=y -# CONFIG_ESP_RMAKER_CONSOLE_UART_NUM_1 is not set -CONFIG_ESP_RMAKER_CONSOLE_UART_NUM=0 -CONFIG_ESP_RMAKER_USE_CERT_BUNDLE=y - -# -# ESP RainMaker OTA Config -# -CONFIG_ESP_RMAKER_OTA_AUTOFETCH=y -CONFIG_ESP_RMAKER_OTA_AUTOFETCH_PERIOD=0 -# CONFIG_ESP_RMAKER_SKIP_COMMON_NAME_CHECK is not set -# CONFIG_ESP_RMAKER_SKIP_VERSION_CHECK is not set -# CONFIG_ESP_RMAKER_SKIP_SECURE_VERSION_CHECK is not set -# CONFIG_ESP_RMAKER_SKIP_PROJECT_NAME_CHECK is not set -CONFIG_ESP_RMAKER_OTA_HTTP_RX_BUFFER_SIZE=1024 -CONFIG_ESP_RMAKER_OTA_ROLLBACK_WAIT_PERIOD=90 -# CONFIG_ESP_RMAKER_OTA_DISABLE_AUTO_REBOOT is not set -CONFIG_ESP_RMAKER_OTA_TIME_SUPPORT=y -# end of ESP RainMaker OTA Config - -# -# ESP RainMaker Scheduling -# -CONFIG_ESP_RMAKER_SCHEDULING_MAX_SCHEDULES=10 -# end of ESP RainMaker Scheduling - -# -# ESP RainMaker Scenes -# -CONFIG_ESP_RMAKER_SCENES_MAX_SCENES=10 -# CONFIG_ESP_RMAKER_SCENES_DEACTIVATE_SUPPORT is not set -# end of ESP RainMaker Scenes - -# -# ESP RainMaker Command-Response -# -CONFIG_ESP_RMAKER_CMD_RESP_ENABLE=y -# CONFIG_ESP_RMAKER_CMD_RESP_TEST_ENABLE is not set -# end of ESP RainMaker Command-Response - -CONFIG_ESP_RMAKER_USING_NETWORK_PROV=y -# end of ESP RainMaker Config - # # Compiler options # @@ -578,234 +460,10 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # # Bluetooth # -CONFIG_BT_ENABLED=y -# CONFIG_BT_BLUEDROID_ENABLED is not set -CONFIG_BT_NIMBLE_ENABLED=y -# CONFIG_BT_CONTROLLER_ONLY is not set -CONFIG_BT_CONTROLLER_ENABLED=y -# CONFIG_BT_CONTROLLER_DISABLED is not set - -# -# NimBLE Options -# -CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y -# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set -CONFIG_BT_NIMBLE_LOG_LEVEL_NONE=y -# CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR is not set -# CONFIG_BT_NIMBLE_LOG_LEVEL_WARNING is not set -# CONFIG_BT_NIMBLE_LOG_LEVEL_INFO is not set -# CONFIG_BT_NIMBLE_LOG_LEVEL_DEBUG is not set -CONFIG_BT_NIMBLE_LOG_LEVEL=4 -CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 -CONFIG_BT_NIMBLE_MAX_BONDS=3 -CONFIG_BT_NIMBLE_MAX_CCCDS=8 -CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM=0 -CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y -# CONFIG_BT_NIMBLE_PINNED_TO_CORE_1 is not set -CONFIG_BT_NIMBLE_PINNED_TO_CORE=0 -CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=4096 -CONFIG_BT_NIMBLE_ROLE_CENTRAL=y -CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y -CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y -CONFIG_BT_NIMBLE_ROLE_OBSERVER=y -# CONFIG_BT_NIMBLE_NVS_PERSIST is not set -# CONFIG_BT_NIMBLE_SMP_ID_RESET is not set -CONFIG_BT_NIMBLE_SECURITY_ENABLE=y -CONFIG_BT_NIMBLE_SM_LEGACY=y -CONFIG_BT_NIMBLE_SM_SC=y -# CONFIG_BT_NIMBLE_SM_SC_DEBUG_KEYS is not set -CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_ENCRYPTION=y -CONFIG_BT_NIMBLE_SM_LVL=0 -CONFIG_BT_NIMBLE_SM_SC_ONLY=0 -# CONFIG_BT_NIMBLE_DEBUG is not set -# CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set -CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" -CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 -CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=256 -CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE=0 - -# -# Memory Settings -# -CONFIG_BT_NIMBLE_MSYS_1_BLOCK_COUNT=12 -CONFIG_BT_NIMBLE_MSYS_1_BLOCK_SIZE=256 -CONFIG_BT_NIMBLE_MSYS_2_BLOCK_COUNT=24 -CONFIG_BT_NIMBLE_MSYS_2_BLOCK_SIZE=320 -CONFIG_BT_NIMBLE_TRANSPORT_ACL_FROM_LL_COUNT=24 -CONFIG_BT_NIMBLE_TRANSPORT_ACL_SIZE=255 -CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70 -CONFIG_BT_NIMBLE_TRANSPORT_EVT_COUNT=30 -CONFIG_BT_NIMBLE_TRANSPORT_EVT_DISCARD_COUNT=8 -CONFIG_BT_NIMBLE_L2CAP_COC_SDU_BUFF_COUNT=1 -# end of Memory Settings - -CONFIG_BT_NIMBLE_GATT_MAX_PROCS=4 -CONFIG_BT_NIMBLE_HS_FLOW_CTRL=y -CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 -CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 -CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y -CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 -# CONFIG_BT_NIMBLE_MESH is not set -CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y -CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 -# CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set -# CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set -CONFIG_BT_NIMBLE_WHITELIST_SIZE=12 -# CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set -# CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set -CONFIG_BT_NIMBLE_USE_ESP_TIMER=y -CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y -# CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set - -# -# GAP Service -# - -# -# GAP Appearance write permissions -# -# CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set -# end of GAP Appearance write permissions - -CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM=0 -CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ENC=0 -CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHN=0 -CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHR=0 -CONFIG_BT_NIMBLE_SVC_GAP_CAR_CHAR_NOT_SUPP=y -# CONFIG_BT_NIMBLE_SVC_GAP_CAR_NOT_SUPP is not set -# CONFIG_BT_NIMBLE_SVC_GAP_CAR_SUPP is not set -CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 - -# -# GAP device name write permissions -# -# CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set -# end of GAP device name write permissions - -CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM=0 -CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_ENC=0 -CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHEN=0 -CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHOR=0 -CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 -CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 -CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 -CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 -# CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL is not set -# end of GAP Service - -# -# BLE Services -# -# CONFIG_BT_NIMBLE_HID_SERVICE is not set -# CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY is not set - -# -# Device Information Service -# -# CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME is not set -# CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER is not set -# CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION is not set -# CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION is not set -# CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION is not set -# CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID is not set -# CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID is not set -# CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED is not set -# end of Device Information Service -# end of BLE Services - -# CONFIG_BT_NIMBLE_VS_SUPPORT is not set -# CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set -# CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set -# CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set -# CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT is not set - -# -# Host-controller Transport -# -CONFIG_UART_HW_FLOWCTRL_DISABLE=y -# CONFIG_UART_HW_FLOWCTRL_CTS_RTS is not set -CONFIG_BT_NIMBLE_HCI_UART_FLOW_CTRL=0 -CONFIG_BT_NIMBLE_HCI_UART_RTS_PIN=19 -CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 -# end of Host-controller Transport - -CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 -# CONFIG_BT_NIMBLE_SUBRATE is not set -# end of NimBLE Options - -# -# Controller Options -# -CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y -# CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set -# CONFIG_BTDM_CTRL_MODE_BTDM is not set -CONFIG_BTDM_CTRL_BLE_MAX_CONN=3 -CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 -CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 -CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 -CONFIG_BTDM_CTRL_PCM_FSYNCSHP_EFF=0 -CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=3 -CONFIG_BTDM_CTRL_BR_EDR_MIN_ENC_KEY_SZ_DFT_EFF=0 -CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 -CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 -CONFIG_BTDM_CTRL_PINNED_TO_CORE_0=y -# CONFIG_BTDM_CTRL_PINNED_TO_CORE_1 is not set -CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 -CONFIG_BTDM_CTRL_HCI_MODE_VHCI=y -# CONFIG_BTDM_CTRL_HCI_MODE_UART_H4 is not set - -# -# MODEM SLEEP Options -# -CONFIG_BTDM_CTRL_MODEM_SLEEP=y -CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG=y -# CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_EVED is not set -CONFIG_BTDM_CTRL_LPCLK_SEL_MAIN_XTAL=y -# end of MODEM SLEEP Options - -CONFIG_BTDM_BLE_DEFAULT_SCA_250PPM=y -CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 -CONFIG_BTDM_BLE_SCAN_DUPL=y -CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y -# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA is not set -# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE is not set -CONFIG_BTDM_SCAN_DUPL_TYPE=0 -CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 -CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 -# CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set -CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y -# CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set -# CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set -CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y -CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 -CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 - -# -# BLE disconnects when Instant Passed (0x28) occurs -# -# CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set -# CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set -# end of BLE disconnects when Instant Passed (0x28) occurs - -CONFIG_BTDM_BLE_CHAN_ASS_EN=y -CONFIG_BTDM_BLE_PING_EN=y -# CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 is not set -CONFIG_BTDM_RESERVE_DRAM=0xdb5c -CONFIG_BTDM_CTRL_HLI=y -# end of Controller Options - -# -# Common Options -# +# CONFIG_BT_ENABLED is not set CONFIG_BT_ALARM_MAX_NUM=50 -# CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set -# end of Common Options - -# CONFIG_BT_HCI_LOG_DEBUG_EN is not set # end of Bluetooth -# CONFIG_BLE_MESH is not set - # # Console Library # @@ -940,8 +598,6 @@ CONFIG_ADC_DISABLE_DAC_OUTPUT=y # Wireless Coexistence # CONFIG_ESP_COEX_ENABLED=y -CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y -# CONFIG_ESP_COEX_POWER_MANAGEMENT is not set # CONFIG_ESP_COEX_GPIO_DEBUG is not set # end of Wireless Coexistence @@ -1361,7 +1017,8 @@ CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y # CONFIG_ESP_PANIC_HANDLER_IRAM is not set # CONFIG_ESP_DEBUG_STUBS_ENABLE is not set CONFIG_ESP_DEBUG_OCDAWARE=y -CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y +# CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y # # Brownout Detector @@ -1682,7 +1339,7 @@ CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -CONFIG_LWIP_SO_RCVBUF=y +# CONFIG_LWIP_SO_RCVBUF is not set # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP_DEFAULT_TTL=64 CONFIG_LWIP_IP4_FRAG=y @@ -2227,295 +1884,9 @@ CONFIG_WL_SECTOR_SIZE=4096 # CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 -# CONFIG_WIFI_PROV_BLE_BONDING is not set -CONFIG_WIFI_PROV_BLE_SEC_CONN=y -# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set -# CONFIG_WIFI_PROV_BLE_NOTIFY is not set -# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set # end of Wi-Fi Provisioning Manager - -# -# DSP Library -# -CONFIG_DSP_OPTIMIZATIONS_SUPPORTED=y -# CONFIG_DSP_ANSI is not set -CONFIG_DSP_OPTIMIZED=y -CONFIG_DSP_OPTIMIZATION=1 -# CONFIG_DSP_MAX_FFT_SIZE_512 is not set -# CONFIG_DSP_MAX_FFT_SIZE_1024 is not set -# CONFIG_DSP_MAX_FFT_SIZE_2048 is not set -CONFIG_DSP_MAX_FFT_SIZE_4096=y -# CONFIG_DSP_MAX_FFT_SIZE_8192 is not set -# CONFIG_DSP_MAX_FFT_SIZE_16384 is not set -# CONFIG_DSP_MAX_FFT_SIZE_32768 is not set -CONFIG_DSP_MAX_FFT_SIZE=4096 -# end of DSP Library - -# -# Modbus configuration -# -CONFIG_FMB_COMM_MODE_TCP_EN=y -CONFIG_FMB_TCP_PORT_DEFAULT=502 -CONFIG_FMB_TCP_PORT_MAX_CONN=5 -CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 -# CONFIG_FMB_TCP_UID_ENABLED is not set -CONFIG_FMB_COMM_MODE_RTU_EN=y -CONFIG_FMB_COMM_MODE_ASCII_EN=y -CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=3000 -CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 -CONFIG_FMB_QUEUE_LENGTH=20 -CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 -CONFIG_FMB_SERIAL_BUF_SIZE=256 -CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 -CONFIG_FMB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS=0 -CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 -CONFIG_FMB_PORT_TASK_PRIO=10 -# CONFIG_FMB_PORT_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_FMB_PORT_TASK_AFFINITY_CPU0=y -# CONFIG_FMB_PORT_TASK_AFFINITY_CPU1 is not set -CONFIG_FMB_PORT_TASK_AFFINITY=0x0 -CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y -CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 -CONFIG_FMB_CONTROLLER_SLAVE_ID_MAX_SIZE=32 -CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 -CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 -CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 -CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 -# CONFIG_FMB_TIMER_PORT_ENABLED is not set -# CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD is not set -# CONFIG_FMB_EXT_TYPE_SUPPORT is not set -# end of Modbus configuration - -# -# ESP serial flasher -# -CONFIG_SERIAL_FLASHER_MD5_ENABLED=y -CONFIG_SERIAL_FLASHER_RESET_HOLD_TIME_MS=100 -CONFIG_SERIAL_FLASHER_BOOT_HOLD_TIME_MS=50 -# end of ESP serial flasher - -# -# Zigbee -# -# CONFIG_ZB_ENABLED is not set -# end of Zigbee - -# -# Diagnostics data store -# -CONFIG_DIAG_DATA_STORE_RTC=y -# CONFIG_DIAG_DATA_STORE_FLASH is not set -# CONFIG_DIAG_DATA_STORE_DBG_PRINTS is not set -CONFIG_DIAG_DATA_STORE_REPORTING_WATERMARK_PERCENT=80 - -# -# RTC Store -# -CONFIG_RTC_STORE_DATA_SIZE=3072 -CONFIG_RTC_STORE_CRITICAL_DATA_SIZE=2048 -# end of RTC Store -# end of Diagnostics data store - -# -# Diagnostics -# -CONFIG_DIAG_LOG_MSG_ARG_FORMAT_TLV=y -# CONFIG_DIAG_LOG_MSG_ARG_FORMAT_STRING is not set -CONFIG_DIAG_LOG_MSG_ARG_MAX_SIZE=64 -CONFIG_DIAG_LOG_DROP_WIFI_LOGS=y -CONFIG_DIAG_ENABLE_METRICS=y -CONFIG_DIAG_METRICS_MAX_COUNT=20 -CONFIG_DIAG_ENABLE_HEAP_METRICS=y -CONFIG_DIAG_ENABLE_WIFI_METRICS=y -CONFIG_DIAG_ENABLE_VARIABLES=y -CONFIG_DIAG_VARIABLES_MAX_COUNT=20 -CONFIG_DIAG_ENABLE_NETWORK_VARIABLES=y -# CONFIG_DIAG_MORE_NETWORK_VARS is not set -# CONFIG_DIAG_USE_EXTERNAL_LOG_WRAP is not set -# end of Diagnostics - -# -# ESP Insights -# -# CONFIG_ESP_INSIGHTS_ENABLED is not set -# CONFIG_ESP_INSIGHTS_TRANSPORT_MQTT is not set -CONFIG_ESP_INSIGHTS_TRANSPORT_HTTPS=y -CONFIG_ESP_INSIGHTS_TRANSPORT_HTTPS_HOST="https://client.insights.espressif.com" -CONFIG_ESP_INSIGHTS_CLOUD_POST_MIN_INTERVAL_SEC=60 -CONFIG_ESP_INSIGHTS_CLOUD_POST_MAX_INTERVAL_SEC=240 -CONFIG_ESP_INSIGHTS_META_VERSION_10=y -# end of ESP Insights - -# -# esp-modem -# -CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y -# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set -CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 -# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set -# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set -CONFIG_ESP_MODEM_C_API_STR_MAX=128 -# CONFIG_ESP_MODEM_URC_HANDLER is not set -# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set -# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set -# end of esp-modem - -# -# OpenThread RCP Update -# -# CONFIG_AUTO_UPDATE_RCP is not set -# CONFIG_CREATE_OTA_IMAGE_WITH_RCP_FW is not set -# end of OpenThread RCP Update - -# -# ESP Secure Cert Manager -# -# CONFIG_ESP_SECURE_CERT_SUPPORT_LEGACY_FORMATS is not set -# end of ESP Secure Cert Manager - -# -# jsmn -# -# CONFIG_JSMN_PARENT_LINKS is not set -# CONFIG_JSMN_STRICT is not set -# CONFIG_JSMN_STATIC is not set -# end of jsmn - -# -# libsodium -# -# end of libsodium - -# -# mDNS -# -CONFIG_MDNS_MAX_INTERFACES=3 -CONFIG_MDNS_MAX_SERVICES=10 -CONFIG_MDNS_TASK_PRIORITY=1 -CONFIG_MDNS_ACTION_QUEUE_LEN=16 -CONFIG_MDNS_TASK_STACK_SIZE=4096 -# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_MDNS_TASK_AFFINITY_CPU0=y -# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set -CONFIG_MDNS_TASK_AFFINITY=0x0 - -# -# MDNS Memory Configuration -# -CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y -CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y -# CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set -# end of MDNS Memory Configuration - -CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 -CONFIG_MDNS_TIMER_PERIOD_MS=100 -# CONFIG_MDNS_NETWORKING_SOCKET is not set -# CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set -# CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set -CONFIG_MDNS_ENABLE_CONSOLE_CLI=y -# CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set -CONFIG_MDNS_MULTIPLE_INSTANCE=y - -# -# MDNS Predefined interfaces -# -CONFIG_MDNS_PREDEF_NETIF_STA=y -CONFIG_MDNS_PREDEF_NETIF_AP=y -CONFIG_MDNS_PREDEF_NETIF_ETH=y -# end of MDNS Predefined interfaces -# end of mDNS - -# -# Network Provisioning Manager -# -CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y -CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 -CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 -# CONFIG_NETWORK_PROV_BLE_BONDING is not set -CONFIG_NETWORK_PROV_BLE_SEC_CONN=y -# CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set -# CONFIG_NETWORK_PROV_KEEP_BLE_ON_AFTER_PROV is not set -CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y -# CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set -# end of Network Provisioning Manager - -# -# ESP RainMaker Common -# -CONFIG_ESP_RMAKER_LIB_ESP_MQTT=y -# CONFIG_ESP_RMAKER_LIB_AWS_IOT is not set -CONFIG_ESP_RMAKER_MQTT_GLUE_LIB=1 -CONFIG_ESP_RMAKER_MQTT_PORT_443=y -# CONFIG_ESP_RMAKER_MQTT_PORT_8883 is not set -CONFIG_ESP_RMAKER_MQTT_PORT=1 -# CONFIG_ESP_RMAKER_MQTT_PERSISTENT_SESSION is not set -CONFIG_ESP_RMAKER_MQTT_SEND_USERNAME=y -CONFIG_ESP_RMAKER_MQTT_PRODUCT_NAME="RMDev" -CONFIG_ESP_RMAKER_MQTT_PRODUCT_VERSION="1x0" -CONFIG_ESP_RMAKER_MQTT_PRODUCT_SKU="EX00" -CONFIG_ESP_RMAKER_MQTT_USE_CERT_BUNDLE=y -CONFIG_ESP_RMAKER_MAX_MQTT_SUBSCRIPTIONS=10 -CONFIG_ESP_RMAKER_MQTT_KEEP_ALIVE_INTERVAL=120 -CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI=y -CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_STACK=4096 -CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_PRIORITY=5 -CONFIG_ESP_RMAKER_FACTORY_PARTITION_NAME="fctry" -CONFIG_ESP_RMAKER_FACTORY_NAMESPACE="rmaker_creds" -CONFIG_ESP_RMAKER_DEF_TIMEZONE="Asia/Shanghai" -CONFIG_ESP_RMAKER_SNTP_SERVER_NAME="pool.ntp.org" -CONFIG_ESP_RMAKER_MAX_COMMANDS=10 -# end of ESP RainMaker Common - -# -# ESP-NimBLE-CPP configuration -# -CONFIG_NIMBLE_CPP_LOG_LEVEL_NONE=y -# CONFIG_NIMBLE_CPP_LOG_LEVEL_ERROR is not set -# CONFIG_NIMBLE_CPP_LOG_LEVEL_WARNING is not set -# CONFIG_NIMBLE_CPP_LOG_LEVEL_INFO is not set -# CONFIG_NIMBLE_CPP_LOG_LEVEL_DEBUG is not set -CONFIG_NIMBLE_CPP_LOG_LEVEL=0 -# CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR is not set -# CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT is not set -# CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT is not set -# CONFIG_NIMBLE_CPP_ENABLE_ADVERTISEMENT_TYPE_TEXT is not set -# CONFIG_NIMBLE_CPP_ADDR_FMT_EXCLUDE_DELIMITER is not set -# CONFIG_NIMBLE_CPP_ADDR_FMT_UPPERCASE is not set -# CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED is not set -CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH=20 -# CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED is not set -CONFIG_NIMBLE_CPP_FREERTOS_TASK_BLOCK_BIT=31 -# end of ESP-NimBLE-CPP configuration - -# -# LittleFS -# -# CONFIG_LITTLEFS_SDMMC_SUPPORT is not set -CONFIG_LITTLEFS_MAX_PARTITIONS=3 -CONFIG_LITTLEFS_PAGE_SIZE=256 -CONFIG_LITTLEFS_OBJ_NAME_LEN=64 -CONFIG_LITTLEFS_READ_SIZE=128 -CONFIG_LITTLEFS_WRITE_SIZE=128 -CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 -CONFIG_LITTLEFS_CACHE_SIZE=512 -CONFIG_LITTLEFS_BLOCK_CYCLES=512 -CONFIG_LITTLEFS_USE_MTIME=y -# CONFIG_LITTLEFS_USE_ONLY_HASH is not set -# CONFIG_LITTLEFS_HUMAN_READABLE is not set -CONFIG_LITTLEFS_MTIME_USE_SECONDS=y -# CONFIG_LITTLEFS_MTIME_USE_NONCE is not set -# CONFIG_LITTLEFS_SPIFFS_COMPAT is not set -# CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set -# CONFIG_LITTLEFS_FCNTL_GET_PATH is not set -# CONFIG_LITTLEFS_MULTIVERSION is not set -# CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set -CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y -# CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set -CONFIG_LITTLEFS_ASSERTS=y -# CONFIG_LITTLEFS_MMAP_PARTITION is not set -# end of LittleFS # end of Component config # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set @@ -2540,7 +1911,6 @@ CONFIG_LOG_BOOTLOADER_LEVEL=3 CONFIG_FLASHMODE_DIO=y # CONFIG_FLASHMODE_DOUT is not set CONFIG_MONITOR_BAUD=115200 -# CONFIG_ESP_RMAKER_LOCAL_CTRL_ENABLE is not set CONFIG_OPTIMIZATION_LEVEL_DEBUG=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y @@ -2559,72 +1929,7 @@ CONFIG_STACK_CHECK_NONE=y # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set CONFIG_ESP32_APPTRACE_DEST_NONE=y CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y -# CONFIG_BLUEDROID_ENABLED is not set -CONFIG_NIMBLE_ENABLED=y -CONFIG_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y -# CONFIG_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set -CONFIG_NIMBLE_MAX_CONNECTIONS=7 -CONFIG_NIMBLE_MAX_BONDS=3 -CONFIG_NIMBLE_MAX_CCCDS=8 -CONFIG_NIMBLE_L2CAP_COC_MAX_NUM=0 -CONFIG_NIMBLE_PINNED_TO_CORE_0=y -# CONFIG_NIMBLE_PINNED_TO_CORE_1 is not set -CONFIG_NIMBLE_PINNED_TO_CORE=0 -CONFIG_NIMBLE_TASK_STACK_SIZE=4096 -CONFIG_BT_NIMBLE_TASK_STACK_SIZE=4096 -CONFIG_NIMBLE_ROLE_CENTRAL=y -CONFIG_NIMBLE_ROLE_PERIPHERAL=y -CONFIG_NIMBLE_ROLE_BROADCASTER=y -CONFIG_NIMBLE_ROLE_OBSERVER=y -# CONFIG_NIMBLE_NVS_PERSIST is not set -CONFIG_NIMBLE_SM_LEGACY=y -CONFIG_NIMBLE_SM_SC=y -# CONFIG_NIMBLE_SM_SC_DEBUG_KEYS is not set -CONFIG_BT_NIMBLE_SM_SC_LVL=0 -# CONFIG_NIMBLE_DEBUG is not set -CONFIG_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" -CONFIG_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 -CONFIG_NIMBLE_ATT_PREFERRED_MTU=256 -CONFIG_NIMBLE_SVC_GAP_APPEARANCE=0 -CONFIG_BT_NIMBLE_MSYS1_BLOCK_COUNT=12 -CONFIG_BT_NIMBLE_ACL_BUF_COUNT=24 -CONFIG_BT_NIMBLE_ACL_BUF_SIZE=255 -CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70 -CONFIG_BT_NIMBLE_HCI_EVT_HI_BUF_COUNT=30 -CONFIG_BT_NIMBLE_HCI_EVT_LO_BUF_COUNT=8 -CONFIG_NIMBLE_HS_FLOW_CTRL=y -CONFIG_NIMBLE_HS_FLOW_CTRL_ITVL=1000 -CONFIG_NIMBLE_HS_FLOW_CTRL_THRESH=2 -CONFIG_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y -CONFIG_NIMBLE_RPA_TIMEOUT=900 -# CONFIG_NIMBLE_MESH is not set -CONFIG_NIMBLE_CRYPTO_STACK_MBEDTLS=y -CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y -# CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY is not set -# CONFIG_BTDM_CONTROLLER_MODE_BTDM is not set -CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=3 -CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=3 -CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0 -CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 -CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 -CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI=y -# CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4 is not set -CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=y -CONFIG_BLE_SCAN_DUPLICATE=y -CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y -# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA is not set -# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR is not set -CONFIG_SCAN_DUPLICATE_TYPE=0 -CONFIG_DUPLICATE_SCAN_CACHE_SIZE=100 -# CONFIG_BLE_MESH_SCAN_DUPLICATE_EN is not set -CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y -CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED=y -CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM=100 -CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 CONFIG_ADC2_DISABLE_DAC=y -CONFIG_SW_COEXIST_ENABLE=y -CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y -CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y # CONFIG_MCPWM_ISR_IN_IRAM is not set # CONFIG_EVENT_LOOP_PROFILING is not set CONFIG_POST_EVENTS_FROM_ISR=y @@ -2795,18 +2100,4 @@ CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=3000 -CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 -CONFIG_MB_QUEUE_LENGTH=20 -CONFIG_MB_SERIAL_TASK_STACK_SIZE=4096 -CONFIG_MB_SERIAL_BUF_SIZE=256 -CONFIG_MB_SERIAL_TASK_PRIO=10 -CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT=y -CONFIG_MB_CONTROLLER_SLAVE_ID=0x00112233 -CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 -CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 -CONFIG_MB_CONTROLLER_STACK_SIZE=4096 -CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 -# CONFIG_MB_TIMER_PORT_ENABLED is not set -CONFIG_NIMBLE_ENABLED=y # End of deprecated options diff --git a/sdkconfig.defaults b/sdkconfig.defaults index 75cef2f8..d50929ea 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -1,12 +1,6 @@ -# This file was generated using idf.py save-defconfig. It can be edited manually. -# Espressif IoT Development Framework (ESP-IDF) 5.4.1 Project Minimal Configuration -# -CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_AUTOSTART_ARDUINO=y -CONFIG_ESP_RMAKER_NO_CLAIM=y -CONFIG_BT_NIMBLE_ENABLED=y -CONFIG_BT_NIMBLE_LOG_LEVEL_NONE=y -CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 +# CONFIG_WS2812_LED_ENABLE is not set CONFIG_FREERTOS_HZ=1000 CONFIG_MBEDTLS_PSK_MODES=y CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y \ No newline at end of file diff --git a/sdkconfig.old b/sdkconfig.old index 2ed7e033..07c9dd84 100644 --- a/sdkconfig.old +++ b/sdkconfig.old @@ -374,14 +374,14 @@ CONFIG_ESPTOOLPY_FLASHFREQ_40M=y # CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set CONFIG_ESPTOOLPY_FLASHFREQ="40m" # CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +CONFIG_ESPTOOLPY_FLASHSIZE="2MB" # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set @@ -406,123 +406,6 @@ CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table -# -# Arduino Configuration -# -CONFIG_ARDUINO_VARIANT="esp32" -CONFIG_ENABLE_ARDUINO_DEPENDS=y -CONFIG_AUTOSTART_ARDUINO=y -# CONFIG_ARDUINO_RUN_CORE0 is not set -CONFIG_ARDUINO_RUN_CORE1=y -# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_RUNNING_CORE=1 -CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 -# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set -CONFIG_ARDUINO_EVENT_RUN_CORE1=y -# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 -# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set -# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set -CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y -CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 -CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=2048 -CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 -CONFIG_ARDUINO_UDP_RUN_CORE0=y -# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set -# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_UDP_RUNNING_CORE=0 -CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 -# CONFIG_ARDUINO_ISR_IRAM is not set -# CONFIG_DISABLE_HAL_LOCKS is not set - -# -# Debug Log Configuration -# -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE is not set -CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR=y -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=1 -# CONFIG_ARDUHAL_LOG_COLORS is not set -# CONFIG_ARDUHAL_ESP_LOG is not set -# end of Debug Log Configuration - -CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT=y -# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS is not set -CONFIG_ARDUHAL_PARTITION_SCHEME="default" -# CONFIG_AUTOCONNECT_WIFI is not set -# CONFIG_ARDUINO_SELECTIVE_COMPILATION is not set -# end of Arduino Configuration - -# -# ESP RainMaker Config -# -CONFIG_ESP_RMAKER_NO_CLAIM=y -# CONFIG_ESP_RMAKER_USE_ESP_SECURE_CERT_MGR is not set -CONFIG_ESP_RMAKER_USE_NVS=y -CONFIG_ESP_RMAKER_CLAIM_TYPE=0 -# CONFIG_ESP_RMAKER_READ_MQTT_HOST_FROM_CONFIG is not set -# CONFIG_ESP_RMAKER_READ_NODE_ID_FROM_CERT_CN is not set -CONFIG_ESP_RMAKER_MQTT_USE_BASIC_INGEST_TOPICS=y -CONFIG_ESP_RMAKER_MQTT_ENABLE_BUDGETING=y -CONFIG_ESP_RMAKER_MQTT_DEFAULT_BUDGET=100 -CONFIG_ESP_RMAKER_MQTT_MAX_BUDGET=1024 -CONFIG_ESP_RMAKER_MQTT_BUDGET_REVIVE_PERIOD=5 -CONFIG_ESP_RMAKER_MQTT_BUDGET_REVIVE_COUNT=1 -CONFIG_ESP_RMAKER_MAX_PARAM_DATA_SIZE=1024 -# CONFIG_ESP_RMAKER_DISABLE_USER_MAPPING_PROV is not set -# CONFIG_ESP_RMAKER_USER_ID_CHECK is not set -# CONFIG_RMAKER_NAME_PARAM_CB is not set -# CONFIG_ESP_RMAKER_LOCAL_CTRL_FEATURE_ENABLE is not set -# CONFIG_ESP_RMAKER_LOCAL_CTRL_AUTO_ENABLE is not set -CONFIG_ESP_RMAKER_CONSOLE_UART_NUM_0=y -# CONFIG_ESP_RMAKER_CONSOLE_UART_NUM_1 is not set -CONFIG_ESP_RMAKER_CONSOLE_UART_NUM=0 -CONFIG_ESP_RMAKER_USE_CERT_BUNDLE=y - -# -# ESP RainMaker OTA Config -# -CONFIG_ESP_RMAKER_OTA_AUTOFETCH=y -CONFIG_ESP_RMAKER_OTA_AUTOFETCH_PERIOD=0 -# CONFIG_ESP_RMAKER_SKIP_COMMON_NAME_CHECK is not set -# CONFIG_ESP_RMAKER_SKIP_VERSION_CHECK is not set -# CONFIG_ESP_RMAKER_SKIP_SECURE_VERSION_CHECK is not set -# CONFIG_ESP_RMAKER_SKIP_PROJECT_NAME_CHECK is not set -CONFIG_ESP_RMAKER_OTA_HTTP_RX_BUFFER_SIZE=1024 -CONFIG_ESP_RMAKER_OTA_ROLLBACK_WAIT_PERIOD=90 -# CONFIG_ESP_RMAKER_OTA_DISABLE_AUTO_REBOOT is not set -CONFIG_ESP_RMAKER_OTA_TIME_SUPPORT=y -# end of ESP RainMaker OTA Config - -# -# ESP RainMaker Scheduling -# -CONFIG_ESP_RMAKER_SCHEDULING_MAX_SCHEDULES=10 -# end of ESP RainMaker Scheduling - -# -# ESP RainMaker Scenes -# -CONFIG_ESP_RMAKER_SCENES_MAX_SCENES=10 -# CONFIG_ESP_RMAKER_SCENES_DEACTIVATE_SUPPORT is not set -# end of ESP RainMaker Scenes - -# -# ESP RainMaker Command-Response -# -CONFIG_ESP_RMAKER_CMD_RESP_ENABLE=y -# CONFIG_ESP_RMAKER_CMD_RESP_TEST_ENABLE is not set -# end of ESP RainMaker Command-Response - -CONFIG_ESP_RMAKER_USING_NETWORK_PROV=y -# end of ESP RainMaker Config - # # Compiler options # @@ -578,7 +461,6 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # Bluetooth # # CONFIG_BT_ENABLED is not set -# CONFIG_BT_NIMBLE_ENABLED is not set CONFIG_BT_ALARM_MAX_NUM=50 # end of Bluetooth @@ -1457,7 +1339,7 @@ CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -CONFIG_LWIP_SO_RCVBUF=y +# CONFIG_LWIP_SO_RCVBUF is not set # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP_DEFAULT_TTL=64 CONFIG_LWIP_IP4_FRAG=y @@ -2005,284 +1887,6 @@ CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set # end of Wi-Fi Provisioning Manager - -# -# DSP Library -# -CONFIG_DSP_OPTIMIZATIONS_SUPPORTED=y -# CONFIG_DSP_ANSI is not set -CONFIG_DSP_OPTIMIZED=y -CONFIG_DSP_OPTIMIZATION=1 -# CONFIG_DSP_MAX_FFT_SIZE_512 is not set -# CONFIG_DSP_MAX_FFT_SIZE_1024 is not set -# CONFIG_DSP_MAX_FFT_SIZE_2048 is not set -CONFIG_DSP_MAX_FFT_SIZE_4096=y -# CONFIG_DSP_MAX_FFT_SIZE_8192 is not set -# CONFIG_DSP_MAX_FFT_SIZE_16384 is not set -# CONFIG_DSP_MAX_FFT_SIZE_32768 is not set -CONFIG_DSP_MAX_FFT_SIZE=4096 -# end of DSP Library - -# -# Modbus configuration -# -CONFIG_FMB_COMM_MODE_TCP_EN=y -CONFIG_FMB_TCP_PORT_DEFAULT=502 -CONFIG_FMB_TCP_PORT_MAX_CONN=5 -CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 -# CONFIG_FMB_TCP_UID_ENABLED is not set -CONFIG_FMB_COMM_MODE_RTU_EN=y -CONFIG_FMB_COMM_MODE_ASCII_EN=y -CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=3000 -CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 -CONFIG_FMB_QUEUE_LENGTH=20 -CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 -CONFIG_FMB_SERIAL_BUF_SIZE=256 -CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 -CONFIG_FMB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS=0 -CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 -CONFIG_FMB_PORT_TASK_PRIO=10 -# CONFIG_FMB_PORT_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_FMB_PORT_TASK_AFFINITY_CPU0=y -# CONFIG_FMB_PORT_TASK_AFFINITY_CPU1 is not set -CONFIG_FMB_PORT_TASK_AFFINITY=0x0 -CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y -CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 -CONFIG_FMB_CONTROLLER_SLAVE_ID_MAX_SIZE=32 -CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 -CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 -CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 -CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 -# CONFIG_FMB_TIMER_PORT_ENABLED is not set -# CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD is not set -# CONFIG_FMB_EXT_TYPE_SUPPORT is not set -# end of Modbus configuration - -# -# ESP serial flasher -# -CONFIG_SERIAL_FLASHER_MD5_ENABLED=y -CONFIG_SERIAL_FLASHER_RESET_HOLD_TIME_MS=100 -CONFIG_SERIAL_FLASHER_BOOT_HOLD_TIME_MS=50 -# end of ESP serial flasher - -# -# Zigbee -# -# CONFIG_ZB_ENABLED is not set -# end of Zigbee - -# -# Diagnostics data store -# -CONFIG_DIAG_DATA_STORE_RTC=y -# CONFIG_DIAG_DATA_STORE_FLASH is not set -# CONFIG_DIAG_DATA_STORE_DBG_PRINTS is not set -CONFIG_DIAG_DATA_STORE_REPORTING_WATERMARK_PERCENT=80 - -# -# RTC Store -# -CONFIG_RTC_STORE_DATA_SIZE=3072 -CONFIG_RTC_STORE_CRITICAL_DATA_SIZE=2048 -# end of RTC Store -# end of Diagnostics data store - -# -# Diagnostics -# -CONFIG_DIAG_LOG_MSG_ARG_FORMAT_TLV=y -# CONFIG_DIAG_LOG_MSG_ARG_FORMAT_STRING is not set -CONFIG_DIAG_LOG_MSG_ARG_MAX_SIZE=64 -CONFIG_DIAG_LOG_DROP_WIFI_LOGS=y -CONFIG_DIAG_ENABLE_METRICS=y -CONFIG_DIAG_METRICS_MAX_COUNT=20 -CONFIG_DIAG_ENABLE_HEAP_METRICS=y -CONFIG_DIAG_ENABLE_WIFI_METRICS=y -CONFIG_DIAG_ENABLE_VARIABLES=y -CONFIG_DIAG_VARIABLES_MAX_COUNT=20 -CONFIG_DIAG_ENABLE_NETWORK_VARIABLES=y -# CONFIG_DIAG_MORE_NETWORK_VARS is not set -# CONFIG_DIAG_USE_EXTERNAL_LOG_WRAP is not set -# end of Diagnostics - -# -# ESP Insights -# -# CONFIG_ESP_INSIGHTS_ENABLED is not set -# CONFIG_ESP_INSIGHTS_TRANSPORT_MQTT is not set -CONFIG_ESP_INSIGHTS_TRANSPORT_HTTPS=y -CONFIG_ESP_INSIGHTS_TRANSPORT_HTTPS_HOST="https://client.insights.espressif.com" -CONFIG_ESP_INSIGHTS_CLOUD_POST_MIN_INTERVAL_SEC=60 -CONFIG_ESP_INSIGHTS_CLOUD_POST_MAX_INTERVAL_SEC=240 -CONFIG_ESP_INSIGHTS_META_VERSION_10=y -# end of ESP Insights - -# -# esp-modem -# -CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y -# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set -CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 -# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set -# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set -CONFIG_ESP_MODEM_C_API_STR_MAX=128 -# CONFIG_ESP_MODEM_URC_HANDLER is not set -# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set -# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set -# end of esp-modem - -# -# OpenThread RCP Update -# -# CONFIG_AUTO_UPDATE_RCP is not set -# CONFIG_CREATE_OTA_IMAGE_WITH_RCP_FW is not set -# end of OpenThread RCP Update - -# -# ESP Secure Cert Manager -# -# CONFIG_ESP_SECURE_CERT_SUPPORT_LEGACY_FORMATS is not set -# end of ESP Secure Cert Manager - -# -# jsmn -# -# CONFIG_JSMN_PARENT_LINKS is not set -# CONFIG_JSMN_STRICT is not set -# CONFIG_JSMN_STATIC is not set -# end of jsmn - -# -# libsodium -# -# end of libsodium - -# -# mDNS -# -CONFIG_MDNS_MAX_INTERFACES=3 -CONFIG_MDNS_MAX_SERVICES=10 -CONFIG_MDNS_TASK_PRIORITY=1 -CONFIG_MDNS_ACTION_QUEUE_LEN=16 -CONFIG_MDNS_TASK_STACK_SIZE=4096 -# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_MDNS_TASK_AFFINITY_CPU0=y -# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set -CONFIG_MDNS_TASK_AFFINITY=0x0 - -# -# MDNS Memory Configuration -# -CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y -CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y -# CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set -# end of MDNS Memory Configuration - -CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 -CONFIG_MDNS_TIMER_PERIOD_MS=100 -# CONFIG_MDNS_NETWORKING_SOCKET is not set -# CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set -# CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set -CONFIG_MDNS_ENABLE_CONSOLE_CLI=y -# CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set -CONFIG_MDNS_MULTIPLE_INSTANCE=y - -# -# MDNS Predefined interfaces -# -CONFIG_MDNS_PREDEF_NETIF_STA=y -CONFIG_MDNS_PREDEF_NETIF_AP=y -CONFIG_MDNS_PREDEF_NETIF_ETH=y -# end of MDNS Predefined interfaces -# end of mDNS - -# -# Network Provisioning Manager -# -CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y -CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 -CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 -# CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set -CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y -# CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set -# end of Network Provisioning Manager - -# -# ESP RainMaker Common -# -CONFIG_ESP_RMAKER_LIB_ESP_MQTT=y -# CONFIG_ESP_RMAKER_LIB_AWS_IOT is not set -CONFIG_ESP_RMAKER_MQTT_GLUE_LIB=1 -CONFIG_ESP_RMAKER_MQTT_PORT_443=y -# CONFIG_ESP_RMAKER_MQTT_PORT_8883 is not set -CONFIG_ESP_RMAKER_MQTT_PORT=1 -# CONFIG_ESP_RMAKER_MQTT_PERSISTENT_SESSION is not set -CONFIG_ESP_RMAKER_MQTT_SEND_USERNAME=y -CONFIG_ESP_RMAKER_MQTT_PRODUCT_NAME="RMDev" -CONFIG_ESP_RMAKER_MQTT_PRODUCT_VERSION="1x0" -CONFIG_ESP_RMAKER_MQTT_PRODUCT_SKU="EX00" -CONFIG_ESP_RMAKER_MQTT_USE_CERT_BUNDLE=y -CONFIG_ESP_RMAKER_MAX_MQTT_SUBSCRIPTIONS=10 -CONFIG_ESP_RMAKER_MQTT_KEEP_ALIVE_INTERVAL=120 -CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI=y -CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_STACK=4096 -CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_PRIORITY=5 -CONFIG_ESP_RMAKER_FACTORY_PARTITION_NAME="fctry" -CONFIG_ESP_RMAKER_FACTORY_NAMESPACE="rmaker_creds" -CONFIG_ESP_RMAKER_DEF_TIMEZONE="Asia/Shanghai" -CONFIG_ESP_RMAKER_SNTP_SERVER_NAME="pool.ntp.org" -CONFIG_ESP_RMAKER_MAX_COMMANDS=10 -# end of ESP RainMaker Common - -# -# ESP-NimBLE-CPP configuration -# -CONFIG_NIMBLE_CPP_LOG_LEVEL_NONE=y -# CONFIG_NIMBLE_CPP_LOG_LEVEL_ERROR is not set -# CONFIG_NIMBLE_CPP_LOG_LEVEL_WARNING is not set -# CONFIG_NIMBLE_CPP_LOG_LEVEL_INFO is not set -# CONFIG_NIMBLE_CPP_LOG_LEVEL_DEBUG is not set -CONFIG_NIMBLE_CPP_LOG_LEVEL=0 -# CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR is not set -# CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT is not set -# CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT is not set -# CONFIG_NIMBLE_CPP_ENABLE_ADVERTISEMENT_TYPE_TEXT is not set -# CONFIG_NIMBLE_CPP_ADDR_FMT_EXCLUDE_DELIMITER is not set -# CONFIG_NIMBLE_CPP_ADDR_FMT_UPPERCASE is not set -# CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED is not set -CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH=20 -# CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED is not set -CONFIG_NIMBLE_CPP_FREERTOS_TASK_BLOCK_BIT=31 -# end of ESP-NimBLE-CPP configuration - -# -# LittleFS -# -# CONFIG_LITTLEFS_SDMMC_SUPPORT is not set -CONFIG_LITTLEFS_MAX_PARTITIONS=3 -CONFIG_LITTLEFS_PAGE_SIZE=256 -CONFIG_LITTLEFS_OBJ_NAME_LEN=64 -CONFIG_LITTLEFS_READ_SIZE=128 -CONFIG_LITTLEFS_WRITE_SIZE=128 -CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 -CONFIG_LITTLEFS_CACHE_SIZE=512 -CONFIG_LITTLEFS_BLOCK_CYCLES=512 -CONFIG_LITTLEFS_USE_MTIME=y -# CONFIG_LITTLEFS_USE_ONLY_HASH is not set -# CONFIG_LITTLEFS_HUMAN_READABLE is not set -CONFIG_LITTLEFS_MTIME_USE_SECONDS=y -# CONFIG_LITTLEFS_MTIME_USE_NONCE is not set -# CONFIG_LITTLEFS_SPIFFS_COMPAT is not set -# CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set -# CONFIG_LITTLEFS_FCNTL_GET_PATH is not set -# CONFIG_LITTLEFS_MULTIVERSION is not set -# CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set -CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y -# CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set -CONFIG_LITTLEFS_ASSERTS=y -# CONFIG_LITTLEFS_MMAP_PARTITION is not set -# end of LittleFS # end of Component config # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set @@ -2307,7 +1911,6 @@ CONFIG_LOG_BOOTLOADER_LEVEL=3 CONFIG_FLASHMODE_DIO=y # CONFIG_FLASHMODE_DOUT is not set CONFIG_MONITOR_BAUD=115200 -# CONFIG_ESP_RMAKER_LOCAL_CTRL_ENABLE is not set CONFIG_OPTIMIZATION_LEVEL_DEBUG=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y @@ -2326,7 +1929,6 @@ CONFIG_STACK_CHECK_NONE=y # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set CONFIG_ESP32_APPTRACE_DEST_NONE=y CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y -# CONFIG_NIMBLE_ENABLED is not set CONFIG_ADC2_DISABLE_DAC=y # CONFIG_MCPWM_ISR_IN_IRAM is not set # CONFIG_EVENT_LOOP_PROFILING is not set @@ -2498,18 +2100,4 @@ CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=3000 -CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 -CONFIG_MB_QUEUE_LENGTH=20 -CONFIG_MB_SERIAL_TASK_STACK_SIZE=4096 -CONFIG_MB_SERIAL_BUF_SIZE=256 -CONFIG_MB_SERIAL_TASK_PRIO=10 -CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT=y -CONFIG_MB_CONTROLLER_SLAVE_ID=0x00112233 -CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 -CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 -CONFIG_MB_CONTROLLER_STACK_SIZE=4096 -CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 -# CONFIG_MB_TIMER_PORT_ENABLED is not set -# CONFIG_NIMBLE_ENABLED is not set # End of deprecated options diff --git a/main/BLE_Client.cpp b/src/BLE_Client.cpp similarity index 100% rename from main/BLE_Client.cpp rename to src/BLE_Client.cpp diff --git a/main/BLE_Common.cpp b/src/BLE_Common.cpp similarity index 100% rename from main/BLE_Common.cpp rename to src/BLE_Common.cpp diff --git a/main/BLE_Custom_Characteristic.cpp b/src/BLE_Custom_Characteristic.cpp similarity index 100% rename from main/BLE_Custom_Characteristic.cpp rename to src/BLE_Custom_Characteristic.cpp diff --git a/main/BLE_Cycling_Power_Service.cpp b/src/BLE_Cycling_Power_Service.cpp similarity index 100% rename from main/BLE_Cycling_Power_Service.cpp rename to src/BLE_Cycling_Power_Service.cpp diff --git a/main/BLE_Cycling_Speed_Cadence.cpp b/src/BLE_Cycling_Speed_Cadence.cpp similarity index 100% rename from main/BLE_Cycling_Speed_Cadence.cpp rename to src/BLE_Cycling_Speed_Cadence.cpp diff --git a/main/BLE_Device_Information_Service.cpp b/src/BLE_Device_Information_Service.cpp similarity index 100% rename from main/BLE_Device_Information_Service.cpp rename to src/BLE_Device_Information_Service.cpp diff --git a/main/BLE_Firmware_Update.cpp b/src/BLE_Firmware_Update.cpp similarity index 100% rename from main/BLE_Firmware_Update.cpp rename to src/BLE_Firmware_Update.cpp diff --git a/main/BLE_Fitness_Machine_Service.cpp b/src/BLE_Fitness_Machine_Service.cpp similarity index 100% rename from main/BLE_Fitness_Machine_Service.cpp rename to src/BLE_Fitness_Machine_Service.cpp diff --git a/main/BLE_Heart_Service.cpp b/src/BLE_Heart_Service.cpp similarity index 100% rename from main/BLE_Heart_Service.cpp rename to src/BLE_Heart_Service.cpp diff --git a/main/BLE_SB20_Service.cpp b/src/BLE_SB20_Service.cpp similarity index 100% rename from main/BLE_SB20_Service.cpp rename to src/BLE_SB20_Service.cpp diff --git a/main/BLE_Server.cpp b/src/BLE_Server.cpp similarity index 100% rename from main/BLE_Server.cpp rename to src/BLE_Server.cpp diff --git a/main/BLE_Setup.cpp b/src/BLE_Setup.cpp similarity index 100% rename from main/BLE_Setup.cpp rename to src/BLE_Setup.cpp diff --git a/main/BLE_Wattbike_Service.cpp b/src/BLE_Wattbike_Service.cpp similarity index 100% rename from main/BLE_Wattbike_Service.cpp rename to src/BLE_Wattbike_Service.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..483bc0cf --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,6 @@ +# This file was automatically generated for projects +# without default 'CMakeLists.txt' file. + +FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*) + +idf_component_register(SRCS ${app_sources}) diff --git a/main/DirConManager.cpp b/src/DirConManager.cpp similarity index 100% rename from main/DirConManager.cpp rename to src/DirConManager.cpp diff --git a/main/DirConMessage.cpp b/src/DirConMessage.cpp similarity index 100% rename from main/DirConMessage.cpp rename to src/DirConMessage.cpp diff --git a/main/ERG_Mode.cpp b/src/ERG_Mode.cpp similarity index 100% rename from main/ERG_Mode.cpp rename to src/ERG_Mode.cpp diff --git a/main/HTTP_Server_Basic.cpp b/src/HTTP_Server_Basic.cpp similarity index 100% rename from main/HTTP_Server_Basic.cpp rename to src/HTTP_Server_Basic.cpp diff --git a/main/Main.cpp b/src/Main.cpp similarity index 100% rename from main/Main.cpp rename to src/Main.cpp diff --git a/main/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp similarity index 100% rename from main/PowerTable_Helpers.cpp rename to src/PowerTable_Helpers.cpp diff --git a/main/Power_Table.cpp b/src/Power_Table.cpp similarity index 100% rename from main/Power_Table.cpp rename to src/Power_Table.cpp diff --git a/main/SS2KLog.cpp b/src/SS2KLog.cpp similarity index 100% rename from main/SS2KLog.cpp rename to src/SS2KLog.cpp diff --git a/main/SensorCollector.cpp b/src/SensorCollector.cpp similarity index 100% rename from main/SensorCollector.cpp rename to src/SensorCollector.cpp diff --git a/main/SmartSpin_parameters.cpp b/src/SmartSpin_parameters.cpp similarity index 100% rename from main/SmartSpin_parameters.cpp rename to src/SmartSpin_parameters.cpp diff --git a/main/UdpAppender.cpp b/src/UdpAppender.cpp similarity index 100% rename from main/UdpAppender.cpp rename to src/UdpAppender.cpp diff --git a/main/WebsocketAppender.cpp b/src/WebsocketAppender.cpp similarity index 100% rename from main/WebsocketAppender.cpp rename to src/WebsocketAppender.cpp diff --git a/main/gitTracking.md b/src/gitTracking.md similarity index 100% rename from main/gitTracking.md rename to src/gitTracking.md From ecc4d225ebd9f764005461badf018643aa1ff964 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 25 Jun 2025 19:51:42 -0500 Subject: [PATCH 251/451] Changes from @h2zero --- .gitignore | 1 + .gitmodules | 6 + .vscode/settings.json | 2 +- CMakeLists.txt | 4 - dependencies.lock | 413 +++++++++- include/BLE_Fitness_Machine_Service.h | 4 +- {src => main}/BLE_Client.cpp | 0 {src => main}/BLE_Common.cpp | 0 {src => main}/BLE_Custom_Characteristic.cpp | 0 {src => main}/BLE_Cycling_Power_Service.cpp | 0 {src => main}/BLE_Cycling_Speed_Cadence.cpp | 0 .../BLE_Device_Information_Service.cpp | 0 {src => main}/BLE_Firmware_Update.cpp | 0 {src => main}/BLE_Fitness_Machine_Service.cpp | 0 {src => main}/BLE_Heart_Service.cpp | 0 {src => main}/BLE_SB20_Service.cpp | 0 {src => main}/BLE_Server.cpp | 0 {src => main}/BLE_Setup.cpp | 0 {src => main}/BLE_Wattbike_Service.cpp | 0 main/CMakeLists.txt | 19 + {src => main}/DirConManager.cpp | 0 {src => main}/DirConMessage.cpp | 0 {src => main}/ERG_Mode.cpp | 0 {src => main}/HTTP_Server_Basic.cpp | 0 {src => main}/Main.cpp | 0 {src => main}/PowerTable_Helpers.cpp | 0 {src => main}/Power_Table.cpp | 0 {src => main}/SS2KLog.cpp | 0 {src => main}/SensorCollector.cpp | 0 {src => main}/SmartSpin_parameters.cpp | 0 {src => main}/UdpAppender.cpp | 0 {src => main}/WebsocketAppender.cpp | 0 {src => main}/gitTracking.md | 0 main/idf_component.yml | 7 + sdkconfig | 717 +++++++++++++++++- sdkconfig.defaults | 10 +- sdkconfig.old | 420 +++++++++- src/CMakeLists.txt | 6 - 38 files changed, 1565 insertions(+), 44 deletions(-) create mode 100644 .gitmodules rename {src => main}/BLE_Client.cpp (100%) rename {src => main}/BLE_Common.cpp (100%) rename {src => main}/BLE_Custom_Characteristic.cpp (100%) rename {src => main}/BLE_Cycling_Power_Service.cpp (100%) rename {src => main}/BLE_Cycling_Speed_Cadence.cpp (100%) rename {src => main}/BLE_Device_Information_Service.cpp (100%) rename {src => main}/BLE_Firmware_Update.cpp (100%) rename {src => main}/BLE_Fitness_Machine_Service.cpp (100%) rename {src => main}/BLE_Heart_Service.cpp (100%) rename {src => main}/BLE_SB20_Service.cpp (100%) rename {src => main}/BLE_Server.cpp (100%) rename {src => main}/BLE_Setup.cpp (100%) rename {src => main}/BLE_Wattbike_Service.cpp (100%) create mode 100644 main/CMakeLists.txt rename {src => main}/DirConManager.cpp (100%) rename {src => main}/DirConMessage.cpp (100%) rename {src => main}/ERG_Mode.cpp (100%) rename {src => main}/HTTP_Server_Basic.cpp (100%) rename {src => main}/Main.cpp (100%) rename {src => main}/PowerTable_Helpers.cpp (100%) rename {src => main}/Power_Table.cpp (100%) rename {src => main}/SS2KLog.cpp (100%) rename {src => main}/SensorCollector.cpp (100%) rename {src => main}/SmartSpin_parameters.cpp (100%) rename {src => main}/UdpAppender.cpp (100%) rename {src => main}/WebsocketAppender.cpp (100%) rename {src => main}/gitTracking.md (100%) create mode 100644 main/idf_component.yml delete mode 100644 src/CMakeLists.txt diff --git a/.gitignore b/.gitignore index 7795ffea..a6674331 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ build/CMakeCache.txt C/Users/ /build /managed_components +dependencies.lock \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..d2d2b5fa --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "lib/TMCStepper"] + path = lib/TMCStepper + url = https://github.com/teemuatlut/TMCStepper.git +[submodule "lib/ArduinoWebsockets"] + path = lib/ArduinoWebsockets + url = https://github.com/gilmaimon/ArduinoWebsockets.git diff --git a/.vscode/settings.json b/.vscode/settings.json index 2888d84a..baf137d4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -119,6 +119,6 @@ "VERSIONFILE", "WEBSERVER" ], - "idf.pythonInstallPath": "/opt/homebrew/bin/python3", + "idf.pythonInstallPath": "C:\\Users\\anthony\\.espressif\\tools\\idf-python\\3.11.2\\python.exe", "idf.flashType": "UART", } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a5f975e..fbd39142 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,3 @@ cmake_minimum_required(VERSION 3.16.0) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(SmartSpin2k) -include_directories( - ${PROJECT_SOURCE_DIR}/include - ${PROJECT_SOURCE_DIR}/src -) \ No newline at end of file diff --git a/dependencies.lock b/dependencies.lock index 937a8ec5..4d7dcec5 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -1,26 +1,191 @@ dependencies: + bblanchon/arduinojson: + component_hash: 914b05e5ba8d6b99d51307d4f5bf6a5ff610c673c200c3134edcc0a7a99d04b0 + dependencies: [] + source: + registry_url: https://components.espressif.com/ + type: service + version: 7.3.1 chmorgan/esp-libhelix-mp3: component_hash: cbb76089dc2c5749f7b470e2e70aedc44c9da519e04eb9a67d4c7ec275229e53 dependencies: - name: idf - registry_url: https://components.espressif.com require: private version: '>=4.1.0' source: - registry_url: https://components.espressif.com/ + registry_url: https://components.espressif.com type: service version: 1.0.3 + doudar/FastAccelStepper: + component_hash: 3e80398cf918e905938828befcbabc69e1a29e7867e9a5d226004349ae70fae0 + dependencies: [] + source: + git: https://github.com/doudar/FastAccelStepper + path: . + type: git + version: 02998fdee1bf6c5c0319f3a5792f56d2d830901e + espressif/arduino-esp32: + component_hash: 24d09ebaba2990281cb54ac3e0ba8fcdd8511c16b24114a4040476ece2949643 + dependencies: + - name: chmorgan/esp-libhelix-mp3 + registry_url: https://components.espressif.com + require: private + version: 1.0.3 + - name: espressif/cbor + registry_url: https://components.espressif.com + require: private + rules: + - if: target not in [esp32c2, esp32p4] + version: 0.6.0~1 + - name: espressif/esp-dsp + registry_url: https://components.espressif.com + require: private + rules: + - if: target != esp32c2 + version: ^1.3.4 + - name: espressif/esp-modbus + registry_url: https://components.espressif.com + require: private + version: ^1.0.15 + - name: espressif/esp-sr + registry_url: https://components.espressif.com + require: private + rules: + - if: target in [esp32s3] + version: ^1.4.2 + - name: espressif/esp-zboss-lib + registry_url: https://components.espressif.com + require: private + rules: + - if: target not in [esp32c2, esp32p4] + version: ==1.6.3 + - name: espressif/esp-zigbee-lib + registry_url: https://components.espressif.com + require: private + rules: + - if: target not in [esp32c2, esp32p4] + version: ==1.6.3 + - name: espressif/esp_diag_data_store + registry_url: https://components.espressif.com + require: private + rules: + - if: target not in [esp32c2, esp32p4] + version: 1.0.2 + - name: espressif/esp_diagnostics + registry_url: https://components.espressif.com + require: private + rules: + - if: target not in [esp32c2, esp32p4] + version: 1.2.1 + - name: espressif/esp_hosted + registry_url: https://components.espressif.com + require: private + rules: + - if: target == esp32p4 + version: ^0.0.25 + - name: espressif/esp_insights + registry_url: https://components.espressif.com + require: private + rules: + - if: target not in [esp32c2, esp32p4] + version: 1.2.2 + - name: espressif/esp_modem + registry_url: https://components.espressif.com + require: private + version: ^1.1.0 + - name: espressif/esp_rainmaker + registry_url: https://components.espressif.com + require: private + rules: + - if: target not in [esp32c2, esp32p4] + version: 1.5.2 + - name: espressif/esp_wifi_remote + registry_url: https://components.espressif.com + require: private + rules: + - if: target == esp32p4 + version: ^0.4.1 + - name: espressif/libsodium + registry_url: https://components.espressif.com + require: private + version: ^1.0.20~1 + - name: espressif/mdns + registry_url: https://components.espressif.com + require: private + version: ^1.2.3 + - name: espressif/network_provisioning + registry_url: https://components.espressif.com + require: private + version: 1.0.2 + - name: espressif/qrcode + registry_url: https://components.espressif.com + require: private + rules: + - if: target not in [esp32c2, esp32p4] + version: 0.1.0~2 + - name: espressif/rmaker_common + registry_url: https://components.espressif.com + require: private + rules: + - if: target not in [esp32c2, esp32p4] + version: 1.4.6 + - name: idf + require: private + version: '>=5.3,<5.5' + - name: joltwallet/littlefs + registry_url: https://components.espressif.com + require: private + version: ^1.10.2 + source: + registry_url: https://components.espressif.com/ + type: service + targets: + - esp32 + - esp32s2 + - esp32s3 + - esp32c2 + - esp32c3 + - esp32c6 + - esp32h2 + - esp32p4 + version: 3.2.0 espressif/cbor: component_hash: 440f4ee4504841cc9b4f3a8ef755776a612ac9dace355514c68b999868f990ff dependencies: - name: idf - registry_url: https://components.espressif.com require: private version: '>=4.3' source: - registry_url: https://components.espressif.com/ + registry_url: https://components.espressif.com type: service version: 0.6.0~1 + espressif/esp-dsp: + component_hash: 42dce32d46ac93dc11f60d368e29a830e9661c7345d794b8a45c343479cae636 + dependencies: + - name: idf + require: private + version: '>=4.2' + source: + registry_url: https://components.espressif.com + type: service + version: 1.7.0 + espressif/esp-modbus: + component_hash: 5d5e90b9e55721a8a194b301ad8102d4affb647f47b74cd413ff7d1ce2c1169c + dependencies: + - name: idf + require: private + version: '>=4.3' + source: + registry_url: https://components.espressif.com + type: service + version: 1.0.18 + espressif/esp-serial-flasher: + component_hash: dcc42a16712a1a636509cf0bf90e14032d7f2141784b533613b267b6aa318d52 + dependencies: [] + source: + registry_url: https://components.espressif.com + type: service + version: 0.0.11 espressif/esp-zboss-lib: component_hash: 2a2256a8d20e5ade59a8e084760c84faa87dc9332523afcb6e245a744420839a dependencies: @@ -28,7 +193,7 @@ dependencies: require: private version: '>=5.0' source: - registry_url: https://components.espressif.com/ + registry_url: https://components.espressif.com type: service version: 1.6.3 espressif/esp-zigbee-lib: @@ -38,9 +203,61 @@ dependencies: require: private version: '>=5.0' source: - registry_url: https://components.espressif.com/ + registry_url: https://components.espressif.com type: service version: 1.6.3 + espressif/esp_diag_data_store: + component_hash: c1e5cf62f545d2b136db299f4df1b228b9840be5bc3410c9ad2d2a882b5c0d64 + dependencies: + - name: idf + require: private + version: '>=4.1' + source: + registry_url: https://components.espressif.com + type: service + version: 1.0.2 + espressif/esp_diagnostics: + component_hash: 5ea8e8da8217ed9ed778db3973139e726e17cd27ef5cf6429c787d19226c79f3 + dependencies: + - name: idf + require: private + version: '>=4.1' + - name: espressif/rmaker_common + registry_url: https://components.espressif.com + require: private + version: ~1.4.0 + source: + registry_url: https://components.espressif.com + type: service + version: 1.2.1 + espressif/esp_insights: + component_hash: 4015c524b9955528f941268cf080174076b195800de910d061efc46113bc2e0c + dependencies: + - name: idf + require: private + version: '>=4.1' + - name: espressif/cbor + registry_url: https://components.espressif.com + require: private + rules: + - if: idf_version >=5.0 + version: ~0.6 + - name: espressif/esp_diag_data_store + registry_url: https://components.espressif.com + require: private + version: 1.0.2 + - name: espressif/esp_diagnostics + registry_url: https://components.espressif.com + require: private + version: 1.2.1 + - name: espressif/rmaker_common + registry_url: https://components.espressif.com + require: private + version: ~1.4.0 + source: + registry_url: https://components.espressif.com + type: service + version: 1.2.2 espressif/esp_modem: component_hash: b541c3f5765d3ba062c0d004b9ca6da6d0af908293421c2dbe046c537fb2a011 dependencies: @@ -48,9 +265,131 @@ dependencies: require: private version: '>=4.1' source: - registry_url: https://components.espressif.com/ + registry_url: https://components.espressif.com type: service version: 1.4.0 + espressif/esp_rainmaker: + component_hash: f6fe458fc7a0102ee2879f0247da4b41419e6c07de12031f66e5e9454d25baaa + dependencies: + - name: espressif/esp_rcp_update + registry_url: https://components.espressif.com + require: private + rules: + - if: idf_version >= 5.1 + version: ~1.2.0 + - name: espressif/esp_schedule + registry_url: https://components.espressif.com + require: private + version: ~1.2.0 + - name: espressif/esp_secure_cert_mgr + registry_url: https://components.espressif.com + require: private + rules: + - if: idf_version >=4.3 + version: ^2.2.1 + - name: espressif/json_generator + registry_url: https://components.espressif.com + require: private + version: ~1.1.1 + - name: espressif/json_parser + registry_url: https://components.espressif.com + require: private + version: ~1.0.3 + - name: espressif/mdns + registry_url: https://components.espressif.com + require: private + rules: + - if: idf_version >=5.0 + version: ^1.2.0 + - name: espressif/network_provisioning + registry_url: https://components.espressif.com + require: private + rules: + - if: idf_version >= 5.1 + version: ~1.0.0 + - name: espressif/rmaker_common + registry_url: https://components.espressif.com + require: private + version: ~1.4.6 + source: + registry_url: https://components.espressif.com + type: service + version: 1.5.2 + espressif/esp_rcp_update: + component_hash: c10afbd54a17f27eed880e61262b161656e6d36ad63376c307f9273e99d0abcd + dependencies: + - name: espressif/esp-serial-flasher + registry_url: https://components.espressif.com + require: private + version: ~0.0.0 + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com + type: service + version: 1.2.0 + espressif/esp_schedule: + component_hash: e202a9c688f7f1ab601efb91d682e4bcfaebc508dcceee1a1e0a0d2d1ca75a26 + dependencies: + - name: espressif/rmaker_common + registry_url: https://components.espressif.com + require: private + version: ~1.4.2 + source: + registry_url: https://components.espressif.com + type: service + version: 1.2.0 + espressif/esp_secure_cert_mgr: + component_hash: 5d9175b416f751ba6a7cb35bdf092f0af85658ce06c4a592c7c541d8017ebeb9 + dependencies: + - name: idf + require: private + version: '>=4.3' + source: + registry_url: https://components.espressif.com + type: service + version: 2.5.0 + espressif/jsmn: + component_hash: d80350c41bbaa827c98a25b6072df00884e72f54885996fab4a4f0aebce6b6c3 + dependencies: + - name: idf + require: private + version: '>=4.3' + source: + registry_url: https://components.espressif.com + type: service + version: 1.1.0 + espressif/json_generator: + component_hash: 45033e1c199b13f1c8c1b544fb7d4e2df6a8e3071ebdcb1b22582b61a7974ff2 + dependencies: [] + source: + registry_url: https://components.espressif.com + type: service + version: 1.1.2 + espressif/json_parser: + component_hash: d74b81729ad06ec11ff5eb5b1b0d7df1d00e6027fc11471f4b139c70dcf1b1e4 + dependencies: + - name: espressif/jsmn + registry_url: https://components.espressif.com + require: private + rules: + - if: idf_version >=5.0 + version: ~1.1 + source: + registry_url: https://components.espressif.com + type: service + version: 1.0.3 + espressif/libsodium: + component_hash: 25b968723c584a2742ca36cebe5a7ef049c6767e059f7b1e1eec69946019025d + dependencies: + - name: idf + require: private + version: '>=4.2' + source: + registry_url: https://components.espressif.com + type: service + version: 1.0.20~2 espressif/mdns: component_hash: 3ec0af5f6bce310512e90f482388d21cc7c0e99668172d2f895356165fc6f7c5 dependencies: @@ -58,20 +397,57 @@ dependencies: require: private version: '>=5.0' source: - registry_url: https://components.espressif.com/ + registry_url: https://components.espressif.com type: service version: 1.8.2 espressif/network_provisioning: component_hash: ef2e10182fd1861e68b821491916327c25416ca7ae70e5a6e43313dbc71fe993 dependencies: - name: idf - registry_url: https://components.espressif.com require: private version: '>=5.1' source: - registry_url: https://components.espressif.com/ + registry_url: https://components.espressif.com type: service version: 1.0.2 + espressif/qrcode: + component_hash: 3b493771bc5d6ad30cbf87c25bf784aada8a08c941504355b55d6b75518ed7bc + dependencies: [] + source: + registry_url: https://components.espressif.com + type: service + version: 0.1.0~2 + espressif/rmaker_common: + component_hash: a3a1df881278d0351fc850b77792fe8a196ddd6dcacbea203d606329cc6a0239 + dependencies: [] + source: + registry_url: https://components.espressif.com + type: service + version: 1.4.6 + h2zero/esp-nimble-cpp: + component_hash: 6fe25905e163f3e6737f3a1f2817618887d86dd88fa724fdad18ac718103984a + dependencies: + - name: espressif/esp_hosted + registry_url: https://components.espressif.com + require: private + rules: + - if: target in [esp32p4] + version: '*' + - name: espressif/esp_wifi_remote + registry_url: https://components.espressif.com + require: private + rules: + - if: target in [esp32p4] + version: '>=0.5.3' + - name: idf + require: private + rules: + - if: target in [esp32p4] + version: '>=5.3.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 2.3.1 idf: source: type: idf @@ -83,19 +459,14 @@ dependencies: require: private version: '>=5.0' source: - registry_url: https://components.espressif.com/ + registry_url: https://components.espressif.com type: service version: 1.20.0 direct_dependencies: -- chmorgan/esp-libhelix-mp3 -- espressif/cbor -- espressif/esp-zboss-lib -- espressif/esp-zigbee-lib -- espressif/esp_modem -- espressif/mdns -- espressif/network_provisioning -- idf -- joltwallet/littlefs -manifest_hash: e9919b5b28bb7bb038864af176d8e81936400eff14ef44258dd5186bdc427ec2 +- bblanchon/arduinojson +- doudar/FastAccelStepper +- espressif/arduino-esp32 +- h2zero/esp-nimble-cpp +manifest_hash: a35e2e02fdd7199ee00e7ac11e63a345f759ba453e99f0153a49769bd73aa883 target: esp32 version: 2.0.0 diff --git a/include/BLE_Fitness_Machine_Service.h b/include/BLE_Fitness_Machine_Service.h index eefbdbe0..adf2184a 100644 --- a/include/BLE_Fitness_Machine_Service.h +++ b/include/BLE_Fitness_Machine_Service.h @@ -21,9 +21,9 @@ class BLE_Fitness_Machine_Service { private: BLEService *pFitnessMachineService; BLECharacteristic *fitnessMachineFeature; - BLECharacteristic *fitnessMachineIndoorBikeData; - BLECharacteristic *fitnessMachineStatusCharacteristic; BLECharacteristic *fitnessMachineControlPoint; + BLECharacteristic *fitnessMachineStatusCharacteristic; + BLECharacteristic *fitnessMachineIndoorBikeData; BLECharacteristic *fitnessMachineResistanceLevelRange; BLECharacteristic *fitnessMachinePowerRange; BLECharacteristic *fitnessMachineInclinationRange; diff --git a/src/BLE_Client.cpp b/main/BLE_Client.cpp similarity index 100% rename from src/BLE_Client.cpp rename to main/BLE_Client.cpp diff --git a/src/BLE_Common.cpp b/main/BLE_Common.cpp similarity index 100% rename from src/BLE_Common.cpp rename to main/BLE_Common.cpp diff --git a/src/BLE_Custom_Characteristic.cpp b/main/BLE_Custom_Characteristic.cpp similarity index 100% rename from src/BLE_Custom_Characteristic.cpp rename to main/BLE_Custom_Characteristic.cpp diff --git a/src/BLE_Cycling_Power_Service.cpp b/main/BLE_Cycling_Power_Service.cpp similarity index 100% rename from src/BLE_Cycling_Power_Service.cpp rename to main/BLE_Cycling_Power_Service.cpp diff --git a/src/BLE_Cycling_Speed_Cadence.cpp b/main/BLE_Cycling_Speed_Cadence.cpp similarity index 100% rename from src/BLE_Cycling_Speed_Cadence.cpp rename to main/BLE_Cycling_Speed_Cadence.cpp diff --git a/src/BLE_Device_Information_Service.cpp b/main/BLE_Device_Information_Service.cpp similarity index 100% rename from src/BLE_Device_Information_Service.cpp rename to main/BLE_Device_Information_Service.cpp diff --git a/src/BLE_Firmware_Update.cpp b/main/BLE_Firmware_Update.cpp similarity index 100% rename from src/BLE_Firmware_Update.cpp rename to main/BLE_Firmware_Update.cpp diff --git a/src/BLE_Fitness_Machine_Service.cpp b/main/BLE_Fitness_Machine_Service.cpp similarity index 100% rename from src/BLE_Fitness_Machine_Service.cpp rename to main/BLE_Fitness_Machine_Service.cpp diff --git a/src/BLE_Heart_Service.cpp b/main/BLE_Heart_Service.cpp similarity index 100% rename from src/BLE_Heart_Service.cpp rename to main/BLE_Heart_Service.cpp diff --git a/src/BLE_SB20_Service.cpp b/main/BLE_SB20_Service.cpp similarity index 100% rename from src/BLE_SB20_Service.cpp rename to main/BLE_SB20_Service.cpp diff --git a/src/BLE_Server.cpp b/main/BLE_Server.cpp similarity index 100% rename from src/BLE_Server.cpp rename to main/BLE_Server.cpp diff --git a/src/BLE_Setup.cpp b/main/BLE_Setup.cpp similarity index 100% rename from src/BLE_Setup.cpp rename to main/BLE_Setup.cpp diff --git a/src/BLE_Wattbike_Service.cpp b/main/BLE_Wattbike_Service.cpp similarity index 100% rename from src/BLE_Wattbike_Service.cpp rename to main/BLE_Wattbike_Service.cpp diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt new file mode 100644 index 00000000..c122670e --- /dev/null +++ b/main/CMakeLists.txt @@ -0,0 +1,19 @@ +# This file was automatically generated for projects +# without default 'CMakeLists.txt' file. + +FILE(GLOB_RECURSE app_sources *.cpp) +FILE(GLOB_RECURSE ss2k_sources ${CMAKE_SOURCE_DIR}/lib/SS2K/src/sensors) +FILE(GLOB_RECURSE aws_sources ${CMAKE_SOURCE_DIR}/lib/ArduinoWebsockets/src) +FILE(GLOB_RECURSE tmcs_sources ${CMAKE_SOURCE_DIR}/lib/TMCStepper/src/source) +set(srcs ${app_sources} ${ss2k_sources} ${aws_sources} ${tmcs_sources}) + +set(include_dirs + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/lib/SS2K/include + ${CMAKE_SOURCE_DIR}/lib/SS2K/include/sensors + ${CMAKE_SOURCE_DIR}/lib/ArduinoWebsockets + ${CMAKE_SOURCE_DIR}/lib/TMCStepper/src + ${CMAKE_SOURCE_DIR}/lib/TMCStepper/src/source +) + +idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "${include_dirs}") diff --git a/src/DirConManager.cpp b/main/DirConManager.cpp similarity index 100% rename from src/DirConManager.cpp rename to main/DirConManager.cpp diff --git a/src/DirConMessage.cpp b/main/DirConMessage.cpp similarity index 100% rename from src/DirConMessage.cpp rename to main/DirConMessage.cpp diff --git a/src/ERG_Mode.cpp b/main/ERG_Mode.cpp similarity index 100% rename from src/ERG_Mode.cpp rename to main/ERG_Mode.cpp diff --git a/src/HTTP_Server_Basic.cpp b/main/HTTP_Server_Basic.cpp similarity index 100% rename from src/HTTP_Server_Basic.cpp rename to main/HTTP_Server_Basic.cpp diff --git a/src/Main.cpp b/main/Main.cpp similarity index 100% rename from src/Main.cpp rename to main/Main.cpp diff --git a/src/PowerTable_Helpers.cpp b/main/PowerTable_Helpers.cpp similarity index 100% rename from src/PowerTable_Helpers.cpp rename to main/PowerTable_Helpers.cpp diff --git a/src/Power_Table.cpp b/main/Power_Table.cpp similarity index 100% rename from src/Power_Table.cpp rename to main/Power_Table.cpp diff --git a/src/SS2KLog.cpp b/main/SS2KLog.cpp similarity index 100% rename from src/SS2KLog.cpp rename to main/SS2KLog.cpp diff --git a/src/SensorCollector.cpp b/main/SensorCollector.cpp similarity index 100% rename from src/SensorCollector.cpp rename to main/SensorCollector.cpp diff --git a/src/SmartSpin_parameters.cpp b/main/SmartSpin_parameters.cpp similarity index 100% rename from src/SmartSpin_parameters.cpp rename to main/SmartSpin_parameters.cpp diff --git a/src/UdpAppender.cpp b/main/UdpAppender.cpp similarity index 100% rename from src/UdpAppender.cpp rename to main/UdpAppender.cpp diff --git a/src/WebsocketAppender.cpp b/main/WebsocketAppender.cpp similarity index 100% rename from src/WebsocketAppender.cpp rename to main/WebsocketAppender.cpp diff --git a/src/gitTracking.md b/main/gitTracking.md similarity index 100% rename from src/gitTracking.md rename to main/gitTracking.md diff --git a/main/idf_component.yml b/main/idf_component.yml new file mode 100644 index 00000000..d614a01a --- /dev/null +++ b/main/idf_component.yml @@ -0,0 +1,7 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/arduino-esp32: ^3.2.0 + h2zero/esp-nimble-cpp: ^2.3.1 + bblanchon/arduinojson: 7.3.1 + doudar/FastAccelStepper: + git: https://github.com/doudar/FastAccelStepper diff --git a/sdkconfig b/sdkconfig index 1287da4d..4be13f57 100644 --- a/sdkconfig +++ b/sdkconfig @@ -406,6 +406,124 @@ CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table +# +# Arduino Configuration +# +CONFIG_ARDUINO_VARIANT="esp32" +CONFIG_ENABLE_ARDUINO_DEPENDS=y +CONFIG_AUTOSTART_ARDUINO=y +# CONFIG_ARDUINO_RUN_CORE0 is not set +CONFIG_ARDUINO_RUN_CORE1=y +# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_RUNNING_CORE=1 +CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 +# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set +CONFIG_ARDUINO_EVENT_RUN_CORE1=y +# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set +CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y +CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=2048 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 +CONFIG_ARDUINO_UDP_RUN_CORE0=y +# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set +# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_UDP_RUNNING_CORE=0 +CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 +# CONFIG_ARDUINO_ISR_IRAM is not set +# CONFIG_DISABLE_HAL_LOCKS is not set + +# +# Debug Log Configuration +# +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE is not set +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR=y +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=1 +# CONFIG_ARDUHAL_LOG_COLORS is not set +# CONFIG_ARDUHAL_ESP_LOG is not set +# end of Debug Log Configuration + +CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT=y +# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS is not set +CONFIG_ARDUHAL_PARTITION_SCHEME="default" +# CONFIG_AUTOCONNECT_WIFI is not set +# CONFIG_ARDUINO_SELECTIVE_COMPILATION is not set +# end of Arduino Configuration + +# +# ESP RainMaker Config +# +CONFIG_ESP_RMAKER_NO_CLAIM=y +# CONFIG_ESP_RMAKER_ASSISTED_CLAIM is not set +# CONFIG_ESP_RMAKER_USE_ESP_SECURE_CERT_MGR is not set +CONFIG_ESP_RMAKER_USE_NVS=y +CONFIG_ESP_RMAKER_CLAIM_TYPE=0 +# CONFIG_ESP_RMAKER_READ_MQTT_HOST_FROM_CONFIG is not set +# CONFIG_ESP_RMAKER_READ_NODE_ID_FROM_CERT_CN is not set +CONFIG_ESP_RMAKER_MQTT_USE_BASIC_INGEST_TOPICS=y +CONFIG_ESP_RMAKER_MQTT_ENABLE_BUDGETING=y +CONFIG_ESP_RMAKER_MQTT_DEFAULT_BUDGET=100 +CONFIG_ESP_RMAKER_MQTT_MAX_BUDGET=1024 +CONFIG_ESP_RMAKER_MQTT_BUDGET_REVIVE_PERIOD=5 +CONFIG_ESP_RMAKER_MQTT_BUDGET_REVIVE_COUNT=1 +CONFIG_ESP_RMAKER_MAX_PARAM_DATA_SIZE=1024 +# CONFIG_ESP_RMAKER_DISABLE_USER_MAPPING_PROV is not set +# CONFIG_ESP_RMAKER_USER_ID_CHECK is not set +# CONFIG_RMAKER_NAME_PARAM_CB is not set +# CONFIG_ESP_RMAKER_LOCAL_CTRL_FEATURE_ENABLE is not set +# CONFIG_ESP_RMAKER_LOCAL_CTRL_AUTO_ENABLE is not set +CONFIG_ESP_RMAKER_CONSOLE_UART_NUM_0=y +# CONFIG_ESP_RMAKER_CONSOLE_UART_NUM_1 is not set +CONFIG_ESP_RMAKER_CONSOLE_UART_NUM=0 +CONFIG_ESP_RMAKER_USE_CERT_BUNDLE=y + +# +# ESP RainMaker OTA Config +# +CONFIG_ESP_RMAKER_OTA_AUTOFETCH=y +CONFIG_ESP_RMAKER_OTA_AUTOFETCH_PERIOD=0 +# CONFIG_ESP_RMAKER_SKIP_COMMON_NAME_CHECK is not set +# CONFIG_ESP_RMAKER_SKIP_VERSION_CHECK is not set +# CONFIG_ESP_RMAKER_SKIP_SECURE_VERSION_CHECK is not set +# CONFIG_ESP_RMAKER_SKIP_PROJECT_NAME_CHECK is not set +CONFIG_ESP_RMAKER_OTA_HTTP_RX_BUFFER_SIZE=1024 +CONFIG_ESP_RMAKER_OTA_ROLLBACK_WAIT_PERIOD=90 +# CONFIG_ESP_RMAKER_OTA_DISABLE_AUTO_REBOOT is not set +CONFIG_ESP_RMAKER_OTA_TIME_SUPPORT=y +# end of ESP RainMaker OTA Config + +# +# ESP RainMaker Scheduling +# +CONFIG_ESP_RMAKER_SCHEDULING_MAX_SCHEDULES=10 +# end of ESP RainMaker Scheduling + +# +# ESP RainMaker Scenes +# +CONFIG_ESP_RMAKER_SCENES_MAX_SCENES=10 +# CONFIG_ESP_RMAKER_SCENES_DEACTIVATE_SUPPORT is not set +# end of ESP RainMaker Scenes + +# +# ESP RainMaker Command-Response +# +CONFIG_ESP_RMAKER_CMD_RESP_ENABLE=y +# CONFIG_ESP_RMAKER_CMD_RESP_TEST_ENABLE is not set +# end of ESP RainMaker Command-Response + +CONFIG_ESP_RMAKER_USING_NETWORK_PROV=y +# end of ESP RainMaker Config + # # Compiler options # @@ -460,10 +578,234 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # # Bluetooth # -# CONFIG_BT_ENABLED is not set +CONFIG_BT_ENABLED=y +# CONFIG_BT_BLUEDROID_ENABLED is not set +CONFIG_BT_NIMBLE_ENABLED=y +# CONFIG_BT_CONTROLLER_ONLY is not set +CONFIG_BT_CONTROLLER_ENABLED=y +# CONFIG_BT_CONTROLLER_DISABLED is not set + +# +# NimBLE Options +# +CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y +# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set +CONFIG_BT_NIMBLE_LOG_LEVEL_NONE=y +# CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_WARNING is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_INFO is not set +# CONFIG_BT_NIMBLE_LOG_LEVEL_DEBUG is not set +CONFIG_BT_NIMBLE_LOG_LEVEL=4 +CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 +CONFIG_BT_NIMBLE_MAX_BONDS=3 +CONFIG_BT_NIMBLE_MAX_CCCDS=8 +CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM=0 +CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y +# CONFIG_BT_NIMBLE_PINNED_TO_CORE_1 is not set +CONFIG_BT_NIMBLE_PINNED_TO_CORE=0 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=4096 +CONFIG_BT_NIMBLE_ROLE_CENTRAL=y +CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y +CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y +CONFIG_BT_NIMBLE_ROLE_OBSERVER=y +# CONFIG_BT_NIMBLE_NVS_PERSIST is not set +# CONFIG_BT_NIMBLE_SMP_ID_RESET is not set +CONFIG_BT_NIMBLE_SECURITY_ENABLE=y +CONFIG_BT_NIMBLE_SM_LEGACY=y +CONFIG_BT_NIMBLE_SM_SC=y +# CONFIG_BT_NIMBLE_SM_SC_DEBUG_KEYS is not set +CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_ENCRYPTION=y +CONFIG_BT_NIMBLE_SM_LVL=0 +CONFIG_BT_NIMBLE_SM_SC_ONLY=0 +# CONFIG_BT_NIMBLE_DEBUG is not set +# CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set +CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" +CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 +CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=256 +CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE=0 + +# +# Memory Settings +# +CONFIG_BT_NIMBLE_MSYS_1_BLOCK_COUNT=12 +CONFIG_BT_NIMBLE_MSYS_1_BLOCK_SIZE=256 +CONFIG_BT_NIMBLE_MSYS_2_BLOCK_COUNT=24 +CONFIG_BT_NIMBLE_MSYS_2_BLOCK_SIZE=320 +CONFIG_BT_NIMBLE_TRANSPORT_ACL_FROM_LL_COUNT=24 +CONFIG_BT_NIMBLE_TRANSPORT_ACL_SIZE=255 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_COUNT=30 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_DISCARD_COUNT=8 +CONFIG_BT_NIMBLE_L2CAP_COC_SDU_BUFF_COUNT=1 +# end of Memory Settings + +CONFIG_BT_NIMBLE_GATT_MAX_PROCS=4 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL=y +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y +CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 +# CONFIG_BT_NIMBLE_MESH is not set +CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y +CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 +# CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set +# CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set +CONFIG_BT_NIMBLE_WHITELIST_SIZE=12 +# CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set +# CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set +CONFIG_BT_NIMBLE_USE_ESP_TIMER=y +CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y +# CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set + +# +# GAP Service +# + +# +# GAP Appearance write permissions +# +# CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set +# end of GAP Appearance write permissions + +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ENC=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHN=0 +CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHR=0 +CONFIG_BT_NIMBLE_SVC_GAP_CAR_CHAR_NOT_SUPP=y +# CONFIG_BT_NIMBLE_SVC_GAP_CAR_NOT_SUPP is not set +# CONFIG_BT_NIMBLE_SVC_GAP_CAR_SUPP is not set +CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 + +# +# GAP device name write permissions +# +# CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set +# end of GAP device name write permissions + +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_ENC=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHEN=0 +CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHOR=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 +CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 +# CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL is not set +# end of GAP Service + +# +# BLE Services +# +# CONFIG_BT_NIMBLE_HID_SERVICE is not set +# CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY is not set + +# +# Device Information Service +# +# CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME is not set +# CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER is not set +# CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION is not set +# CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION is not set +# CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION is not set +# CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID is not set +# CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID is not set +# CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED is not set +# end of Device Information Service +# end of BLE Services + +# CONFIG_BT_NIMBLE_VS_SUPPORT is not set +# CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set +# CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set +# CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set +# CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT is not set + +# +# Host-controller Transport +# +CONFIG_UART_HW_FLOWCTRL_DISABLE=y +# CONFIG_UART_HW_FLOWCTRL_CTS_RTS is not set +CONFIG_BT_NIMBLE_HCI_UART_FLOW_CTRL=0 +CONFIG_BT_NIMBLE_HCI_UART_RTS_PIN=19 +CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 +# end of Host-controller Transport + +CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 +# CONFIG_BT_NIMBLE_SUBRATE is not set +# end of NimBLE Options + +# +# Controller Options +# +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +# CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set +# CONFIG_BTDM_CTRL_MODE_BTDM is not set +CONFIG_BTDM_CTRL_BLE_MAX_CONN=3 +CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 +CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 +CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 +CONFIG_BTDM_CTRL_PCM_FSYNCSHP_EFF=0 +CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=3 +CONFIG_BTDM_CTRL_BR_EDR_MIN_ENC_KEY_SZ_DFT_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CTRL_PINNED_TO_CORE_0=y +# CONFIG_BTDM_CTRL_PINNED_TO_CORE_1 is not set +CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 +CONFIG_BTDM_CTRL_HCI_MODE_VHCI=y +# CONFIG_BTDM_CTRL_HCI_MODE_UART_H4 is not set + +# +# MODEM SLEEP Options +# +CONFIG_BTDM_CTRL_MODEM_SLEEP=y +CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG=y +# CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_EVED is not set +CONFIG_BTDM_CTRL_LPCLK_SEL_MAIN_XTAL=y +# end of MODEM SLEEP Options + +CONFIG_BTDM_BLE_DEFAULT_SCA_250PPM=y +CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 +CONFIG_BTDM_BLE_SCAN_DUPL=y +CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y +# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA is not set +# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE is not set +CONFIG_BTDM_SCAN_DUPL_TYPE=0 +CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 +CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 +# CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set +CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y +# CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set +# CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set +CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y +CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 +CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 + +# +# BLE disconnects when Instant Passed (0x28) occurs +# +# CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set +# CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set +# end of BLE disconnects when Instant Passed (0x28) occurs + +CONFIG_BTDM_BLE_CHAN_ASS_EN=y +CONFIG_BTDM_BLE_PING_EN=y +# CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 is not set +CONFIG_BTDM_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_CTRL_HLI=y +# end of Controller Options + +# +# Common Options +# CONFIG_BT_ALARM_MAX_NUM=50 +# CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set +# end of Common Options + +# CONFIG_BT_HCI_LOG_DEBUG_EN is not set # end of Bluetooth +# CONFIG_BLE_MESH is not set + # # Console Library # @@ -598,6 +940,8 @@ CONFIG_ADC_DISABLE_DAC_OUTPUT=y # Wireless Coexistence # CONFIG_ESP_COEX_ENABLED=y +CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y +# CONFIG_ESP_COEX_POWER_MANAGEMENT is not set # CONFIG_ESP_COEX_GPIO_DEBUG is not set # end of Wireless Coexistence @@ -1017,8 +1361,7 @@ CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y # CONFIG_ESP_PANIC_HANDLER_IRAM is not set # CONFIG_ESP_DEBUG_STUBS_ENABLE is not set CONFIG_ESP_DEBUG_OCDAWARE=y -# CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set -CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y # # Brownout Detector @@ -1339,7 +1682,7 @@ CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -# CONFIG_LWIP_SO_RCVBUF is not set +CONFIG_LWIP_SO_RCVBUF=y # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP_DEFAULT_TTL=64 CONFIG_LWIP_IP4_FRAG=y @@ -1884,9 +2227,295 @@ CONFIG_WL_SECTOR_SIZE=4096 # CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_WIFI_PROV_BLE_BONDING is not set +CONFIG_WIFI_PROV_BLE_SEC_CONN=y +# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set +# CONFIG_WIFI_PROV_BLE_NOTIFY is not set +# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set # end of Wi-Fi Provisioning Manager + +# +# DSP Library +# +CONFIG_DSP_OPTIMIZATIONS_SUPPORTED=y +# CONFIG_DSP_ANSI is not set +CONFIG_DSP_OPTIMIZED=y +CONFIG_DSP_OPTIMIZATION=1 +# CONFIG_DSP_MAX_FFT_SIZE_512 is not set +# CONFIG_DSP_MAX_FFT_SIZE_1024 is not set +# CONFIG_DSP_MAX_FFT_SIZE_2048 is not set +CONFIG_DSP_MAX_FFT_SIZE_4096=y +# CONFIG_DSP_MAX_FFT_SIZE_8192 is not set +# CONFIG_DSP_MAX_FFT_SIZE_16384 is not set +# CONFIG_DSP_MAX_FFT_SIZE_32768 is not set +CONFIG_DSP_MAX_FFT_SIZE=4096 +# end of DSP Library + +# +# Modbus configuration +# +CONFIG_FMB_COMM_MODE_TCP_EN=y +CONFIG_FMB_TCP_PORT_DEFAULT=502 +CONFIG_FMB_TCP_PORT_MAX_CONN=5 +CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 +# CONFIG_FMB_TCP_UID_ENABLED is not set +CONFIG_FMB_COMM_MODE_RTU_EN=y +CONFIG_FMB_COMM_MODE_ASCII_EN=y +CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=3000 +CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_FMB_QUEUE_LENGTH=20 +CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 +CONFIG_FMB_SERIAL_BUF_SIZE=256 +CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 +CONFIG_FMB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS=0 +CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 +CONFIG_FMB_PORT_TASK_PRIO=10 +# CONFIG_FMB_PORT_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_FMB_PORT_TASK_AFFINITY_CPU0=y +# CONFIG_FMB_PORT_TASK_AFFINITY_CPU1 is not set +CONFIG_FMB_PORT_TASK_AFFINITY=0x0 +CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_FMB_CONTROLLER_SLAVE_ID_MAX_SIZE=32 +CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 +CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 +# CONFIG_FMB_TIMER_PORT_ENABLED is not set +# CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD is not set +# CONFIG_FMB_EXT_TYPE_SUPPORT is not set +# end of Modbus configuration + +# +# ESP serial flasher +# +CONFIG_SERIAL_FLASHER_MD5_ENABLED=y +CONFIG_SERIAL_FLASHER_RESET_HOLD_TIME_MS=100 +CONFIG_SERIAL_FLASHER_BOOT_HOLD_TIME_MS=50 +# end of ESP serial flasher + +# +# Zigbee +# +# CONFIG_ZB_ENABLED is not set +# end of Zigbee + +# +# Diagnostics data store +# +CONFIG_DIAG_DATA_STORE_RTC=y +# CONFIG_DIAG_DATA_STORE_FLASH is not set +# CONFIG_DIAG_DATA_STORE_DBG_PRINTS is not set +CONFIG_DIAG_DATA_STORE_REPORTING_WATERMARK_PERCENT=80 + +# +# RTC Store +# +CONFIG_RTC_STORE_DATA_SIZE=3072 +CONFIG_RTC_STORE_CRITICAL_DATA_SIZE=2048 +# end of RTC Store +# end of Diagnostics data store + +# +# Diagnostics +# +CONFIG_DIAG_LOG_MSG_ARG_FORMAT_TLV=y +# CONFIG_DIAG_LOG_MSG_ARG_FORMAT_STRING is not set +CONFIG_DIAG_LOG_MSG_ARG_MAX_SIZE=64 +CONFIG_DIAG_LOG_DROP_WIFI_LOGS=y +CONFIG_DIAG_ENABLE_METRICS=y +CONFIG_DIAG_METRICS_MAX_COUNT=20 +CONFIG_DIAG_ENABLE_HEAP_METRICS=y +CONFIG_DIAG_ENABLE_WIFI_METRICS=y +CONFIG_DIAG_ENABLE_VARIABLES=y +CONFIG_DIAG_VARIABLES_MAX_COUNT=20 +CONFIG_DIAG_ENABLE_NETWORK_VARIABLES=y +# CONFIG_DIAG_MORE_NETWORK_VARS is not set +# CONFIG_DIAG_USE_EXTERNAL_LOG_WRAP is not set +# end of Diagnostics + +# +# ESP Insights +# +# CONFIG_ESP_INSIGHTS_ENABLED is not set +# CONFIG_ESP_INSIGHTS_TRANSPORT_MQTT is not set +CONFIG_ESP_INSIGHTS_TRANSPORT_HTTPS=y +CONFIG_ESP_INSIGHTS_TRANSPORT_HTTPS_HOST="https://client.insights.espressif.com" +CONFIG_ESP_INSIGHTS_CLOUD_POST_MIN_INTERVAL_SEC=60 +CONFIG_ESP_INSIGHTS_CLOUD_POST_MAX_INTERVAL_SEC=240 +CONFIG_ESP_INSIGHTS_META_VERSION_10=y +# end of ESP Insights + +# +# esp-modem +# +CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y +# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set +CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 +# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set +# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set +CONFIG_ESP_MODEM_C_API_STR_MAX=128 +# CONFIG_ESP_MODEM_URC_HANDLER is not set +# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set +# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set +# end of esp-modem + +# +# OpenThread RCP Update +# +# CONFIG_AUTO_UPDATE_RCP is not set +# CONFIG_CREATE_OTA_IMAGE_WITH_RCP_FW is not set +# end of OpenThread RCP Update + +# +# ESP Secure Cert Manager +# +# CONFIG_ESP_SECURE_CERT_SUPPORT_LEGACY_FORMATS is not set +# end of ESP Secure Cert Manager + +# +# jsmn +# +# CONFIG_JSMN_PARENT_LINKS is not set +# CONFIG_JSMN_STRICT is not set +# CONFIG_JSMN_STATIC is not set +# end of jsmn + +# +# libsodium +# +# end of libsodium + +# +# mDNS +# +CONFIG_MDNS_MAX_INTERFACES=3 +CONFIG_MDNS_MAX_SERVICES=10 +CONFIG_MDNS_TASK_PRIORITY=1 +CONFIG_MDNS_ACTION_QUEUE_LEN=16 +CONFIG_MDNS_TASK_STACK_SIZE=4096 +# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_MDNS_TASK_AFFINITY_CPU0=y +# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set +CONFIG_MDNS_TASK_AFFINITY=0x0 + +# +# MDNS Memory Configuration +# +CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y +CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y +# CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set +# end of MDNS Memory Configuration + +CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 +CONFIG_MDNS_TIMER_PERIOD_MS=100 +# CONFIG_MDNS_NETWORKING_SOCKET is not set +# CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set +# CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set +CONFIG_MDNS_ENABLE_CONSOLE_CLI=y +# CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set +CONFIG_MDNS_MULTIPLE_INSTANCE=y + +# +# MDNS Predefined interfaces +# +CONFIG_MDNS_PREDEF_NETIF_STA=y +CONFIG_MDNS_PREDEF_NETIF_AP=y +CONFIG_MDNS_PREDEF_NETIF_ETH=y +# end of MDNS Predefined interfaces +# end of mDNS + +# +# Network Provisioning Manager +# +CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y +CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_NETWORK_PROV_BLE_BONDING is not set +CONFIG_NETWORK_PROV_BLE_SEC_CONN=y +# CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set +# CONFIG_NETWORK_PROV_KEEP_BLE_ON_AFTER_PROV is not set +CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y +# CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set +# end of Network Provisioning Manager + +# +# ESP RainMaker Common +# +CONFIG_ESP_RMAKER_LIB_ESP_MQTT=y +# CONFIG_ESP_RMAKER_LIB_AWS_IOT is not set +CONFIG_ESP_RMAKER_MQTT_GLUE_LIB=1 +CONFIG_ESP_RMAKER_MQTT_PORT_443=y +# CONFIG_ESP_RMAKER_MQTT_PORT_8883 is not set +CONFIG_ESP_RMAKER_MQTT_PORT=1 +# CONFIG_ESP_RMAKER_MQTT_PERSISTENT_SESSION is not set +CONFIG_ESP_RMAKER_MQTT_SEND_USERNAME=y +CONFIG_ESP_RMAKER_MQTT_PRODUCT_NAME="RMDev" +CONFIG_ESP_RMAKER_MQTT_PRODUCT_VERSION="1x0" +CONFIG_ESP_RMAKER_MQTT_PRODUCT_SKU="EX00" +CONFIG_ESP_RMAKER_MQTT_USE_CERT_BUNDLE=y +CONFIG_ESP_RMAKER_MAX_MQTT_SUBSCRIPTIONS=10 +CONFIG_ESP_RMAKER_MQTT_KEEP_ALIVE_INTERVAL=120 +CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI=y +CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_STACK=4096 +CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_PRIORITY=5 +CONFIG_ESP_RMAKER_FACTORY_PARTITION_NAME="fctry" +CONFIG_ESP_RMAKER_FACTORY_NAMESPACE="rmaker_creds" +CONFIG_ESP_RMAKER_DEF_TIMEZONE="Asia/Shanghai" +CONFIG_ESP_RMAKER_SNTP_SERVER_NAME="pool.ntp.org" +CONFIG_ESP_RMAKER_MAX_COMMANDS=10 +# end of ESP RainMaker Common + +# +# ESP-NimBLE-CPP configuration +# +CONFIG_NIMBLE_CPP_LOG_LEVEL_NONE=y +# CONFIG_NIMBLE_CPP_LOG_LEVEL_ERROR is not set +# CONFIG_NIMBLE_CPP_LOG_LEVEL_WARNING is not set +# CONFIG_NIMBLE_CPP_LOG_LEVEL_INFO is not set +# CONFIG_NIMBLE_CPP_LOG_LEVEL_DEBUG is not set +CONFIG_NIMBLE_CPP_LOG_LEVEL=0 +# CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR is not set +# CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT is not set +# CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT is not set +# CONFIG_NIMBLE_CPP_ENABLE_ADVERTISEMENT_TYPE_TEXT is not set +# CONFIG_NIMBLE_CPP_ADDR_FMT_EXCLUDE_DELIMITER is not set +# CONFIG_NIMBLE_CPP_ADDR_FMT_UPPERCASE is not set +# CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED is not set +CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH=20 +# CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED is not set +CONFIG_NIMBLE_CPP_FREERTOS_TASK_BLOCK_BIT=31 +# end of ESP-NimBLE-CPP configuration + +# +# LittleFS +# +# CONFIG_LITTLEFS_SDMMC_SUPPORT is not set +CONFIG_LITTLEFS_MAX_PARTITIONS=3 +CONFIG_LITTLEFS_PAGE_SIZE=256 +CONFIG_LITTLEFS_OBJ_NAME_LEN=64 +CONFIG_LITTLEFS_READ_SIZE=128 +CONFIG_LITTLEFS_WRITE_SIZE=128 +CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 +CONFIG_LITTLEFS_CACHE_SIZE=512 +CONFIG_LITTLEFS_BLOCK_CYCLES=512 +CONFIG_LITTLEFS_USE_MTIME=y +# CONFIG_LITTLEFS_USE_ONLY_HASH is not set +# CONFIG_LITTLEFS_HUMAN_READABLE is not set +CONFIG_LITTLEFS_MTIME_USE_SECONDS=y +# CONFIG_LITTLEFS_MTIME_USE_NONCE is not set +# CONFIG_LITTLEFS_SPIFFS_COMPAT is not set +# CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set +# CONFIG_LITTLEFS_FCNTL_GET_PATH is not set +# CONFIG_LITTLEFS_MULTIVERSION is not set +# CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set +CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y +# CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set +CONFIG_LITTLEFS_ASSERTS=y +# CONFIG_LITTLEFS_MMAP_PARTITION is not set +# end of LittleFS # end of Component config # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set @@ -1911,6 +2540,7 @@ CONFIG_LOG_BOOTLOADER_LEVEL=3 CONFIG_FLASHMODE_DIO=y # CONFIG_FLASHMODE_DOUT is not set CONFIG_MONITOR_BAUD=115200 +# CONFIG_ESP_RMAKER_LOCAL_CTRL_ENABLE is not set CONFIG_OPTIMIZATION_LEVEL_DEBUG=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y @@ -1929,7 +2559,72 @@ CONFIG_STACK_CHECK_NONE=y # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set CONFIG_ESP32_APPTRACE_DEST_NONE=y CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +# CONFIG_BLUEDROID_ENABLED is not set +CONFIG_NIMBLE_ENABLED=y +CONFIG_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y +# CONFIG_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set +CONFIG_NIMBLE_MAX_CONNECTIONS=7 +CONFIG_NIMBLE_MAX_BONDS=3 +CONFIG_NIMBLE_MAX_CCCDS=8 +CONFIG_NIMBLE_L2CAP_COC_MAX_NUM=0 +CONFIG_NIMBLE_PINNED_TO_CORE_0=y +# CONFIG_NIMBLE_PINNED_TO_CORE_1 is not set +CONFIG_NIMBLE_PINNED_TO_CORE=0 +CONFIG_NIMBLE_TASK_STACK_SIZE=4096 +CONFIG_BT_NIMBLE_TASK_STACK_SIZE=4096 +CONFIG_NIMBLE_ROLE_CENTRAL=y +CONFIG_NIMBLE_ROLE_PERIPHERAL=y +CONFIG_NIMBLE_ROLE_BROADCASTER=y +CONFIG_NIMBLE_ROLE_OBSERVER=y +# CONFIG_NIMBLE_NVS_PERSIST is not set +CONFIG_NIMBLE_SM_LEGACY=y +CONFIG_NIMBLE_SM_SC=y +# CONFIG_NIMBLE_SM_SC_DEBUG_KEYS is not set +CONFIG_BT_NIMBLE_SM_SC_LVL=0 +# CONFIG_NIMBLE_DEBUG is not set +CONFIG_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" +CONFIG_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 +CONFIG_NIMBLE_ATT_PREFERRED_MTU=256 +CONFIG_NIMBLE_SVC_GAP_APPEARANCE=0 +CONFIG_BT_NIMBLE_MSYS1_BLOCK_COUNT=12 +CONFIG_BT_NIMBLE_ACL_BUF_COUNT=24 +CONFIG_BT_NIMBLE_ACL_BUF_SIZE=255 +CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70 +CONFIG_BT_NIMBLE_HCI_EVT_HI_BUF_COUNT=30 +CONFIG_BT_NIMBLE_HCI_EVT_LO_BUF_COUNT=8 +CONFIG_NIMBLE_HS_FLOW_CTRL=y +CONFIG_NIMBLE_HS_FLOW_CTRL_ITVL=1000 +CONFIG_NIMBLE_HS_FLOW_CTRL_THRESH=2 +CONFIG_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y +CONFIG_NIMBLE_RPA_TIMEOUT=900 +# CONFIG_NIMBLE_MESH is not set +CONFIG_NIMBLE_CRYPTO_STACK_MBEDTLS=y +CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y +# CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY is not set +# CONFIG_BTDM_CONTROLLER_MODE_BTDM is not set +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=3 +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=3 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 +CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI=y +# CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4 is not set +CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=y +CONFIG_BLE_SCAN_DUPLICATE=y +CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y +# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA is not set +# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR is not set +CONFIG_SCAN_DUPLICATE_TYPE=0 +CONFIG_DUPLICATE_SCAN_CACHE_SIZE=100 +# CONFIG_BLE_MESH_SCAN_DUPLICATE_EN is not set +CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y +CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED=y +CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM=100 +CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 CONFIG_ADC2_DISABLE_DAC=y +CONFIG_SW_COEXIST_ENABLE=y +CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y +CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y # CONFIG_MCPWM_ISR_IN_IRAM is not set # CONFIG_EVENT_LOOP_PROFILING is not set CONFIG_POST_EVENTS_FROM_ISR=y @@ -2100,4 +2795,18 @@ CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=3000 +CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_MB_QUEUE_LENGTH=20 +CONFIG_MB_SERIAL_TASK_STACK_SIZE=4096 +CONFIG_MB_SERIAL_BUF_SIZE=256 +CONFIG_MB_SERIAL_TASK_PRIO=10 +CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_MB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_MB_CONTROLLER_STACK_SIZE=4096 +CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 +# CONFIG_MB_TIMER_PORT_ENABLED is not set +CONFIG_NIMBLE_ENABLED=y # End of deprecated options diff --git a/sdkconfig.defaults b/sdkconfig.defaults index d50929ea..75cef2f8 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -1,6 +1,12 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) 5.4.1 Project Minimal Configuration +# +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_AUTOSTART_ARDUINO=y -# CONFIG_WS2812_LED_ENABLE is not set +CONFIG_ESP_RMAKER_NO_CLAIM=y +CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_BT_NIMBLE_LOG_LEVEL_NONE=y +CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 CONFIG_FREERTOS_HZ=1000 CONFIG_MBEDTLS_PSK_MODES=y CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y -CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y \ No newline at end of file diff --git a/sdkconfig.old b/sdkconfig.old index 07c9dd84..2ed7e033 100644 --- a/sdkconfig.old +++ b/sdkconfig.old @@ -374,14 +374,14 @@ CONFIG_ESPTOOLPY_FLASHFREQ_40M=y # CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set CONFIG_ESPTOOLPY_FLASHFREQ="40m" # CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y -# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y # CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="2MB" +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set @@ -406,6 +406,123 @@ CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table +# +# Arduino Configuration +# +CONFIG_ARDUINO_VARIANT="esp32" +CONFIG_ENABLE_ARDUINO_DEPENDS=y +CONFIG_AUTOSTART_ARDUINO=y +# CONFIG_ARDUINO_RUN_CORE0 is not set +CONFIG_ARDUINO_RUN_CORE1=y +# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_RUNNING_CORE=1 +CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 +# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set +CONFIG_ARDUINO_EVENT_RUN_CORE1=y +# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set +CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y +CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=2048 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 +CONFIG_ARDUINO_UDP_RUN_CORE0=y +# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set +# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_UDP_RUNNING_CORE=0 +CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 +# CONFIG_ARDUINO_ISR_IRAM is not set +# CONFIG_DISABLE_HAL_LOCKS is not set + +# +# Debug Log Configuration +# +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE is not set +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR=y +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=1 +# CONFIG_ARDUHAL_LOG_COLORS is not set +# CONFIG_ARDUHAL_ESP_LOG is not set +# end of Debug Log Configuration + +CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT=y +# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS is not set +CONFIG_ARDUHAL_PARTITION_SCHEME="default" +# CONFIG_AUTOCONNECT_WIFI is not set +# CONFIG_ARDUINO_SELECTIVE_COMPILATION is not set +# end of Arduino Configuration + +# +# ESP RainMaker Config +# +CONFIG_ESP_RMAKER_NO_CLAIM=y +# CONFIG_ESP_RMAKER_USE_ESP_SECURE_CERT_MGR is not set +CONFIG_ESP_RMAKER_USE_NVS=y +CONFIG_ESP_RMAKER_CLAIM_TYPE=0 +# CONFIG_ESP_RMAKER_READ_MQTT_HOST_FROM_CONFIG is not set +# CONFIG_ESP_RMAKER_READ_NODE_ID_FROM_CERT_CN is not set +CONFIG_ESP_RMAKER_MQTT_USE_BASIC_INGEST_TOPICS=y +CONFIG_ESP_RMAKER_MQTT_ENABLE_BUDGETING=y +CONFIG_ESP_RMAKER_MQTT_DEFAULT_BUDGET=100 +CONFIG_ESP_RMAKER_MQTT_MAX_BUDGET=1024 +CONFIG_ESP_RMAKER_MQTT_BUDGET_REVIVE_PERIOD=5 +CONFIG_ESP_RMAKER_MQTT_BUDGET_REVIVE_COUNT=1 +CONFIG_ESP_RMAKER_MAX_PARAM_DATA_SIZE=1024 +# CONFIG_ESP_RMAKER_DISABLE_USER_MAPPING_PROV is not set +# CONFIG_ESP_RMAKER_USER_ID_CHECK is not set +# CONFIG_RMAKER_NAME_PARAM_CB is not set +# CONFIG_ESP_RMAKER_LOCAL_CTRL_FEATURE_ENABLE is not set +# CONFIG_ESP_RMAKER_LOCAL_CTRL_AUTO_ENABLE is not set +CONFIG_ESP_RMAKER_CONSOLE_UART_NUM_0=y +# CONFIG_ESP_RMAKER_CONSOLE_UART_NUM_1 is not set +CONFIG_ESP_RMAKER_CONSOLE_UART_NUM=0 +CONFIG_ESP_RMAKER_USE_CERT_BUNDLE=y + +# +# ESP RainMaker OTA Config +# +CONFIG_ESP_RMAKER_OTA_AUTOFETCH=y +CONFIG_ESP_RMAKER_OTA_AUTOFETCH_PERIOD=0 +# CONFIG_ESP_RMAKER_SKIP_COMMON_NAME_CHECK is not set +# CONFIG_ESP_RMAKER_SKIP_VERSION_CHECK is not set +# CONFIG_ESP_RMAKER_SKIP_SECURE_VERSION_CHECK is not set +# CONFIG_ESP_RMAKER_SKIP_PROJECT_NAME_CHECK is not set +CONFIG_ESP_RMAKER_OTA_HTTP_RX_BUFFER_SIZE=1024 +CONFIG_ESP_RMAKER_OTA_ROLLBACK_WAIT_PERIOD=90 +# CONFIG_ESP_RMAKER_OTA_DISABLE_AUTO_REBOOT is not set +CONFIG_ESP_RMAKER_OTA_TIME_SUPPORT=y +# end of ESP RainMaker OTA Config + +# +# ESP RainMaker Scheduling +# +CONFIG_ESP_RMAKER_SCHEDULING_MAX_SCHEDULES=10 +# end of ESP RainMaker Scheduling + +# +# ESP RainMaker Scenes +# +CONFIG_ESP_RMAKER_SCENES_MAX_SCENES=10 +# CONFIG_ESP_RMAKER_SCENES_DEACTIVATE_SUPPORT is not set +# end of ESP RainMaker Scenes + +# +# ESP RainMaker Command-Response +# +CONFIG_ESP_RMAKER_CMD_RESP_ENABLE=y +# CONFIG_ESP_RMAKER_CMD_RESP_TEST_ENABLE is not set +# end of ESP RainMaker Command-Response + +CONFIG_ESP_RMAKER_USING_NETWORK_PROV=y +# end of ESP RainMaker Config + # # Compiler options # @@ -461,6 +578,7 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # Bluetooth # # CONFIG_BT_ENABLED is not set +# CONFIG_BT_NIMBLE_ENABLED is not set CONFIG_BT_ALARM_MAX_NUM=50 # end of Bluetooth @@ -1339,7 +1457,7 @@ CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -# CONFIG_LWIP_SO_RCVBUF is not set +CONFIG_LWIP_SO_RCVBUF=y # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP_DEFAULT_TTL=64 CONFIG_LWIP_IP4_FRAG=y @@ -1887,6 +2005,284 @@ CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set # end of Wi-Fi Provisioning Manager + +# +# DSP Library +# +CONFIG_DSP_OPTIMIZATIONS_SUPPORTED=y +# CONFIG_DSP_ANSI is not set +CONFIG_DSP_OPTIMIZED=y +CONFIG_DSP_OPTIMIZATION=1 +# CONFIG_DSP_MAX_FFT_SIZE_512 is not set +# CONFIG_DSP_MAX_FFT_SIZE_1024 is not set +# CONFIG_DSP_MAX_FFT_SIZE_2048 is not set +CONFIG_DSP_MAX_FFT_SIZE_4096=y +# CONFIG_DSP_MAX_FFT_SIZE_8192 is not set +# CONFIG_DSP_MAX_FFT_SIZE_16384 is not set +# CONFIG_DSP_MAX_FFT_SIZE_32768 is not set +CONFIG_DSP_MAX_FFT_SIZE=4096 +# end of DSP Library + +# +# Modbus configuration +# +CONFIG_FMB_COMM_MODE_TCP_EN=y +CONFIG_FMB_TCP_PORT_DEFAULT=502 +CONFIG_FMB_TCP_PORT_MAX_CONN=5 +CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 +# CONFIG_FMB_TCP_UID_ENABLED is not set +CONFIG_FMB_COMM_MODE_RTU_EN=y +CONFIG_FMB_COMM_MODE_ASCII_EN=y +CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=3000 +CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_FMB_QUEUE_LENGTH=20 +CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 +CONFIG_FMB_SERIAL_BUF_SIZE=256 +CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 +CONFIG_FMB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS=0 +CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 +CONFIG_FMB_PORT_TASK_PRIO=10 +# CONFIG_FMB_PORT_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_FMB_PORT_TASK_AFFINITY_CPU0=y +# CONFIG_FMB_PORT_TASK_AFFINITY_CPU1 is not set +CONFIG_FMB_PORT_TASK_AFFINITY=0x0 +CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_FMB_CONTROLLER_SLAVE_ID_MAX_SIZE=32 +CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 +CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 +# CONFIG_FMB_TIMER_PORT_ENABLED is not set +# CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD is not set +# CONFIG_FMB_EXT_TYPE_SUPPORT is not set +# end of Modbus configuration + +# +# ESP serial flasher +# +CONFIG_SERIAL_FLASHER_MD5_ENABLED=y +CONFIG_SERIAL_FLASHER_RESET_HOLD_TIME_MS=100 +CONFIG_SERIAL_FLASHER_BOOT_HOLD_TIME_MS=50 +# end of ESP serial flasher + +# +# Zigbee +# +# CONFIG_ZB_ENABLED is not set +# end of Zigbee + +# +# Diagnostics data store +# +CONFIG_DIAG_DATA_STORE_RTC=y +# CONFIG_DIAG_DATA_STORE_FLASH is not set +# CONFIG_DIAG_DATA_STORE_DBG_PRINTS is not set +CONFIG_DIAG_DATA_STORE_REPORTING_WATERMARK_PERCENT=80 + +# +# RTC Store +# +CONFIG_RTC_STORE_DATA_SIZE=3072 +CONFIG_RTC_STORE_CRITICAL_DATA_SIZE=2048 +# end of RTC Store +# end of Diagnostics data store + +# +# Diagnostics +# +CONFIG_DIAG_LOG_MSG_ARG_FORMAT_TLV=y +# CONFIG_DIAG_LOG_MSG_ARG_FORMAT_STRING is not set +CONFIG_DIAG_LOG_MSG_ARG_MAX_SIZE=64 +CONFIG_DIAG_LOG_DROP_WIFI_LOGS=y +CONFIG_DIAG_ENABLE_METRICS=y +CONFIG_DIAG_METRICS_MAX_COUNT=20 +CONFIG_DIAG_ENABLE_HEAP_METRICS=y +CONFIG_DIAG_ENABLE_WIFI_METRICS=y +CONFIG_DIAG_ENABLE_VARIABLES=y +CONFIG_DIAG_VARIABLES_MAX_COUNT=20 +CONFIG_DIAG_ENABLE_NETWORK_VARIABLES=y +# CONFIG_DIAG_MORE_NETWORK_VARS is not set +# CONFIG_DIAG_USE_EXTERNAL_LOG_WRAP is not set +# end of Diagnostics + +# +# ESP Insights +# +# CONFIG_ESP_INSIGHTS_ENABLED is not set +# CONFIG_ESP_INSIGHTS_TRANSPORT_MQTT is not set +CONFIG_ESP_INSIGHTS_TRANSPORT_HTTPS=y +CONFIG_ESP_INSIGHTS_TRANSPORT_HTTPS_HOST="https://client.insights.espressif.com" +CONFIG_ESP_INSIGHTS_CLOUD_POST_MIN_INTERVAL_SEC=60 +CONFIG_ESP_INSIGHTS_CLOUD_POST_MAX_INTERVAL_SEC=240 +CONFIG_ESP_INSIGHTS_META_VERSION_10=y +# end of ESP Insights + +# +# esp-modem +# +CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y +# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set +CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 +# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set +# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set +CONFIG_ESP_MODEM_C_API_STR_MAX=128 +# CONFIG_ESP_MODEM_URC_HANDLER is not set +# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set +# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set +# end of esp-modem + +# +# OpenThread RCP Update +# +# CONFIG_AUTO_UPDATE_RCP is not set +# CONFIG_CREATE_OTA_IMAGE_WITH_RCP_FW is not set +# end of OpenThread RCP Update + +# +# ESP Secure Cert Manager +# +# CONFIG_ESP_SECURE_CERT_SUPPORT_LEGACY_FORMATS is not set +# end of ESP Secure Cert Manager + +# +# jsmn +# +# CONFIG_JSMN_PARENT_LINKS is not set +# CONFIG_JSMN_STRICT is not set +# CONFIG_JSMN_STATIC is not set +# end of jsmn + +# +# libsodium +# +# end of libsodium + +# +# mDNS +# +CONFIG_MDNS_MAX_INTERFACES=3 +CONFIG_MDNS_MAX_SERVICES=10 +CONFIG_MDNS_TASK_PRIORITY=1 +CONFIG_MDNS_ACTION_QUEUE_LEN=16 +CONFIG_MDNS_TASK_STACK_SIZE=4096 +# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_MDNS_TASK_AFFINITY_CPU0=y +# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set +CONFIG_MDNS_TASK_AFFINITY=0x0 + +# +# MDNS Memory Configuration +# +CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y +CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y +# CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set +# end of MDNS Memory Configuration + +CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 +CONFIG_MDNS_TIMER_PERIOD_MS=100 +# CONFIG_MDNS_NETWORKING_SOCKET is not set +# CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set +# CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set +CONFIG_MDNS_ENABLE_CONSOLE_CLI=y +# CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set +CONFIG_MDNS_MULTIPLE_INSTANCE=y + +# +# MDNS Predefined interfaces +# +CONFIG_MDNS_PREDEF_NETIF_STA=y +CONFIG_MDNS_PREDEF_NETIF_AP=y +CONFIG_MDNS_PREDEF_NETIF_ETH=y +# end of MDNS Predefined interfaces +# end of mDNS + +# +# Network Provisioning Manager +# +CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y +CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set +CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y +# CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set +# end of Network Provisioning Manager + +# +# ESP RainMaker Common +# +CONFIG_ESP_RMAKER_LIB_ESP_MQTT=y +# CONFIG_ESP_RMAKER_LIB_AWS_IOT is not set +CONFIG_ESP_RMAKER_MQTT_GLUE_LIB=1 +CONFIG_ESP_RMAKER_MQTT_PORT_443=y +# CONFIG_ESP_RMAKER_MQTT_PORT_8883 is not set +CONFIG_ESP_RMAKER_MQTT_PORT=1 +# CONFIG_ESP_RMAKER_MQTT_PERSISTENT_SESSION is not set +CONFIG_ESP_RMAKER_MQTT_SEND_USERNAME=y +CONFIG_ESP_RMAKER_MQTT_PRODUCT_NAME="RMDev" +CONFIG_ESP_RMAKER_MQTT_PRODUCT_VERSION="1x0" +CONFIG_ESP_RMAKER_MQTT_PRODUCT_SKU="EX00" +CONFIG_ESP_RMAKER_MQTT_USE_CERT_BUNDLE=y +CONFIG_ESP_RMAKER_MAX_MQTT_SUBSCRIPTIONS=10 +CONFIG_ESP_RMAKER_MQTT_KEEP_ALIVE_INTERVAL=120 +CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI=y +CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_STACK=4096 +CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_PRIORITY=5 +CONFIG_ESP_RMAKER_FACTORY_PARTITION_NAME="fctry" +CONFIG_ESP_RMAKER_FACTORY_NAMESPACE="rmaker_creds" +CONFIG_ESP_RMAKER_DEF_TIMEZONE="Asia/Shanghai" +CONFIG_ESP_RMAKER_SNTP_SERVER_NAME="pool.ntp.org" +CONFIG_ESP_RMAKER_MAX_COMMANDS=10 +# end of ESP RainMaker Common + +# +# ESP-NimBLE-CPP configuration +# +CONFIG_NIMBLE_CPP_LOG_LEVEL_NONE=y +# CONFIG_NIMBLE_CPP_LOG_LEVEL_ERROR is not set +# CONFIG_NIMBLE_CPP_LOG_LEVEL_WARNING is not set +# CONFIG_NIMBLE_CPP_LOG_LEVEL_INFO is not set +# CONFIG_NIMBLE_CPP_LOG_LEVEL_DEBUG is not set +CONFIG_NIMBLE_CPP_LOG_LEVEL=0 +# CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR is not set +# CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT is not set +# CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT is not set +# CONFIG_NIMBLE_CPP_ENABLE_ADVERTISEMENT_TYPE_TEXT is not set +# CONFIG_NIMBLE_CPP_ADDR_FMT_EXCLUDE_DELIMITER is not set +# CONFIG_NIMBLE_CPP_ADDR_FMT_UPPERCASE is not set +# CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED is not set +CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH=20 +# CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED is not set +CONFIG_NIMBLE_CPP_FREERTOS_TASK_BLOCK_BIT=31 +# end of ESP-NimBLE-CPP configuration + +# +# LittleFS +# +# CONFIG_LITTLEFS_SDMMC_SUPPORT is not set +CONFIG_LITTLEFS_MAX_PARTITIONS=3 +CONFIG_LITTLEFS_PAGE_SIZE=256 +CONFIG_LITTLEFS_OBJ_NAME_LEN=64 +CONFIG_LITTLEFS_READ_SIZE=128 +CONFIG_LITTLEFS_WRITE_SIZE=128 +CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 +CONFIG_LITTLEFS_CACHE_SIZE=512 +CONFIG_LITTLEFS_BLOCK_CYCLES=512 +CONFIG_LITTLEFS_USE_MTIME=y +# CONFIG_LITTLEFS_USE_ONLY_HASH is not set +# CONFIG_LITTLEFS_HUMAN_READABLE is not set +CONFIG_LITTLEFS_MTIME_USE_SECONDS=y +# CONFIG_LITTLEFS_MTIME_USE_NONCE is not set +# CONFIG_LITTLEFS_SPIFFS_COMPAT is not set +# CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set +# CONFIG_LITTLEFS_FCNTL_GET_PATH is not set +# CONFIG_LITTLEFS_MULTIVERSION is not set +# CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set +CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y +# CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set +CONFIG_LITTLEFS_ASSERTS=y +# CONFIG_LITTLEFS_MMAP_PARTITION is not set +# end of LittleFS # end of Component config # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set @@ -1911,6 +2307,7 @@ CONFIG_LOG_BOOTLOADER_LEVEL=3 CONFIG_FLASHMODE_DIO=y # CONFIG_FLASHMODE_DOUT is not set CONFIG_MONITOR_BAUD=115200 +# CONFIG_ESP_RMAKER_LOCAL_CTRL_ENABLE is not set CONFIG_OPTIMIZATION_LEVEL_DEBUG=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y @@ -1929,6 +2326,7 @@ CONFIG_STACK_CHECK_NONE=y # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set CONFIG_ESP32_APPTRACE_DEST_NONE=y CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +# CONFIG_NIMBLE_ENABLED is not set CONFIG_ADC2_DISABLE_DAC=y # CONFIG_MCPWM_ISR_IN_IRAM is not set # CONFIG_EVENT_LOOP_PROFILING is not set @@ -2100,4 +2498,18 @@ CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=3000 +CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_MB_QUEUE_LENGTH=20 +CONFIG_MB_SERIAL_TASK_STACK_SIZE=4096 +CONFIG_MB_SERIAL_BUF_SIZE=256 +CONFIG_MB_SERIAL_TASK_PRIO=10 +CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_MB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_MB_CONTROLLER_STACK_SIZE=4096 +CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 +# CONFIG_MB_TIMER_PORT_ENABLED is not set +# CONFIG_NIMBLE_ENABLED is not set # End of deprecated options diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index 483bc0cf..00000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# This file was automatically generated for projects -# without default 'CMakeLists.txt' file. - -FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*) - -idf_component_register(SRCS ${app_sources}) From 2c77c17519a612ce4f10c30f323d492eed3f0362 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 25 Jun 2025 20:20:08 -0500 Subject: [PATCH 252/451] Revert "Changes from @h2zero" This reverts commit ecc4d225ebd9f764005461badf018643aa1ff964. --- .gitignore | 1 - .gitmodules | 6 - .vscode/settings.json | 2 +- CMakeLists.txt | 4 + dependencies.lock | 413 +--------- include/BLE_Fitness_Machine_Service.h | 4 +- main/CMakeLists.txt | 19 - main/idf_component.yml | 7 - sdkconfig | 717 +----------------- sdkconfig.defaults | 10 +- sdkconfig.old | 420 +--------- {main => src}/BLE_Client.cpp | 0 {main => src}/BLE_Common.cpp | 0 {main => src}/BLE_Custom_Characteristic.cpp | 0 {main => src}/BLE_Cycling_Power_Service.cpp | 0 {main => src}/BLE_Cycling_Speed_Cadence.cpp | 0 .../BLE_Device_Information_Service.cpp | 0 {main => src}/BLE_Firmware_Update.cpp | 0 {main => src}/BLE_Fitness_Machine_Service.cpp | 0 {main => src}/BLE_Heart_Service.cpp | 0 {main => src}/BLE_SB20_Service.cpp | 0 {main => src}/BLE_Server.cpp | 0 {main => src}/BLE_Setup.cpp | 0 {main => src}/BLE_Wattbike_Service.cpp | 0 src/CMakeLists.txt | 6 + {main => src}/DirConManager.cpp | 0 {main => src}/DirConMessage.cpp | 0 {main => src}/ERG_Mode.cpp | 0 {main => src}/HTTP_Server_Basic.cpp | 0 {main => src}/Main.cpp | 0 {main => src}/PowerTable_Helpers.cpp | 0 {main => src}/Power_Table.cpp | 0 {main => src}/SS2KLog.cpp | 0 {main => src}/SensorCollector.cpp | 0 {main => src}/SmartSpin_parameters.cpp | 0 {main => src}/UdpAppender.cpp | 0 {main => src}/WebsocketAppender.cpp | 0 {main => src}/gitTracking.md | 0 38 files changed, 44 insertions(+), 1565 deletions(-) delete mode 100644 .gitmodules delete mode 100644 main/CMakeLists.txt delete mode 100644 main/idf_component.yml rename {main => src}/BLE_Client.cpp (100%) rename {main => src}/BLE_Common.cpp (100%) rename {main => src}/BLE_Custom_Characteristic.cpp (100%) rename {main => src}/BLE_Cycling_Power_Service.cpp (100%) rename {main => src}/BLE_Cycling_Speed_Cadence.cpp (100%) rename {main => src}/BLE_Device_Information_Service.cpp (100%) rename {main => src}/BLE_Firmware_Update.cpp (100%) rename {main => src}/BLE_Fitness_Machine_Service.cpp (100%) rename {main => src}/BLE_Heart_Service.cpp (100%) rename {main => src}/BLE_SB20_Service.cpp (100%) rename {main => src}/BLE_Server.cpp (100%) rename {main => src}/BLE_Setup.cpp (100%) rename {main => src}/BLE_Wattbike_Service.cpp (100%) create mode 100644 src/CMakeLists.txt rename {main => src}/DirConManager.cpp (100%) rename {main => src}/DirConMessage.cpp (100%) rename {main => src}/ERG_Mode.cpp (100%) rename {main => src}/HTTP_Server_Basic.cpp (100%) rename {main => src}/Main.cpp (100%) rename {main => src}/PowerTable_Helpers.cpp (100%) rename {main => src}/Power_Table.cpp (100%) rename {main => src}/SS2KLog.cpp (100%) rename {main => src}/SensorCollector.cpp (100%) rename {main => src}/SmartSpin_parameters.cpp (100%) rename {main => src}/UdpAppender.cpp (100%) rename {main => src}/WebsocketAppender.cpp (100%) rename {main => src}/gitTracking.md (100%) diff --git a/.gitignore b/.gitignore index a6674331..7795ffea 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,3 @@ build/CMakeCache.txt C/Users/ /build /managed_components -dependencies.lock \ No newline at end of file diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index d2d2b5fa..00000000 --- a/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "lib/TMCStepper"] - path = lib/TMCStepper - url = https://github.com/teemuatlut/TMCStepper.git -[submodule "lib/ArduinoWebsockets"] - path = lib/ArduinoWebsockets - url = https://github.com/gilmaimon/ArduinoWebsockets.git diff --git a/.vscode/settings.json b/.vscode/settings.json index baf137d4..2888d84a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -119,6 +119,6 @@ "VERSIONFILE", "WEBSERVER" ], - "idf.pythonInstallPath": "C:\\Users\\anthony\\.espressif\\tools\\idf-python\\3.11.2\\python.exe", + "idf.pythonInstallPath": "/opt/homebrew/bin/python3", "idf.flashType": "UART", } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index fbd39142..9a5f975e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,7 @@ cmake_minimum_required(VERSION 3.16.0) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(SmartSpin2k) +include_directories( + ${PROJECT_SOURCE_DIR}/include + ${PROJECT_SOURCE_DIR}/src +) \ No newline at end of file diff --git a/dependencies.lock b/dependencies.lock index 4d7dcec5..937a8ec5 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -1,191 +1,26 @@ dependencies: - bblanchon/arduinojson: - component_hash: 914b05e5ba8d6b99d51307d4f5bf6a5ff610c673c200c3134edcc0a7a99d04b0 - dependencies: [] - source: - registry_url: https://components.espressif.com/ - type: service - version: 7.3.1 chmorgan/esp-libhelix-mp3: component_hash: cbb76089dc2c5749f7b470e2e70aedc44c9da519e04eb9a67d4c7ec275229e53 dependencies: - name: idf - require: private - version: '>=4.1.0' - source: - registry_url: https://components.espressif.com - type: service - version: 1.0.3 - doudar/FastAccelStepper: - component_hash: 3e80398cf918e905938828befcbabc69e1a29e7867e9a5d226004349ae70fae0 - dependencies: [] - source: - git: https://github.com/doudar/FastAccelStepper - path: . - type: git - version: 02998fdee1bf6c5c0319f3a5792f56d2d830901e - espressif/arduino-esp32: - component_hash: 24d09ebaba2990281cb54ac3e0ba8fcdd8511c16b24114a4040476ece2949643 - dependencies: - - name: chmorgan/esp-libhelix-mp3 - registry_url: https://components.espressif.com - require: private - version: 1.0.3 - - name: espressif/cbor - registry_url: https://components.espressif.com - require: private - rules: - - if: target not in [esp32c2, esp32p4] - version: 0.6.0~1 - - name: espressif/esp-dsp - registry_url: https://components.espressif.com - require: private - rules: - - if: target != esp32c2 - version: ^1.3.4 - - name: espressif/esp-modbus - registry_url: https://components.espressif.com - require: private - version: ^1.0.15 - - name: espressif/esp-sr - registry_url: https://components.espressif.com - require: private - rules: - - if: target in [esp32s3] - version: ^1.4.2 - - name: espressif/esp-zboss-lib - registry_url: https://components.espressif.com - require: private - rules: - - if: target not in [esp32c2, esp32p4] - version: ==1.6.3 - - name: espressif/esp-zigbee-lib - registry_url: https://components.espressif.com - require: private - rules: - - if: target not in [esp32c2, esp32p4] - version: ==1.6.3 - - name: espressif/esp_diag_data_store registry_url: https://components.espressif.com require: private - rules: - - if: target not in [esp32c2, esp32p4] - version: 1.0.2 - - name: espressif/esp_diagnostics - registry_url: https://components.espressif.com - require: private - rules: - - if: target not in [esp32c2, esp32p4] - version: 1.2.1 - - name: espressif/esp_hosted - registry_url: https://components.espressif.com - require: private - rules: - - if: target == esp32p4 - version: ^0.0.25 - - name: espressif/esp_insights - registry_url: https://components.espressif.com - require: private - rules: - - if: target not in [esp32c2, esp32p4] - version: 1.2.2 - - name: espressif/esp_modem - registry_url: https://components.espressif.com - require: private - version: ^1.1.0 - - name: espressif/esp_rainmaker - registry_url: https://components.espressif.com - require: private - rules: - - if: target not in [esp32c2, esp32p4] - version: 1.5.2 - - name: espressif/esp_wifi_remote - registry_url: https://components.espressif.com - require: private - rules: - - if: target == esp32p4 - version: ^0.4.1 - - name: espressif/libsodium - registry_url: https://components.espressif.com - require: private - version: ^1.0.20~1 - - name: espressif/mdns - registry_url: https://components.espressif.com - require: private - version: ^1.2.3 - - name: espressif/network_provisioning - registry_url: https://components.espressif.com - require: private - version: 1.0.2 - - name: espressif/qrcode - registry_url: https://components.espressif.com - require: private - rules: - - if: target not in [esp32c2, esp32p4] - version: 0.1.0~2 - - name: espressif/rmaker_common - registry_url: https://components.espressif.com - require: private - rules: - - if: target not in [esp32c2, esp32p4] - version: 1.4.6 - - name: idf - require: private - version: '>=5.3,<5.5' - - name: joltwallet/littlefs - registry_url: https://components.espressif.com - require: private - version: ^1.10.2 + version: '>=4.1.0' source: registry_url: https://components.espressif.com/ type: service - targets: - - esp32 - - esp32s2 - - esp32s3 - - esp32c2 - - esp32c3 - - esp32c6 - - esp32h2 - - esp32p4 - version: 3.2.0 + version: 1.0.3 espressif/cbor: component_hash: 440f4ee4504841cc9b4f3a8ef755776a612ac9dace355514c68b999868f990ff dependencies: - name: idf - require: private - version: '>=4.3' - source: registry_url: https://components.espressif.com - type: service - version: 0.6.0~1 - espressif/esp-dsp: - component_hash: 42dce32d46ac93dc11f60d368e29a830e9661c7345d794b8a45c343479cae636 - dependencies: - - name: idf - require: private - version: '>=4.2' - source: - registry_url: https://components.espressif.com - type: service - version: 1.7.0 - espressif/esp-modbus: - component_hash: 5d5e90b9e55721a8a194b301ad8102d4affb647f47b74cd413ff7d1ce2c1169c - dependencies: - - name: idf require: private version: '>=4.3' source: - registry_url: https://components.espressif.com - type: service - version: 1.0.18 - espressif/esp-serial-flasher: - component_hash: dcc42a16712a1a636509cf0bf90e14032d7f2141784b533613b267b6aa318d52 - dependencies: [] - source: - registry_url: https://components.espressif.com + registry_url: https://components.espressif.com/ type: service - version: 0.0.11 + version: 0.6.0~1 espressif/esp-zboss-lib: component_hash: 2a2256a8d20e5ade59a8e084760c84faa87dc9332523afcb6e245a744420839a dependencies: @@ -193,7 +28,7 @@ dependencies: require: private version: '>=5.0' source: - registry_url: https://components.espressif.com + registry_url: https://components.espressif.com/ type: service version: 1.6.3 espressif/esp-zigbee-lib: @@ -203,61 +38,9 @@ dependencies: require: private version: '>=5.0' source: - registry_url: https://components.espressif.com + registry_url: https://components.espressif.com/ type: service version: 1.6.3 - espressif/esp_diag_data_store: - component_hash: c1e5cf62f545d2b136db299f4df1b228b9840be5bc3410c9ad2d2a882b5c0d64 - dependencies: - - name: idf - require: private - version: '>=4.1' - source: - registry_url: https://components.espressif.com - type: service - version: 1.0.2 - espressif/esp_diagnostics: - component_hash: 5ea8e8da8217ed9ed778db3973139e726e17cd27ef5cf6429c787d19226c79f3 - dependencies: - - name: idf - require: private - version: '>=4.1' - - name: espressif/rmaker_common - registry_url: https://components.espressif.com - require: private - version: ~1.4.0 - source: - registry_url: https://components.espressif.com - type: service - version: 1.2.1 - espressif/esp_insights: - component_hash: 4015c524b9955528f941268cf080174076b195800de910d061efc46113bc2e0c - dependencies: - - name: idf - require: private - version: '>=4.1' - - name: espressif/cbor - registry_url: https://components.espressif.com - require: private - rules: - - if: idf_version >=5.0 - version: ~0.6 - - name: espressif/esp_diag_data_store - registry_url: https://components.espressif.com - require: private - version: 1.0.2 - - name: espressif/esp_diagnostics - registry_url: https://components.espressif.com - require: private - version: 1.2.1 - - name: espressif/rmaker_common - registry_url: https://components.espressif.com - require: private - version: ~1.4.0 - source: - registry_url: https://components.espressif.com - type: service - version: 1.2.2 espressif/esp_modem: component_hash: b541c3f5765d3ba062c0d004b9ca6da6d0af908293421c2dbe046c537fb2a011 dependencies: @@ -265,131 +48,9 @@ dependencies: require: private version: '>=4.1' source: - registry_url: https://components.espressif.com + registry_url: https://components.espressif.com/ type: service version: 1.4.0 - espressif/esp_rainmaker: - component_hash: f6fe458fc7a0102ee2879f0247da4b41419e6c07de12031f66e5e9454d25baaa - dependencies: - - name: espressif/esp_rcp_update - registry_url: https://components.espressif.com - require: private - rules: - - if: idf_version >= 5.1 - version: ~1.2.0 - - name: espressif/esp_schedule - registry_url: https://components.espressif.com - require: private - version: ~1.2.0 - - name: espressif/esp_secure_cert_mgr - registry_url: https://components.espressif.com - require: private - rules: - - if: idf_version >=4.3 - version: ^2.2.1 - - name: espressif/json_generator - registry_url: https://components.espressif.com - require: private - version: ~1.1.1 - - name: espressif/json_parser - registry_url: https://components.espressif.com - require: private - version: ~1.0.3 - - name: espressif/mdns - registry_url: https://components.espressif.com - require: private - rules: - - if: idf_version >=5.0 - version: ^1.2.0 - - name: espressif/network_provisioning - registry_url: https://components.espressif.com - require: private - rules: - - if: idf_version >= 5.1 - version: ~1.0.0 - - name: espressif/rmaker_common - registry_url: https://components.espressif.com - require: private - version: ~1.4.6 - source: - registry_url: https://components.espressif.com - type: service - version: 1.5.2 - espressif/esp_rcp_update: - component_hash: c10afbd54a17f27eed880e61262b161656e6d36ad63376c307f9273e99d0abcd - dependencies: - - name: espressif/esp-serial-flasher - registry_url: https://components.espressif.com - require: private - version: ~0.0.0 - - name: idf - require: private - version: '>=5.0' - source: - registry_url: https://components.espressif.com - type: service - version: 1.2.0 - espressif/esp_schedule: - component_hash: e202a9c688f7f1ab601efb91d682e4bcfaebc508dcceee1a1e0a0d2d1ca75a26 - dependencies: - - name: espressif/rmaker_common - registry_url: https://components.espressif.com - require: private - version: ~1.4.2 - source: - registry_url: https://components.espressif.com - type: service - version: 1.2.0 - espressif/esp_secure_cert_mgr: - component_hash: 5d9175b416f751ba6a7cb35bdf092f0af85658ce06c4a592c7c541d8017ebeb9 - dependencies: - - name: idf - require: private - version: '>=4.3' - source: - registry_url: https://components.espressif.com - type: service - version: 2.5.0 - espressif/jsmn: - component_hash: d80350c41bbaa827c98a25b6072df00884e72f54885996fab4a4f0aebce6b6c3 - dependencies: - - name: idf - require: private - version: '>=4.3' - source: - registry_url: https://components.espressif.com - type: service - version: 1.1.0 - espressif/json_generator: - component_hash: 45033e1c199b13f1c8c1b544fb7d4e2df6a8e3071ebdcb1b22582b61a7974ff2 - dependencies: [] - source: - registry_url: https://components.espressif.com - type: service - version: 1.1.2 - espressif/json_parser: - component_hash: d74b81729ad06ec11ff5eb5b1b0d7df1d00e6027fc11471f4b139c70dcf1b1e4 - dependencies: - - name: espressif/jsmn - registry_url: https://components.espressif.com - require: private - rules: - - if: idf_version >=5.0 - version: ~1.1 - source: - registry_url: https://components.espressif.com - type: service - version: 1.0.3 - espressif/libsodium: - component_hash: 25b968723c584a2742ca36cebe5a7ef049c6767e059f7b1e1eec69946019025d - dependencies: - - name: idf - require: private - version: '>=4.2' - source: - registry_url: https://components.espressif.com - type: service - version: 1.0.20~2 espressif/mdns: component_hash: 3ec0af5f6bce310512e90f482388d21cc7c0e99668172d2f895356165fc6f7c5 dependencies: @@ -397,57 +58,20 @@ dependencies: require: private version: '>=5.0' source: - registry_url: https://components.espressif.com + registry_url: https://components.espressif.com/ type: service version: 1.8.2 espressif/network_provisioning: component_hash: ef2e10182fd1861e68b821491916327c25416ca7ae70e5a6e43313dbc71fe993 dependencies: - name: idf - require: private - version: '>=5.1' - source: - registry_url: https://components.espressif.com - type: service - version: 1.0.2 - espressif/qrcode: - component_hash: 3b493771bc5d6ad30cbf87c25bf784aada8a08c941504355b55d6b75518ed7bc - dependencies: [] - source: - registry_url: https://components.espressif.com - type: service - version: 0.1.0~2 - espressif/rmaker_common: - component_hash: a3a1df881278d0351fc850b77792fe8a196ddd6dcacbea203d606329cc6a0239 - dependencies: [] - source: - registry_url: https://components.espressif.com - type: service - version: 1.4.6 - h2zero/esp-nimble-cpp: - component_hash: 6fe25905e163f3e6737f3a1f2817618887d86dd88fa724fdad18ac718103984a - dependencies: - - name: espressif/esp_hosted - registry_url: https://components.espressif.com - require: private - rules: - - if: target in [esp32p4] - version: '*' - - name: espressif/esp_wifi_remote registry_url: https://components.espressif.com require: private - rules: - - if: target in [esp32p4] - version: '>=0.5.3' - - name: idf - require: private - rules: - - if: target in [esp32p4] - version: '>=5.3.0' + version: '>=5.1' source: registry_url: https://components.espressif.com/ type: service - version: 2.3.1 + version: 1.0.2 idf: source: type: idf @@ -459,14 +83,19 @@ dependencies: require: private version: '>=5.0' source: - registry_url: https://components.espressif.com + registry_url: https://components.espressif.com/ type: service version: 1.20.0 direct_dependencies: -- bblanchon/arduinojson -- doudar/FastAccelStepper -- espressif/arduino-esp32 -- h2zero/esp-nimble-cpp -manifest_hash: a35e2e02fdd7199ee00e7ac11e63a345f759ba453e99f0153a49769bd73aa883 +- chmorgan/esp-libhelix-mp3 +- espressif/cbor +- espressif/esp-zboss-lib +- espressif/esp-zigbee-lib +- espressif/esp_modem +- espressif/mdns +- espressif/network_provisioning +- idf +- joltwallet/littlefs +manifest_hash: e9919b5b28bb7bb038864af176d8e81936400eff14ef44258dd5186bdc427ec2 target: esp32 version: 2.0.0 diff --git a/include/BLE_Fitness_Machine_Service.h b/include/BLE_Fitness_Machine_Service.h index adf2184a..eefbdbe0 100644 --- a/include/BLE_Fitness_Machine_Service.h +++ b/include/BLE_Fitness_Machine_Service.h @@ -21,9 +21,9 @@ class BLE_Fitness_Machine_Service { private: BLEService *pFitnessMachineService; BLECharacteristic *fitnessMachineFeature; - BLECharacteristic *fitnessMachineControlPoint; - BLECharacteristic *fitnessMachineStatusCharacteristic; BLECharacteristic *fitnessMachineIndoorBikeData; + BLECharacteristic *fitnessMachineStatusCharacteristic; + BLECharacteristic *fitnessMachineControlPoint; BLECharacteristic *fitnessMachineResistanceLevelRange; BLECharacteristic *fitnessMachinePowerRange; BLECharacteristic *fitnessMachineInclinationRange; diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt deleted file mode 100644 index c122670e..00000000 --- a/main/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# This file was automatically generated for projects -# without default 'CMakeLists.txt' file. - -FILE(GLOB_RECURSE app_sources *.cpp) -FILE(GLOB_RECURSE ss2k_sources ${CMAKE_SOURCE_DIR}/lib/SS2K/src/sensors) -FILE(GLOB_RECURSE aws_sources ${CMAKE_SOURCE_DIR}/lib/ArduinoWebsockets/src) -FILE(GLOB_RECURSE tmcs_sources ${CMAKE_SOURCE_DIR}/lib/TMCStepper/src/source) -set(srcs ${app_sources} ${ss2k_sources} ${aws_sources} ${tmcs_sources}) - -set(include_dirs - ${CMAKE_SOURCE_DIR}/include - ${CMAKE_SOURCE_DIR}/lib/SS2K/include - ${CMAKE_SOURCE_DIR}/lib/SS2K/include/sensors - ${CMAKE_SOURCE_DIR}/lib/ArduinoWebsockets - ${CMAKE_SOURCE_DIR}/lib/TMCStepper/src - ${CMAKE_SOURCE_DIR}/lib/TMCStepper/src/source -) - -idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "${include_dirs}") diff --git a/main/idf_component.yml b/main/idf_component.yml deleted file mode 100644 index d614a01a..00000000 --- a/main/idf_component.yml +++ /dev/null @@ -1,7 +0,0 @@ -## IDF Component Manager Manifest File -dependencies: - espressif/arduino-esp32: ^3.2.0 - h2zero/esp-nimble-cpp: ^2.3.1 - bblanchon/arduinojson: 7.3.1 - doudar/FastAccelStepper: - git: https://github.com/doudar/FastAccelStepper diff --git a/sdkconfig b/sdkconfig index 4be13f57..1287da4d 100644 --- a/sdkconfig +++ b/sdkconfig @@ -406,124 +406,6 @@ CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table -# -# Arduino Configuration -# -CONFIG_ARDUINO_VARIANT="esp32" -CONFIG_ENABLE_ARDUINO_DEPENDS=y -CONFIG_AUTOSTART_ARDUINO=y -# CONFIG_ARDUINO_RUN_CORE0 is not set -CONFIG_ARDUINO_RUN_CORE1=y -# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_RUNNING_CORE=1 -CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 -# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set -CONFIG_ARDUINO_EVENT_RUN_CORE1=y -# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 -# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set -# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set -CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y -CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 -CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=2048 -CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 -CONFIG_ARDUINO_UDP_RUN_CORE0=y -# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set -# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_UDP_RUNNING_CORE=0 -CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 -# CONFIG_ARDUINO_ISR_IRAM is not set -# CONFIG_DISABLE_HAL_LOCKS is not set - -# -# Debug Log Configuration -# -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE is not set -CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR=y -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=1 -# CONFIG_ARDUHAL_LOG_COLORS is not set -# CONFIG_ARDUHAL_ESP_LOG is not set -# end of Debug Log Configuration - -CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT=y -# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS is not set -CONFIG_ARDUHAL_PARTITION_SCHEME="default" -# CONFIG_AUTOCONNECT_WIFI is not set -# CONFIG_ARDUINO_SELECTIVE_COMPILATION is not set -# end of Arduino Configuration - -# -# ESP RainMaker Config -# -CONFIG_ESP_RMAKER_NO_CLAIM=y -# CONFIG_ESP_RMAKER_ASSISTED_CLAIM is not set -# CONFIG_ESP_RMAKER_USE_ESP_SECURE_CERT_MGR is not set -CONFIG_ESP_RMAKER_USE_NVS=y -CONFIG_ESP_RMAKER_CLAIM_TYPE=0 -# CONFIG_ESP_RMAKER_READ_MQTT_HOST_FROM_CONFIG is not set -# CONFIG_ESP_RMAKER_READ_NODE_ID_FROM_CERT_CN is not set -CONFIG_ESP_RMAKER_MQTT_USE_BASIC_INGEST_TOPICS=y -CONFIG_ESP_RMAKER_MQTT_ENABLE_BUDGETING=y -CONFIG_ESP_RMAKER_MQTT_DEFAULT_BUDGET=100 -CONFIG_ESP_RMAKER_MQTT_MAX_BUDGET=1024 -CONFIG_ESP_RMAKER_MQTT_BUDGET_REVIVE_PERIOD=5 -CONFIG_ESP_RMAKER_MQTT_BUDGET_REVIVE_COUNT=1 -CONFIG_ESP_RMAKER_MAX_PARAM_DATA_SIZE=1024 -# CONFIG_ESP_RMAKER_DISABLE_USER_MAPPING_PROV is not set -# CONFIG_ESP_RMAKER_USER_ID_CHECK is not set -# CONFIG_RMAKER_NAME_PARAM_CB is not set -# CONFIG_ESP_RMAKER_LOCAL_CTRL_FEATURE_ENABLE is not set -# CONFIG_ESP_RMAKER_LOCAL_CTRL_AUTO_ENABLE is not set -CONFIG_ESP_RMAKER_CONSOLE_UART_NUM_0=y -# CONFIG_ESP_RMAKER_CONSOLE_UART_NUM_1 is not set -CONFIG_ESP_RMAKER_CONSOLE_UART_NUM=0 -CONFIG_ESP_RMAKER_USE_CERT_BUNDLE=y - -# -# ESP RainMaker OTA Config -# -CONFIG_ESP_RMAKER_OTA_AUTOFETCH=y -CONFIG_ESP_RMAKER_OTA_AUTOFETCH_PERIOD=0 -# CONFIG_ESP_RMAKER_SKIP_COMMON_NAME_CHECK is not set -# CONFIG_ESP_RMAKER_SKIP_VERSION_CHECK is not set -# CONFIG_ESP_RMAKER_SKIP_SECURE_VERSION_CHECK is not set -# CONFIG_ESP_RMAKER_SKIP_PROJECT_NAME_CHECK is not set -CONFIG_ESP_RMAKER_OTA_HTTP_RX_BUFFER_SIZE=1024 -CONFIG_ESP_RMAKER_OTA_ROLLBACK_WAIT_PERIOD=90 -# CONFIG_ESP_RMAKER_OTA_DISABLE_AUTO_REBOOT is not set -CONFIG_ESP_RMAKER_OTA_TIME_SUPPORT=y -# end of ESP RainMaker OTA Config - -# -# ESP RainMaker Scheduling -# -CONFIG_ESP_RMAKER_SCHEDULING_MAX_SCHEDULES=10 -# end of ESP RainMaker Scheduling - -# -# ESP RainMaker Scenes -# -CONFIG_ESP_RMAKER_SCENES_MAX_SCENES=10 -# CONFIG_ESP_RMAKER_SCENES_DEACTIVATE_SUPPORT is not set -# end of ESP RainMaker Scenes - -# -# ESP RainMaker Command-Response -# -CONFIG_ESP_RMAKER_CMD_RESP_ENABLE=y -# CONFIG_ESP_RMAKER_CMD_RESP_TEST_ENABLE is not set -# end of ESP RainMaker Command-Response - -CONFIG_ESP_RMAKER_USING_NETWORK_PROV=y -# end of ESP RainMaker Config - # # Compiler options # @@ -578,234 +460,10 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # # Bluetooth # -CONFIG_BT_ENABLED=y -# CONFIG_BT_BLUEDROID_ENABLED is not set -CONFIG_BT_NIMBLE_ENABLED=y -# CONFIG_BT_CONTROLLER_ONLY is not set -CONFIG_BT_CONTROLLER_ENABLED=y -# CONFIG_BT_CONTROLLER_DISABLED is not set - -# -# NimBLE Options -# -CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y -# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set -CONFIG_BT_NIMBLE_LOG_LEVEL_NONE=y -# CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR is not set -# CONFIG_BT_NIMBLE_LOG_LEVEL_WARNING is not set -# CONFIG_BT_NIMBLE_LOG_LEVEL_INFO is not set -# CONFIG_BT_NIMBLE_LOG_LEVEL_DEBUG is not set -CONFIG_BT_NIMBLE_LOG_LEVEL=4 -CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 -CONFIG_BT_NIMBLE_MAX_BONDS=3 -CONFIG_BT_NIMBLE_MAX_CCCDS=8 -CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM=0 -CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y -# CONFIG_BT_NIMBLE_PINNED_TO_CORE_1 is not set -CONFIG_BT_NIMBLE_PINNED_TO_CORE=0 -CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=4096 -CONFIG_BT_NIMBLE_ROLE_CENTRAL=y -CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y -CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y -CONFIG_BT_NIMBLE_ROLE_OBSERVER=y -# CONFIG_BT_NIMBLE_NVS_PERSIST is not set -# CONFIG_BT_NIMBLE_SMP_ID_RESET is not set -CONFIG_BT_NIMBLE_SECURITY_ENABLE=y -CONFIG_BT_NIMBLE_SM_LEGACY=y -CONFIG_BT_NIMBLE_SM_SC=y -# CONFIG_BT_NIMBLE_SM_SC_DEBUG_KEYS is not set -CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_ENCRYPTION=y -CONFIG_BT_NIMBLE_SM_LVL=0 -CONFIG_BT_NIMBLE_SM_SC_ONLY=0 -# CONFIG_BT_NIMBLE_DEBUG is not set -# CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set -CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" -CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 -CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=256 -CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE=0 - -# -# Memory Settings -# -CONFIG_BT_NIMBLE_MSYS_1_BLOCK_COUNT=12 -CONFIG_BT_NIMBLE_MSYS_1_BLOCK_SIZE=256 -CONFIG_BT_NIMBLE_MSYS_2_BLOCK_COUNT=24 -CONFIG_BT_NIMBLE_MSYS_2_BLOCK_SIZE=320 -CONFIG_BT_NIMBLE_TRANSPORT_ACL_FROM_LL_COUNT=24 -CONFIG_BT_NIMBLE_TRANSPORT_ACL_SIZE=255 -CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70 -CONFIG_BT_NIMBLE_TRANSPORT_EVT_COUNT=30 -CONFIG_BT_NIMBLE_TRANSPORT_EVT_DISCARD_COUNT=8 -CONFIG_BT_NIMBLE_L2CAP_COC_SDU_BUFF_COUNT=1 -# end of Memory Settings - -CONFIG_BT_NIMBLE_GATT_MAX_PROCS=4 -CONFIG_BT_NIMBLE_HS_FLOW_CTRL=y -CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 -CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 -CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y -CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 -# CONFIG_BT_NIMBLE_MESH is not set -CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y -CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 -# CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set -# CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set -CONFIG_BT_NIMBLE_WHITELIST_SIZE=12 -# CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set -# CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set -CONFIG_BT_NIMBLE_USE_ESP_TIMER=y -CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y -# CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set - -# -# GAP Service -# - -# -# GAP Appearance write permissions -# -# CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set -# end of GAP Appearance write permissions - -CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM=0 -CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ENC=0 -CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHN=0 -CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHR=0 -CONFIG_BT_NIMBLE_SVC_GAP_CAR_CHAR_NOT_SUPP=y -# CONFIG_BT_NIMBLE_SVC_GAP_CAR_NOT_SUPP is not set -# CONFIG_BT_NIMBLE_SVC_GAP_CAR_SUPP is not set -CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 - -# -# GAP device name write permissions -# -# CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set -# end of GAP device name write permissions - -CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM=0 -CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_ENC=0 -CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHEN=0 -CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHOR=0 -CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 -CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 -CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 -CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 -# CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL is not set -# end of GAP Service - -# -# BLE Services -# -# CONFIG_BT_NIMBLE_HID_SERVICE is not set -# CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY is not set - -# -# Device Information Service -# -# CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME is not set -# CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER is not set -# CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION is not set -# CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION is not set -# CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION is not set -# CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID is not set -# CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID is not set -# CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED is not set -# end of Device Information Service -# end of BLE Services - -# CONFIG_BT_NIMBLE_VS_SUPPORT is not set -# CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set -# CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set -# CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set -# CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT is not set - -# -# Host-controller Transport -# -CONFIG_UART_HW_FLOWCTRL_DISABLE=y -# CONFIG_UART_HW_FLOWCTRL_CTS_RTS is not set -CONFIG_BT_NIMBLE_HCI_UART_FLOW_CTRL=0 -CONFIG_BT_NIMBLE_HCI_UART_RTS_PIN=19 -CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 -# end of Host-controller Transport - -CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 -# CONFIG_BT_NIMBLE_SUBRATE is not set -# end of NimBLE Options - -# -# Controller Options -# -CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y -# CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set -# CONFIG_BTDM_CTRL_MODE_BTDM is not set -CONFIG_BTDM_CTRL_BLE_MAX_CONN=3 -CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 -CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 -CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 -CONFIG_BTDM_CTRL_PCM_FSYNCSHP_EFF=0 -CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=3 -CONFIG_BTDM_CTRL_BR_EDR_MIN_ENC_KEY_SZ_DFT_EFF=0 -CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 -CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 -CONFIG_BTDM_CTRL_PINNED_TO_CORE_0=y -# CONFIG_BTDM_CTRL_PINNED_TO_CORE_1 is not set -CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 -CONFIG_BTDM_CTRL_HCI_MODE_VHCI=y -# CONFIG_BTDM_CTRL_HCI_MODE_UART_H4 is not set - -# -# MODEM SLEEP Options -# -CONFIG_BTDM_CTRL_MODEM_SLEEP=y -CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG=y -# CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_EVED is not set -CONFIG_BTDM_CTRL_LPCLK_SEL_MAIN_XTAL=y -# end of MODEM SLEEP Options - -CONFIG_BTDM_BLE_DEFAULT_SCA_250PPM=y -CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 -CONFIG_BTDM_BLE_SCAN_DUPL=y -CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y -# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA is not set -# CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE is not set -CONFIG_BTDM_SCAN_DUPL_TYPE=0 -CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 -CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 -# CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set -CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y -# CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set -# CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set -CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y -CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 -CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 - -# -# BLE disconnects when Instant Passed (0x28) occurs -# -# CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set -# CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set -# end of BLE disconnects when Instant Passed (0x28) occurs - -CONFIG_BTDM_BLE_CHAN_ASS_EN=y -CONFIG_BTDM_BLE_PING_EN=y -# CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 is not set -CONFIG_BTDM_RESERVE_DRAM=0xdb5c -CONFIG_BTDM_CTRL_HLI=y -# end of Controller Options - -# -# Common Options -# +# CONFIG_BT_ENABLED is not set CONFIG_BT_ALARM_MAX_NUM=50 -# CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set -# end of Common Options - -# CONFIG_BT_HCI_LOG_DEBUG_EN is not set # end of Bluetooth -# CONFIG_BLE_MESH is not set - # # Console Library # @@ -940,8 +598,6 @@ CONFIG_ADC_DISABLE_DAC_OUTPUT=y # Wireless Coexistence # CONFIG_ESP_COEX_ENABLED=y -CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y -# CONFIG_ESP_COEX_POWER_MANAGEMENT is not set # CONFIG_ESP_COEX_GPIO_DEBUG is not set # end of Wireless Coexistence @@ -1361,7 +1017,8 @@ CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y # CONFIG_ESP_PANIC_HANDLER_IRAM is not set # CONFIG_ESP_DEBUG_STUBS_ENABLE is not set CONFIG_ESP_DEBUG_OCDAWARE=y -CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y +# CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y # # Brownout Detector @@ -1682,7 +1339,7 @@ CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -CONFIG_LWIP_SO_RCVBUF=y +# CONFIG_LWIP_SO_RCVBUF is not set # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP_DEFAULT_TTL=64 CONFIG_LWIP_IP4_FRAG=y @@ -2227,295 +1884,9 @@ CONFIG_WL_SECTOR_SIZE=4096 # CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 -# CONFIG_WIFI_PROV_BLE_BONDING is not set -CONFIG_WIFI_PROV_BLE_SEC_CONN=y -# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set -# CONFIG_WIFI_PROV_BLE_NOTIFY is not set -# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set # end of Wi-Fi Provisioning Manager - -# -# DSP Library -# -CONFIG_DSP_OPTIMIZATIONS_SUPPORTED=y -# CONFIG_DSP_ANSI is not set -CONFIG_DSP_OPTIMIZED=y -CONFIG_DSP_OPTIMIZATION=1 -# CONFIG_DSP_MAX_FFT_SIZE_512 is not set -# CONFIG_DSP_MAX_FFT_SIZE_1024 is not set -# CONFIG_DSP_MAX_FFT_SIZE_2048 is not set -CONFIG_DSP_MAX_FFT_SIZE_4096=y -# CONFIG_DSP_MAX_FFT_SIZE_8192 is not set -# CONFIG_DSP_MAX_FFT_SIZE_16384 is not set -# CONFIG_DSP_MAX_FFT_SIZE_32768 is not set -CONFIG_DSP_MAX_FFT_SIZE=4096 -# end of DSP Library - -# -# Modbus configuration -# -CONFIG_FMB_COMM_MODE_TCP_EN=y -CONFIG_FMB_TCP_PORT_DEFAULT=502 -CONFIG_FMB_TCP_PORT_MAX_CONN=5 -CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 -# CONFIG_FMB_TCP_UID_ENABLED is not set -CONFIG_FMB_COMM_MODE_RTU_EN=y -CONFIG_FMB_COMM_MODE_ASCII_EN=y -CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=3000 -CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 -CONFIG_FMB_QUEUE_LENGTH=20 -CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 -CONFIG_FMB_SERIAL_BUF_SIZE=256 -CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 -CONFIG_FMB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS=0 -CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 -CONFIG_FMB_PORT_TASK_PRIO=10 -# CONFIG_FMB_PORT_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_FMB_PORT_TASK_AFFINITY_CPU0=y -# CONFIG_FMB_PORT_TASK_AFFINITY_CPU1 is not set -CONFIG_FMB_PORT_TASK_AFFINITY=0x0 -CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y -CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 -CONFIG_FMB_CONTROLLER_SLAVE_ID_MAX_SIZE=32 -CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 -CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 -CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 -CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 -# CONFIG_FMB_TIMER_PORT_ENABLED is not set -# CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD is not set -# CONFIG_FMB_EXT_TYPE_SUPPORT is not set -# end of Modbus configuration - -# -# ESP serial flasher -# -CONFIG_SERIAL_FLASHER_MD5_ENABLED=y -CONFIG_SERIAL_FLASHER_RESET_HOLD_TIME_MS=100 -CONFIG_SERIAL_FLASHER_BOOT_HOLD_TIME_MS=50 -# end of ESP serial flasher - -# -# Zigbee -# -# CONFIG_ZB_ENABLED is not set -# end of Zigbee - -# -# Diagnostics data store -# -CONFIG_DIAG_DATA_STORE_RTC=y -# CONFIG_DIAG_DATA_STORE_FLASH is not set -# CONFIG_DIAG_DATA_STORE_DBG_PRINTS is not set -CONFIG_DIAG_DATA_STORE_REPORTING_WATERMARK_PERCENT=80 - -# -# RTC Store -# -CONFIG_RTC_STORE_DATA_SIZE=3072 -CONFIG_RTC_STORE_CRITICAL_DATA_SIZE=2048 -# end of RTC Store -# end of Diagnostics data store - -# -# Diagnostics -# -CONFIG_DIAG_LOG_MSG_ARG_FORMAT_TLV=y -# CONFIG_DIAG_LOG_MSG_ARG_FORMAT_STRING is not set -CONFIG_DIAG_LOG_MSG_ARG_MAX_SIZE=64 -CONFIG_DIAG_LOG_DROP_WIFI_LOGS=y -CONFIG_DIAG_ENABLE_METRICS=y -CONFIG_DIAG_METRICS_MAX_COUNT=20 -CONFIG_DIAG_ENABLE_HEAP_METRICS=y -CONFIG_DIAG_ENABLE_WIFI_METRICS=y -CONFIG_DIAG_ENABLE_VARIABLES=y -CONFIG_DIAG_VARIABLES_MAX_COUNT=20 -CONFIG_DIAG_ENABLE_NETWORK_VARIABLES=y -# CONFIG_DIAG_MORE_NETWORK_VARS is not set -# CONFIG_DIAG_USE_EXTERNAL_LOG_WRAP is not set -# end of Diagnostics - -# -# ESP Insights -# -# CONFIG_ESP_INSIGHTS_ENABLED is not set -# CONFIG_ESP_INSIGHTS_TRANSPORT_MQTT is not set -CONFIG_ESP_INSIGHTS_TRANSPORT_HTTPS=y -CONFIG_ESP_INSIGHTS_TRANSPORT_HTTPS_HOST="https://client.insights.espressif.com" -CONFIG_ESP_INSIGHTS_CLOUD_POST_MIN_INTERVAL_SEC=60 -CONFIG_ESP_INSIGHTS_CLOUD_POST_MAX_INTERVAL_SEC=240 -CONFIG_ESP_INSIGHTS_META_VERSION_10=y -# end of ESP Insights - -# -# esp-modem -# -CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y -# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set -CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 -# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set -# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set -CONFIG_ESP_MODEM_C_API_STR_MAX=128 -# CONFIG_ESP_MODEM_URC_HANDLER is not set -# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set -# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set -# end of esp-modem - -# -# OpenThread RCP Update -# -# CONFIG_AUTO_UPDATE_RCP is not set -# CONFIG_CREATE_OTA_IMAGE_WITH_RCP_FW is not set -# end of OpenThread RCP Update - -# -# ESP Secure Cert Manager -# -# CONFIG_ESP_SECURE_CERT_SUPPORT_LEGACY_FORMATS is not set -# end of ESP Secure Cert Manager - -# -# jsmn -# -# CONFIG_JSMN_PARENT_LINKS is not set -# CONFIG_JSMN_STRICT is not set -# CONFIG_JSMN_STATIC is not set -# end of jsmn - -# -# libsodium -# -# end of libsodium - -# -# mDNS -# -CONFIG_MDNS_MAX_INTERFACES=3 -CONFIG_MDNS_MAX_SERVICES=10 -CONFIG_MDNS_TASK_PRIORITY=1 -CONFIG_MDNS_ACTION_QUEUE_LEN=16 -CONFIG_MDNS_TASK_STACK_SIZE=4096 -# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_MDNS_TASK_AFFINITY_CPU0=y -# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set -CONFIG_MDNS_TASK_AFFINITY=0x0 - -# -# MDNS Memory Configuration -# -CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y -CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y -# CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set -# end of MDNS Memory Configuration - -CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 -CONFIG_MDNS_TIMER_PERIOD_MS=100 -# CONFIG_MDNS_NETWORKING_SOCKET is not set -# CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set -# CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set -CONFIG_MDNS_ENABLE_CONSOLE_CLI=y -# CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set -CONFIG_MDNS_MULTIPLE_INSTANCE=y - -# -# MDNS Predefined interfaces -# -CONFIG_MDNS_PREDEF_NETIF_STA=y -CONFIG_MDNS_PREDEF_NETIF_AP=y -CONFIG_MDNS_PREDEF_NETIF_ETH=y -# end of MDNS Predefined interfaces -# end of mDNS - -# -# Network Provisioning Manager -# -CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y -CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 -CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 -# CONFIG_NETWORK_PROV_BLE_BONDING is not set -CONFIG_NETWORK_PROV_BLE_SEC_CONN=y -# CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set -# CONFIG_NETWORK_PROV_KEEP_BLE_ON_AFTER_PROV is not set -CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y -# CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set -# end of Network Provisioning Manager - -# -# ESP RainMaker Common -# -CONFIG_ESP_RMAKER_LIB_ESP_MQTT=y -# CONFIG_ESP_RMAKER_LIB_AWS_IOT is not set -CONFIG_ESP_RMAKER_MQTT_GLUE_LIB=1 -CONFIG_ESP_RMAKER_MQTT_PORT_443=y -# CONFIG_ESP_RMAKER_MQTT_PORT_8883 is not set -CONFIG_ESP_RMAKER_MQTT_PORT=1 -# CONFIG_ESP_RMAKER_MQTT_PERSISTENT_SESSION is not set -CONFIG_ESP_RMAKER_MQTT_SEND_USERNAME=y -CONFIG_ESP_RMAKER_MQTT_PRODUCT_NAME="RMDev" -CONFIG_ESP_RMAKER_MQTT_PRODUCT_VERSION="1x0" -CONFIG_ESP_RMAKER_MQTT_PRODUCT_SKU="EX00" -CONFIG_ESP_RMAKER_MQTT_USE_CERT_BUNDLE=y -CONFIG_ESP_RMAKER_MAX_MQTT_SUBSCRIPTIONS=10 -CONFIG_ESP_RMAKER_MQTT_KEEP_ALIVE_INTERVAL=120 -CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI=y -CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_STACK=4096 -CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_PRIORITY=5 -CONFIG_ESP_RMAKER_FACTORY_PARTITION_NAME="fctry" -CONFIG_ESP_RMAKER_FACTORY_NAMESPACE="rmaker_creds" -CONFIG_ESP_RMAKER_DEF_TIMEZONE="Asia/Shanghai" -CONFIG_ESP_RMAKER_SNTP_SERVER_NAME="pool.ntp.org" -CONFIG_ESP_RMAKER_MAX_COMMANDS=10 -# end of ESP RainMaker Common - -# -# ESP-NimBLE-CPP configuration -# -CONFIG_NIMBLE_CPP_LOG_LEVEL_NONE=y -# CONFIG_NIMBLE_CPP_LOG_LEVEL_ERROR is not set -# CONFIG_NIMBLE_CPP_LOG_LEVEL_WARNING is not set -# CONFIG_NIMBLE_CPP_LOG_LEVEL_INFO is not set -# CONFIG_NIMBLE_CPP_LOG_LEVEL_DEBUG is not set -CONFIG_NIMBLE_CPP_LOG_LEVEL=0 -# CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR is not set -# CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT is not set -# CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT is not set -# CONFIG_NIMBLE_CPP_ENABLE_ADVERTISEMENT_TYPE_TEXT is not set -# CONFIG_NIMBLE_CPP_ADDR_FMT_EXCLUDE_DELIMITER is not set -# CONFIG_NIMBLE_CPP_ADDR_FMT_UPPERCASE is not set -# CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED is not set -CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH=20 -# CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED is not set -CONFIG_NIMBLE_CPP_FREERTOS_TASK_BLOCK_BIT=31 -# end of ESP-NimBLE-CPP configuration - -# -# LittleFS -# -# CONFIG_LITTLEFS_SDMMC_SUPPORT is not set -CONFIG_LITTLEFS_MAX_PARTITIONS=3 -CONFIG_LITTLEFS_PAGE_SIZE=256 -CONFIG_LITTLEFS_OBJ_NAME_LEN=64 -CONFIG_LITTLEFS_READ_SIZE=128 -CONFIG_LITTLEFS_WRITE_SIZE=128 -CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 -CONFIG_LITTLEFS_CACHE_SIZE=512 -CONFIG_LITTLEFS_BLOCK_CYCLES=512 -CONFIG_LITTLEFS_USE_MTIME=y -# CONFIG_LITTLEFS_USE_ONLY_HASH is not set -# CONFIG_LITTLEFS_HUMAN_READABLE is not set -CONFIG_LITTLEFS_MTIME_USE_SECONDS=y -# CONFIG_LITTLEFS_MTIME_USE_NONCE is not set -# CONFIG_LITTLEFS_SPIFFS_COMPAT is not set -# CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set -# CONFIG_LITTLEFS_FCNTL_GET_PATH is not set -# CONFIG_LITTLEFS_MULTIVERSION is not set -# CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set -CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y -# CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set -CONFIG_LITTLEFS_ASSERTS=y -# CONFIG_LITTLEFS_MMAP_PARTITION is not set -# end of LittleFS # end of Component config # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set @@ -2540,7 +1911,6 @@ CONFIG_LOG_BOOTLOADER_LEVEL=3 CONFIG_FLASHMODE_DIO=y # CONFIG_FLASHMODE_DOUT is not set CONFIG_MONITOR_BAUD=115200 -# CONFIG_ESP_RMAKER_LOCAL_CTRL_ENABLE is not set CONFIG_OPTIMIZATION_LEVEL_DEBUG=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y @@ -2559,72 +1929,7 @@ CONFIG_STACK_CHECK_NONE=y # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set CONFIG_ESP32_APPTRACE_DEST_NONE=y CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y -# CONFIG_BLUEDROID_ENABLED is not set -CONFIG_NIMBLE_ENABLED=y -CONFIG_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y -# CONFIG_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set -CONFIG_NIMBLE_MAX_CONNECTIONS=7 -CONFIG_NIMBLE_MAX_BONDS=3 -CONFIG_NIMBLE_MAX_CCCDS=8 -CONFIG_NIMBLE_L2CAP_COC_MAX_NUM=0 -CONFIG_NIMBLE_PINNED_TO_CORE_0=y -# CONFIG_NIMBLE_PINNED_TO_CORE_1 is not set -CONFIG_NIMBLE_PINNED_TO_CORE=0 -CONFIG_NIMBLE_TASK_STACK_SIZE=4096 -CONFIG_BT_NIMBLE_TASK_STACK_SIZE=4096 -CONFIG_NIMBLE_ROLE_CENTRAL=y -CONFIG_NIMBLE_ROLE_PERIPHERAL=y -CONFIG_NIMBLE_ROLE_BROADCASTER=y -CONFIG_NIMBLE_ROLE_OBSERVER=y -# CONFIG_NIMBLE_NVS_PERSIST is not set -CONFIG_NIMBLE_SM_LEGACY=y -CONFIG_NIMBLE_SM_SC=y -# CONFIG_NIMBLE_SM_SC_DEBUG_KEYS is not set -CONFIG_BT_NIMBLE_SM_SC_LVL=0 -# CONFIG_NIMBLE_DEBUG is not set -CONFIG_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" -CONFIG_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 -CONFIG_NIMBLE_ATT_PREFERRED_MTU=256 -CONFIG_NIMBLE_SVC_GAP_APPEARANCE=0 -CONFIG_BT_NIMBLE_MSYS1_BLOCK_COUNT=12 -CONFIG_BT_NIMBLE_ACL_BUF_COUNT=24 -CONFIG_BT_NIMBLE_ACL_BUF_SIZE=255 -CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70 -CONFIG_BT_NIMBLE_HCI_EVT_HI_BUF_COUNT=30 -CONFIG_BT_NIMBLE_HCI_EVT_LO_BUF_COUNT=8 -CONFIG_NIMBLE_HS_FLOW_CTRL=y -CONFIG_NIMBLE_HS_FLOW_CTRL_ITVL=1000 -CONFIG_NIMBLE_HS_FLOW_CTRL_THRESH=2 -CONFIG_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y -CONFIG_NIMBLE_RPA_TIMEOUT=900 -# CONFIG_NIMBLE_MESH is not set -CONFIG_NIMBLE_CRYPTO_STACK_MBEDTLS=y -CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y -# CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY is not set -# CONFIG_BTDM_CONTROLLER_MODE_BTDM is not set -CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=3 -CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=3 -CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0 -CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 -CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 -CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI=y -# CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4 is not set -CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=y -CONFIG_BLE_SCAN_DUPLICATE=y -CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y -# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA is not set -# CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR is not set -CONFIG_SCAN_DUPLICATE_TYPE=0 -CONFIG_DUPLICATE_SCAN_CACHE_SIZE=100 -# CONFIG_BLE_MESH_SCAN_DUPLICATE_EN is not set -CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y -CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED=y -CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM=100 -CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 CONFIG_ADC2_DISABLE_DAC=y -CONFIG_SW_COEXIST_ENABLE=y -CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y -CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y # CONFIG_MCPWM_ISR_IN_IRAM is not set # CONFIG_EVENT_LOOP_PROFILING is not set CONFIG_POST_EVENTS_FROM_ISR=y @@ -2795,18 +2100,4 @@ CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=3000 -CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 -CONFIG_MB_QUEUE_LENGTH=20 -CONFIG_MB_SERIAL_TASK_STACK_SIZE=4096 -CONFIG_MB_SERIAL_BUF_SIZE=256 -CONFIG_MB_SERIAL_TASK_PRIO=10 -CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT=y -CONFIG_MB_CONTROLLER_SLAVE_ID=0x00112233 -CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 -CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 -CONFIG_MB_CONTROLLER_STACK_SIZE=4096 -CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 -# CONFIG_MB_TIMER_PORT_ENABLED is not set -CONFIG_NIMBLE_ENABLED=y # End of deprecated options diff --git a/sdkconfig.defaults b/sdkconfig.defaults index 75cef2f8..d50929ea 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -1,12 +1,6 @@ -# This file was generated using idf.py save-defconfig. It can be edited manually. -# Espressif IoT Development Framework (ESP-IDF) 5.4.1 Project Minimal Configuration -# -CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_AUTOSTART_ARDUINO=y -CONFIG_ESP_RMAKER_NO_CLAIM=y -CONFIG_BT_NIMBLE_ENABLED=y -CONFIG_BT_NIMBLE_LOG_LEVEL_NONE=y -CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 +# CONFIG_WS2812_LED_ENABLE is not set CONFIG_FREERTOS_HZ=1000 CONFIG_MBEDTLS_PSK_MODES=y CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y \ No newline at end of file diff --git a/sdkconfig.old b/sdkconfig.old index 2ed7e033..07c9dd84 100644 --- a/sdkconfig.old +++ b/sdkconfig.old @@ -374,14 +374,14 @@ CONFIG_ESPTOOLPY_FLASHFREQ_40M=y # CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set CONFIG_ESPTOOLPY_FLASHFREQ="40m" # CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +CONFIG_ESPTOOLPY_FLASHSIZE="2MB" # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set @@ -406,123 +406,6 @@ CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table -# -# Arduino Configuration -# -CONFIG_ARDUINO_VARIANT="esp32" -CONFIG_ENABLE_ARDUINO_DEPENDS=y -CONFIG_AUTOSTART_ARDUINO=y -# CONFIG_ARDUINO_RUN_CORE0 is not set -CONFIG_ARDUINO_RUN_CORE1=y -# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_RUNNING_CORE=1 -CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 -# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set -CONFIG_ARDUINO_EVENT_RUN_CORE1=y -# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 -# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set -# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set -CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y -CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 -CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=2048 -CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 -CONFIG_ARDUINO_UDP_RUN_CORE0=y -# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set -# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_UDP_RUNNING_CORE=0 -CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 -# CONFIG_ARDUINO_ISR_IRAM is not set -# CONFIG_DISABLE_HAL_LOCKS is not set - -# -# Debug Log Configuration -# -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE is not set -CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR=y -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=1 -# CONFIG_ARDUHAL_LOG_COLORS is not set -# CONFIG_ARDUHAL_ESP_LOG is not set -# end of Debug Log Configuration - -CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT=y -# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS is not set -CONFIG_ARDUHAL_PARTITION_SCHEME="default" -# CONFIG_AUTOCONNECT_WIFI is not set -# CONFIG_ARDUINO_SELECTIVE_COMPILATION is not set -# end of Arduino Configuration - -# -# ESP RainMaker Config -# -CONFIG_ESP_RMAKER_NO_CLAIM=y -# CONFIG_ESP_RMAKER_USE_ESP_SECURE_CERT_MGR is not set -CONFIG_ESP_RMAKER_USE_NVS=y -CONFIG_ESP_RMAKER_CLAIM_TYPE=0 -# CONFIG_ESP_RMAKER_READ_MQTT_HOST_FROM_CONFIG is not set -# CONFIG_ESP_RMAKER_READ_NODE_ID_FROM_CERT_CN is not set -CONFIG_ESP_RMAKER_MQTT_USE_BASIC_INGEST_TOPICS=y -CONFIG_ESP_RMAKER_MQTT_ENABLE_BUDGETING=y -CONFIG_ESP_RMAKER_MQTT_DEFAULT_BUDGET=100 -CONFIG_ESP_RMAKER_MQTT_MAX_BUDGET=1024 -CONFIG_ESP_RMAKER_MQTT_BUDGET_REVIVE_PERIOD=5 -CONFIG_ESP_RMAKER_MQTT_BUDGET_REVIVE_COUNT=1 -CONFIG_ESP_RMAKER_MAX_PARAM_DATA_SIZE=1024 -# CONFIG_ESP_RMAKER_DISABLE_USER_MAPPING_PROV is not set -# CONFIG_ESP_RMAKER_USER_ID_CHECK is not set -# CONFIG_RMAKER_NAME_PARAM_CB is not set -# CONFIG_ESP_RMAKER_LOCAL_CTRL_FEATURE_ENABLE is not set -# CONFIG_ESP_RMAKER_LOCAL_CTRL_AUTO_ENABLE is not set -CONFIG_ESP_RMAKER_CONSOLE_UART_NUM_0=y -# CONFIG_ESP_RMAKER_CONSOLE_UART_NUM_1 is not set -CONFIG_ESP_RMAKER_CONSOLE_UART_NUM=0 -CONFIG_ESP_RMAKER_USE_CERT_BUNDLE=y - -# -# ESP RainMaker OTA Config -# -CONFIG_ESP_RMAKER_OTA_AUTOFETCH=y -CONFIG_ESP_RMAKER_OTA_AUTOFETCH_PERIOD=0 -# CONFIG_ESP_RMAKER_SKIP_COMMON_NAME_CHECK is not set -# CONFIG_ESP_RMAKER_SKIP_VERSION_CHECK is not set -# CONFIG_ESP_RMAKER_SKIP_SECURE_VERSION_CHECK is not set -# CONFIG_ESP_RMAKER_SKIP_PROJECT_NAME_CHECK is not set -CONFIG_ESP_RMAKER_OTA_HTTP_RX_BUFFER_SIZE=1024 -CONFIG_ESP_RMAKER_OTA_ROLLBACK_WAIT_PERIOD=90 -# CONFIG_ESP_RMAKER_OTA_DISABLE_AUTO_REBOOT is not set -CONFIG_ESP_RMAKER_OTA_TIME_SUPPORT=y -# end of ESP RainMaker OTA Config - -# -# ESP RainMaker Scheduling -# -CONFIG_ESP_RMAKER_SCHEDULING_MAX_SCHEDULES=10 -# end of ESP RainMaker Scheduling - -# -# ESP RainMaker Scenes -# -CONFIG_ESP_RMAKER_SCENES_MAX_SCENES=10 -# CONFIG_ESP_RMAKER_SCENES_DEACTIVATE_SUPPORT is not set -# end of ESP RainMaker Scenes - -# -# ESP RainMaker Command-Response -# -CONFIG_ESP_RMAKER_CMD_RESP_ENABLE=y -# CONFIG_ESP_RMAKER_CMD_RESP_TEST_ENABLE is not set -# end of ESP RainMaker Command-Response - -CONFIG_ESP_RMAKER_USING_NETWORK_PROV=y -# end of ESP RainMaker Config - # # Compiler options # @@ -578,7 +461,6 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # Bluetooth # # CONFIG_BT_ENABLED is not set -# CONFIG_BT_NIMBLE_ENABLED is not set CONFIG_BT_ALARM_MAX_NUM=50 # end of Bluetooth @@ -1457,7 +1339,7 @@ CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -CONFIG_LWIP_SO_RCVBUF=y +# CONFIG_LWIP_SO_RCVBUF is not set # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP_DEFAULT_TTL=64 CONFIG_LWIP_IP4_FRAG=y @@ -2005,284 +1887,6 @@ CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set # end of Wi-Fi Provisioning Manager - -# -# DSP Library -# -CONFIG_DSP_OPTIMIZATIONS_SUPPORTED=y -# CONFIG_DSP_ANSI is not set -CONFIG_DSP_OPTIMIZED=y -CONFIG_DSP_OPTIMIZATION=1 -# CONFIG_DSP_MAX_FFT_SIZE_512 is not set -# CONFIG_DSP_MAX_FFT_SIZE_1024 is not set -# CONFIG_DSP_MAX_FFT_SIZE_2048 is not set -CONFIG_DSP_MAX_FFT_SIZE_4096=y -# CONFIG_DSP_MAX_FFT_SIZE_8192 is not set -# CONFIG_DSP_MAX_FFT_SIZE_16384 is not set -# CONFIG_DSP_MAX_FFT_SIZE_32768 is not set -CONFIG_DSP_MAX_FFT_SIZE=4096 -# end of DSP Library - -# -# Modbus configuration -# -CONFIG_FMB_COMM_MODE_TCP_EN=y -CONFIG_FMB_TCP_PORT_DEFAULT=502 -CONFIG_FMB_TCP_PORT_MAX_CONN=5 -CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 -# CONFIG_FMB_TCP_UID_ENABLED is not set -CONFIG_FMB_COMM_MODE_RTU_EN=y -CONFIG_FMB_COMM_MODE_ASCII_EN=y -CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=3000 -CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 -CONFIG_FMB_QUEUE_LENGTH=20 -CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 -CONFIG_FMB_SERIAL_BUF_SIZE=256 -CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 -CONFIG_FMB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS=0 -CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 -CONFIG_FMB_PORT_TASK_PRIO=10 -# CONFIG_FMB_PORT_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_FMB_PORT_TASK_AFFINITY_CPU0=y -# CONFIG_FMB_PORT_TASK_AFFINITY_CPU1 is not set -CONFIG_FMB_PORT_TASK_AFFINITY=0x0 -CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y -CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 -CONFIG_FMB_CONTROLLER_SLAVE_ID_MAX_SIZE=32 -CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 -CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 -CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 -CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 -# CONFIG_FMB_TIMER_PORT_ENABLED is not set -# CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD is not set -# CONFIG_FMB_EXT_TYPE_SUPPORT is not set -# end of Modbus configuration - -# -# ESP serial flasher -# -CONFIG_SERIAL_FLASHER_MD5_ENABLED=y -CONFIG_SERIAL_FLASHER_RESET_HOLD_TIME_MS=100 -CONFIG_SERIAL_FLASHER_BOOT_HOLD_TIME_MS=50 -# end of ESP serial flasher - -# -# Zigbee -# -# CONFIG_ZB_ENABLED is not set -# end of Zigbee - -# -# Diagnostics data store -# -CONFIG_DIAG_DATA_STORE_RTC=y -# CONFIG_DIAG_DATA_STORE_FLASH is not set -# CONFIG_DIAG_DATA_STORE_DBG_PRINTS is not set -CONFIG_DIAG_DATA_STORE_REPORTING_WATERMARK_PERCENT=80 - -# -# RTC Store -# -CONFIG_RTC_STORE_DATA_SIZE=3072 -CONFIG_RTC_STORE_CRITICAL_DATA_SIZE=2048 -# end of RTC Store -# end of Diagnostics data store - -# -# Diagnostics -# -CONFIG_DIAG_LOG_MSG_ARG_FORMAT_TLV=y -# CONFIG_DIAG_LOG_MSG_ARG_FORMAT_STRING is not set -CONFIG_DIAG_LOG_MSG_ARG_MAX_SIZE=64 -CONFIG_DIAG_LOG_DROP_WIFI_LOGS=y -CONFIG_DIAG_ENABLE_METRICS=y -CONFIG_DIAG_METRICS_MAX_COUNT=20 -CONFIG_DIAG_ENABLE_HEAP_METRICS=y -CONFIG_DIAG_ENABLE_WIFI_METRICS=y -CONFIG_DIAG_ENABLE_VARIABLES=y -CONFIG_DIAG_VARIABLES_MAX_COUNT=20 -CONFIG_DIAG_ENABLE_NETWORK_VARIABLES=y -# CONFIG_DIAG_MORE_NETWORK_VARS is not set -# CONFIG_DIAG_USE_EXTERNAL_LOG_WRAP is not set -# end of Diagnostics - -# -# ESP Insights -# -# CONFIG_ESP_INSIGHTS_ENABLED is not set -# CONFIG_ESP_INSIGHTS_TRANSPORT_MQTT is not set -CONFIG_ESP_INSIGHTS_TRANSPORT_HTTPS=y -CONFIG_ESP_INSIGHTS_TRANSPORT_HTTPS_HOST="https://client.insights.espressif.com" -CONFIG_ESP_INSIGHTS_CLOUD_POST_MIN_INTERVAL_SEC=60 -CONFIG_ESP_INSIGHTS_CLOUD_POST_MAX_INTERVAL_SEC=240 -CONFIG_ESP_INSIGHTS_META_VERSION_10=y -# end of ESP Insights - -# -# esp-modem -# -CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y -# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set -CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 -# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set -# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set -CONFIG_ESP_MODEM_C_API_STR_MAX=128 -# CONFIG_ESP_MODEM_URC_HANDLER is not set -# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set -# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set -# end of esp-modem - -# -# OpenThread RCP Update -# -# CONFIG_AUTO_UPDATE_RCP is not set -# CONFIG_CREATE_OTA_IMAGE_WITH_RCP_FW is not set -# end of OpenThread RCP Update - -# -# ESP Secure Cert Manager -# -# CONFIG_ESP_SECURE_CERT_SUPPORT_LEGACY_FORMATS is not set -# end of ESP Secure Cert Manager - -# -# jsmn -# -# CONFIG_JSMN_PARENT_LINKS is not set -# CONFIG_JSMN_STRICT is not set -# CONFIG_JSMN_STATIC is not set -# end of jsmn - -# -# libsodium -# -# end of libsodium - -# -# mDNS -# -CONFIG_MDNS_MAX_INTERFACES=3 -CONFIG_MDNS_MAX_SERVICES=10 -CONFIG_MDNS_TASK_PRIORITY=1 -CONFIG_MDNS_ACTION_QUEUE_LEN=16 -CONFIG_MDNS_TASK_STACK_SIZE=4096 -# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_MDNS_TASK_AFFINITY_CPU0=y -# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set -CONFIG_MDNS_TASK_AFFINITY=0x0 - -# -# MDNS Memory Configuration -# -CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y -CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y -# CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set -# end of MDNS Memory Configuration - -CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 -CONFIG_MDNS_TIMER_PERIOD_MS=100 -# CONFIG_MDNS_NETWORKING_SOCKET is not set -# CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set -# CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set -CONFIG_MDNS_ENABLE_CONSOLE_CLI=y -# CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set -CONFIG_MDNS_MULTIPLE_INSTANCE=y - -# -# MDNS Predefined interfaces -# -CONFIG_MDNS_PREDEF_NETIF_STA=y -CONFIG_MDNS_PREDEF_NETIF_AP=y -CONFIG_MDNS_PREDEF_NETIF_ETH=y -# end of MDNS Predefined interfaces -# end of mDNS - -# -# Network Provisioning Manager -# -CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y -CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 -CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 -# CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set -CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y -# CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set -# end of Network Provisioning Manager - -# -# ESP RainMaker Common -# -CONFIG_ESP_RMAKER_LIB_ESP_MQTT=y -# CONFIG_ESP_RMAKER_LIB_AWS_IOT is not set -CONFIG_ESP_RMAKER_MQTT_GLUE_LIB=1 -CONFIG_ESP_RMAKER_MQTT_PORT_443=y -# CONFIG_ESP_RMAKER_MQTT_PORT_8883 is not set -CONFIG_ESP_RMAKER_MQTT_PORT=1 -# CONFIG_ESP_RMAKER_MQTT_PERSISTENT_SESSION is not set -CONFIG_ESP_RMAKER_MQTT_SEND_USERNAME=y -CONFIG_ESP_RMAKER_MQTT_PRODUCT_NAME="RMDev" -CONFIG_ESP_RMAKER_MQTT_PRODUCT_VERSION="1x0" -CONFIG_ESP_RMAKER_MQTT_PRODUCT_SKU="EX00" -CONFIG_ESP_RMAKER_MQTT_USE_CERT_BUNDLE=y -CONFIG_ESP_RMAKER_MAX_MQTT_SUBSCRIPTIONS=10 -CONFIG_ESP_RMAKER_MQTT_KEEP_ALIVE_INTERVAL=120 -CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI=y -CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_STACK=4096 -CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_PRIORITY=5 -CONFIG_ESP_RMAKER_FACTORY_PARTITION_NAME="fctry" -CONFIG_ESP_RMAKER_FACTORY_NAMESPACE="rmaker_creds" -CONFIG_ESP_RMAKER_DEF_TIMEZONE="Asia/Shanghai" -CONFIG_ESP_RMAKER_SNTP_SERVER_NAME="pool.ntp.org" -CONFIG_ESP_RMAKER_MAX_COMMANDS=10 -# end of ESP RainMaker Common - -# -# ESP-NimBLE-CPP configuration -# -CONFIG_NIMBLE_CPP_LOG_LEVEL_NONE=y -# CONFIG_NIMBLE_CPP_LOG_LEVEL_ERROR is not set -# CONFIG_NIMBLE_CPP_LOG_LEVEL_WARNING is not set -# CONFIG_NIMBLE_CPP_LOG_LEVEL_INFO is not set -# CONFIG_NIMBLE_CPP_LOG_LEVEL_DEBUG is not set -CONFIG_NIMBLE_CPP_LOG_LEVEL=0 -# CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR is not set -# CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT is not set -# CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT is not set -# CONFIG_NIMBLE_CPP_ENABLE_ADVERTISEMENT_TYPE_TEXT is not set -# CONFIG_NIMBLE_CPP_ADDR_FMT_EXCLUDE_DELIMITER is not set -# CONFIG_NIMBLE_CPP_ADDR_FMT_UPPERCASE is not set -# CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED is not set -CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH=20 -# CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED is not set -CONFIG_NIMBLE_CPP_FREERTOS_TASK_BLOCK_BIT=31 -# end of ESP-NimBLE-CPP configuration - -# -# LittleFS -# -# CONFIG_LITTLEFS_SDMMC_SUPPORT is not set -CONFIG_LITTLEFS_MAX_PARTITIONS=3 -CONFIG_LITTLEFS_PAGE_SIZE=256 -CONFIG_LITTLEFS_OBJ_NAME_LEN=64 -CONFIG_LITTLEFS_READ_SIZE=128 -CONFIG_LITTLEFS_WRITE_SIZE=128 -CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 -CONFIG_LITTLEFS_CACHE_SIZE=512 -CONFIG_LITTLEFS_BLOCK_CYCLES=512 -CONFIG_LITTLEFS_USE_MTIME=y -# CONFIG_LITTLEFS_USE_ONLY_HASH is not set -# CONFIG_LITTLEFS_HUMAN_READABLE is not set -CONFIG_LITTLEFS_MTIME_USE_SECONDS=y -# CONFIG_LITTLEFS_MTIME_USE_NONCE is not set -# CONFIG_LITTLEFS_SPIFFS_COMPAT is not set -# CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set -# CONFIG_LITTLEFS_FCNTL_GET_PATH is not set -# CONFIG_LITTLEFS_MULTIVERSION is not set -# CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set -CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y -# CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set -CONFIG_LITTLEFS_ASSERTS=y -# CONFIG_LITTLEFS_MMAP_PARTITION is not set -# end of LittleFS # end of Component config # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set @@ -2307,7 +1911,6 @@ CONFIG_LOG_BOOTLOADER_LEVEL=3 CONFIG_FLASHMODE_DIO=y # CONFIG_FLASHMODE_DOUT is not set CONFIG_MONITOR_BAUD=115200 -# CONFIG_ESP_RMAKER_LOCAL_CTRL_ENABLE is not set CONFIG_OPTIMIZATION_LEVEL_DEBUG=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y @@ -2326,7 +1929,6 @@ CONFIG_STACK_CHECK_NONE=y # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set CONFIG_ESP32_APPTRACE_DEST_NONE=y CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y -# CONFIG_NIMBLE_ENABLED is not set CONFIG_ADC2_DISABLE_DAC=y # CONFIG_MCPWM_ISR_IN_IRAM is not set # CONFIG_EVENT_LOOP_PROFILING is not set @@ -2498,18 +2100,4 @@ CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=3000 -CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 -CONFIG_MB_QUEUE_LENGTH=20 -CONFIG_MB_SERIAL_TASK_STACK_SIZE=4096 -CONFIG_MB_SERIAL_BUF_SIZE=256 -CONFIG_MB_SERIAL_TASK_PRIO=10 -CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT=y -CONFIG_MB_CONTROLLER_SLAVE_ID=0x00112233 -CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 -CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 -CONFIG_MB_CONTROLLER_STACK_SIZE=4096 -CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 -# CONFIG_MB_TIMER_PORT_ENABLED is not set -# CONFIG_NIMBLE_ENABLED is not set # End of deprecated options diff --git a/main/BLE_Client.cpp b/src/BLE_Client.cpp similarity index 100% rename from main/BLE_Client.cpp rename to src/BLE_Client.cpp diff --git a/main/BLE_Common.cpp b/src/BLE_Common.cpp similarity index 100% rename from main/BLE_Common.cpp rename to src/BLE_Common.cpp diff --git a/main/BLE_Custom_Characteristic.cpp b/src/BLE_Custom_Characteristic.cpp similarity index 100% rename from main/BLE_Custom_Characteristic.cpp rename to src/BLE_Custom_Characteristic.cpp diff --git a/main/BLE_Cycling_Power_Service.cpp b/src/BLE_Cycling_Power_Service.cpp similarity index 100% rename from main/BLE_Cycling_Power_Service.cpp rename to src/BLE_Cycling_Power_Service.cpp diff --git a/main/BLE_Cycling_Speed_Cadence.cpp b/src/BLE_Cycling_Speed_Cadence.cpp similarity index 100% rename from main/BLE_Cycling_Speed_Cadence.cpp rename to src/BLE_Cycling_Speed_Cadence.cpp diff --git a/main/BLE_Device_Information_Service.cpp b/src/BLE_Device_Information_Service.cpp similarity index 100% rename from main/BLE_Device_Information_Service.cpp rename to src/BLE_Device_Information_Service.cpp diff --git a/main/BLE_Firmware_Update.cpp b/src/BLE_Firmware_Update.cpp similarity index 100% rename from main/BLE_Firmware_Update.cpp rename to src/BLE_Firmware_Update.cpp diff --git a/main/BLE_Fitness_Machine_Service.cpp b/src/BLE_Fitness_Machine_Service.cpp similarity index 100% rename from main/BLE_Fitness_Machine_Service.cpp rename to src/BLE_Fitness_Machine_Service.cpp diff --git a/main/BLE_Heart_Service.cpp b/src/BLE_Heart_Service.cpp similarity index 100% rename from main/BLE_Heart_Service.cpp rename to src/BLE_Heart_Service.cpp diff --git a/main/BLE_SB20_Service.cpp b/src/BLE_SB20_Service.cpp similarity index 100% rename from main/BLE_SB20_Service.cpp rename to src/BLE_SB20_Service.cpp diff --git a/main/BLE_Server.cpp b/src/BLE_Server.cpp similarity index 100% rename from main/BLE_Server.cpp rename to src/BLE_Server.cpp diff --git a/main/BLE_Setup.cpp b/src/BLE_Setup.cpp similarity index 100% rename from main/BLE_Setup.cpp rename to src/BLE_Setup.cpp diff --git a/main/BLE_Wattbike_Service.cpp b/src/BLE_Wattbike_Service.cpp similarity index 100% rename from main/BLE_Wattbike_Service.cpp rename to src/BLE_Wattbike_Service.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..483bc0cf --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,6 @@ +# This file was automatically generated for projects +# without default 'CMakeLists.txt' file. + +FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*) + +idf_component_register(SRCS ${app_sources}) diff --git a/main/DirConManager.cpp b/src/DirConManager.cpp similarity index 100% rename from main/DirConManager.cpp rename to src/DirConManager.cpp diff --git a/main/DirConMessage.cpp b/src/DirConMessage.cpp similarity index 100% rename from main/DirConMessage.cpp rename to src/DirConMessage.cpp diff --git a/main/ERG_Mode.cpp b/src/ERG_Mode.cpp similarity index 100% rename from main/ERG_Mode.cpp rename to src/ERG_Mode.cpp diff --git a/main/HTTP_Server_Basic.cpp b/src/HTTP_Server_Basic.cpp similarity index 100% rename from main/HTTP_Server_Basic.cpp rename to src/HTTP_Server_Basic.cpp diff --git a/main/Main.cpp b/src/Main.cpp similarity index 100% rename from main/Main.cpp rename to src/Main.cpp diff --git a/main/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp similarity index 100% rename from main/PowerTable_Helpers.cpp rename to src/PowerTable_Helpers.cpp diff --git a/main/Power_Table.cpp b/src/Power_Table.cpp similarity index 100% rename from main/Power_Table.cpp rename to src/Power_Table.cpp diff --git a/main/SS2KLog.cpp b/src/SS2KLog.cpp similarity index 100% rename from main/SS2KLog.cpp rename to src/SS2KLog.cpp diff --git a/main/SensorCollector.cpp b/src/SensorCollector.cpp similarity index 100% rename from main/SensorCollector.cpp rename to src/SensorCollector.cpp diff --git a/main/SmartSpin_parameters.cpp b/src/SmartSpin_parameters.cpp similarity index 100% rename from main/SmartSpin_parameters.cpp rename to src/SmartSpin_parameters.cpp diff --git a/main/UdpAppender.cpp b/src/UdpAppender.cpp similarity index 100% rename from main/UdpAppender.cpp rename to src/UdpAppender.cpp diff --git a/main/WebsocketAppender.cpp b/src/WebsocketAppender.cpp similarity index 100% rename from main/WebsocketAppender.cpp rename to src/WebsocketAppender.cpp diff --git a/main/gitTracking.md b/src/gitTracking.md similarity index 100% rename from main/gitTracking.md rename to src/gitTracking.md From 1fea7c701fba4fb3edd58dfa51c98b5b006f51ec Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 25 Jun 2025 20:41:40 -0500 Subject: [PATCH 253/451] builds in pio --- .gitignore | 2 ++ .vscode/settings.json | 2 +- dependencies.lock | 2 +- sdkconfig.defaults | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 7795ffea..322bef49 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ build/CMakeCache.txt C/Users/ /build /managed_components +dependencies.lock +.vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json index 2888d84a..baf137d4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -119,6 +119,6 @@ "VERSIONFILE", "WEBSERVER" ], - "idf.pythonInstallPath": "/opt/homebrew/bin/python3", + "idf.pythonInstallPath": "C:\\Users\\anthony\\.espressif\\tools\\idf-python\\3.11.2\\python.exe", "idf.flashType": "UART", } \ No newline at end of file diff --git a/dependencies.lock b/dependencies.lock index 937a8ec5..17170be1 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -96,6 +96,6 @@ direct_dependencies: - espressif/network_provisioning - idf - joltwallet/littlefs -manifest_hash: e9919b5b28bb7bb038864af176d8e81936400eff14ef44258dd5186bdc427ec2 +manifest_hash: e871ea1e1aff9421b8e57e1c5a4db8daeef71b071a2a17f239e5feebc4acdfc3 target: esp32 version: 2.0.0 diff --git a/sdkconfig.defaults b/sdkconfig.defaults index d50929ea..84dd329f 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -1,4 +1,4 @@ -CONFIG_AUTOSTART_ARDUINO=y +CONFIG_AUTOSTART_ARDUINO=n # CONFIG_WS2812_LED_ENABLE is not set CONFIG_FREERTOS_HZ=1000 CONFIG_MBEDTLS_PSK_MODES=y From e529fbf74fc46ff7c7961c1cf882574f17836904 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Thu, 26 Jun 2025 11:39:45 -0400 Subject: [PATCH 254/451] updated github build. Updated max connections. --- .github/workflows/build.yml | 6 + .gitignore | 1 + dependencies.lock | 13 +- platformio.ini | 2 +- sdkconfig.release | 437 +----------------------------------- sdkconfig.release.old | 149 +++++++++--- 6 files changed, 127 insertions(+), 481 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 20968b5c..31e2fc5f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,6 +43,12 @@ jobs: run: python --version - name: Install PlatformIO run: python -m pip install platformio + - name: Install ESP-IDF + run: | + git clone --recursive https://github.com/espressif/esp-idf.git + cd esp-idf + git checkout v5.4 + ./install.sh - name: Check pre-commit hooks uses: pre-commit/action@v3.0.1 - name: Build firmware diff --git a/.gitignore b/.gitignore index 322bef49..ac2754f8 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ C/Users/ /managed_components dependencies.lock .vscode/settings.json +dependencies.lock diff --git a/dependencies.lock b/dependencies.lock index 17170be1..3aef0ca5 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -41,16 +41,6 @@ dependencies: registry_url: https://components.espressif.com/ type: service version: 1.6.3 - espressif/esp_modem: - component_hash: b541c3f5765d3ba062c0d004b9ca6da6d0af908293421c2dbe046c537fb2a011 - dependencies: - - name: idf - require: private - version: '>=4.1' - source: - registry_url: https://components.espressif.com/ - type: service - version: 1.4.0 espressif/mdns: component_hash: 3ec0af5f6bce310512e90f482388d21cc7c0e99668172d2f895356165fc6f7c5 dependencies: @@ -91,11 +81,10 @@ direct_dependencies: - espressif/cbor - espressif/esp-zboss-lib - espressif/esp-zigbee-lib -- espressif/esp_modem - espressif/mdns - espressif/network_provisioning - idf - joltwallet/littlefs -manifest_hash: e871ea1e1aff9421b8e57e1c5a4db8daeef71b071a2a17f239e5feebc4acdfc3 +manifest_hash: cdea08c215af25ecb07f34a572afe529ccee1d11a022752ebfb3b54cbc0cb5f8 target: esp32 version: 2.0.0 diff --git a/platformio.ini b/platformio.ini index cf55353b..0414362f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -53,7 +53,7 @@ build_flags = ;-D CONFIG_NEWLIB_NANO_FORMAT=y ;-D CONFIG_LWIP_IRAM_OPTIMIZATION=y ;-D CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM=y - ;-D CONFIG_BT_NIMBLE_MAX_CONNECTIONS=7 + ;-D CONFIG_NIMBLE_MAX_CONNECTIONS=7 ;-D CONFIG_BT_NIMBLE_WHITELIST_SIZE=0 ;-D CONFIG_MDNS_STRICT_MODE=1 ;-D CORE_DEBUG_LEVEL=1 diff --git a/sdkconfig.release b/sdkconfig.release index fa80a910..7b3b88bf 100644 --- a/sdkconfig.release +++ b/sdkconfig.release @@ -259,13 +259,9 @@ CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y CONFIG_APP_BUILD_GENERATE_BINARIES=y CONFIG_APP_BUILD_BOOTLOADER=y CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y -# default: # CONFIG_APP_REPRODUCIBLE_BUILD is not set -# default: # CONFIG_APP_NO_BLOBS is not set -# default: # CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set -# default: # CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set # end of Build type @@ -300,7 +296,6 @@ CONFIG_BOOTLOADER_LOG_LEVEL=3 # # Format # -# default: # CONFIG_BOOTLOADER_LOG_COLORS is not set CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y # end of Format @@ -309,32 +304,23 @@ CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y # # Serial Flash Configurations # -# default: # CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y # end of Serial Flash Configurations # CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y -# default: # CONFIG_BOOTLOADER_FACTORY_RESET is not set -# default: # CONFIG_BOOTLOADER_APP_TEST is not set CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y CONFIG_BOOTLOADER_WDT_ENABLE=y -# default: # CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set CONFIG_BOOTLOADER_WDT_TIME_MS=9000 -# default: # CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set -# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set -# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set -# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 -# default: # CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set # end of Bootloader config @@ -342,11 +328,8 @@ CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 # Security features # CONFIG_SECURE_BOOT_V1_SUPPORTED=y -# default: # CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set -# default: # CONFIG_SECURE_BOOT is not set -# default: # CONFIG_SECURE_FLASH_ENC_ENABLED is not set # end of Security features @@ -354,11 +337,8 @@ CONFIG_SECURE_BOOT_V1_SUPPORTED=y # Application manager # CONFIG_APP_COMPILE_TIME_DATE=y -# default: # CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set -# default: # CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set -# default: # CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 # end of Application manager @@ -381,7 +361,6 @@ CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y # # Serial flasher config # -# default: # CONFIG_ESPTOOLPY_NO_STUB is not set # CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set @@ -403,7 +382,6 @@ CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set CONFIG_ESPTOOLPY_FLASHSIZE="2MB" -# default: # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set @@ -433,7 +411,6 @@ CONFIG_PARTITION_TABLE_MD5=y # CONFIG_ARDUINO_VARIANT="esp32" CONFIG_ENABLE_ARDUINO_DEPENDS=y -# default: # CONFIG_AUTOSTART_ARDUINO is not set # CONFIG_ARDUINO_RUN_CORE0 is not set CONFIG_ARDUINO_RUN_CORE1=y @@ -455,9 +432,7 @@ CONFIG_ARDUINO_UDP_RUN_CORE0=y # CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set CONFIG_ARDUINO_UDP_RUNNING_CORE=0 CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 -# default: # CONFIG_ARDUINO_ISR_IRAM is not set -# default: # CONFIG_DISABLE_HAL_LOCKS is not set # @@ -470,9 +445,7 @@ CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE=y # CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set # CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=0 -# default: # CONFIG_ARDUHAL_LOG_COLORS is not set -# default: # CONFIG_ARDUHAL_ESP_LOG is not set # end of Debug Log Configuration @@ -487,25 +460,17 @@ CONFIG_ARDUINO_SELECTIVE_SPI=y CONFIG_ARDUINO_SELECTIVE_Wire=y CONFIG_ARDUINO_SELECTIVE_ESP_SR=y CONFIG_ARDUINO_SELECTIVE_EEPROM=y -# default: # CONFIG_ARDUINO_SELECTIVE_Preferences is not set -# default: # CONFIG_ARDUINO_SELECTIVE_Ticker is not set CONFIG_ARDUINO_SELECTIVE_Update=y -# default: # CONFIG_ARDUINO_SELECTIVE_Zigbee is not set CONFIG_ARDUINO_SELECTIVE_FS=y -# default: # CONFIG_ARDUINO_SELECTIVE_SD is not set -# default: # CONFIG_ARDUINO_SELECTIVE_SD_MMC is not set -# default: # CONFIG_ARDUINO_SELECTIVE_SPIFFS is not set -# default: # CONFIG_ARDUINO_SELECTIVE_FFat is not set CONFIG_ARDUINO_SELECTIVE_LittleFS=y CONFIG_ARDUINO_SELECTIVE_Network=y -# default: # CONFIG_ARDUINO_SELECTIVE_Ethernet is not set CONFIG_ARDUINO_SELECTIVE_PPP=y CONFIG_ARDUINO_SELECTIVE_ArduinoOTA=y @@ -513,23 +478,17 @@ CONFIG_ARDUINO_SELECTIVE_AsyncUDP=y CONFIG_ARDUINO_SELECTIVE_DNSServer=y CONFIG_ARDUINO_SELECTIVE_ESPmDNS=y CONFIG_ARDUINO_SELECTIVE_HTTPClient=y -# default: # CONFIG_ARDUINO_SELECTIVE_Matter is not set -# default: # CONFIG_ARDUINO_SELECTIVE_NetBIOS is not set CONFIG_ARDUINO_SELECTIVE_WebServer=y CONFIG_ARDUINO_SELECTIVE_WiFi=y CONFIG_ARDUINO_SELECTIVE_NetworkClientSecure=y CONFIG_ARDUINO_SELECTIVE_WiFiProv=y CONFIG_ARDUINO_SELECTIVE_BLE=y -# default: # CONFIG_ARDUINO_SELECTIVE_BluetoothSerial is not set CONFIG_ARDUINO_SELECTIVE_SimpleBLE=y -# default: # CONFIG_ARDUINO_SELECTIVE_RainMaker is not set -# default: # CONFIG_ARDUINO_SELECTIVE_OpenThread is not set -# default: # CONFIG_ARDUINO_SELECTIVE_Insights is not set # end of Arduino Configuration @@ -546,35 +505,25 @@ CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 -# default: # CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set CONFIG_COMPILER_HIDE_PATHS_MACROS=y -# default: # CONFIG_COMPILER_CXX_EXCEPTIONS is not set -# default: # CONFIG_COMPILER_CXX_RTTI is not set CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set # CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set # CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set -# default: # CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set -# default: # CONFIG_COMPILER_WARN_WRITE_STRINGS is not set CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y -# default: # CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set -# default: # CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set -# default: # CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set -# default: # CONFIG_COMPILER_DUMP_RTL_FILES is not set CONFIG_COMPILER_RT_LIB_GCCLIB=y CONFIG_COMPILER_RT_LIB_NAME="gcc" CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y # CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set -# default: # CONFIG_COMPILER_STATIC_ANALYZER is not set # end of Compiler options @@ -627,15 +576,10 @@ CONFIG_BT_NIMBLE_ROLE_CENTRAL=y CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y CONFIG_BT_NIMBLE_ROLE_OBSERVER=y -# default: # CONFIG_BT_NIMBLE_NVS_PERSIST is not set -# default: # CONFIG_BT_NIMBLE_SMP_ID_RESET is not set -# default: # CONFIG_BT_NIMBLE_SECURITY_ENABLE is not set -# default: # CONFIG_BT_NIMBLE_DEBUG is not set -# default: # CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 @@ -663,22 +607,16 @@ CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 -# default: # CONFIG_BT_NIMBLE_MESH is not set CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 -# default: # CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set -# default: # CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set CONFIG_BT_NIMBLE_WHITELIST_SIZE=1 -# default: # CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set -# default: # CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set CONFIG_BT_NIMBLE_USE_ESP_TIMER=y CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y -# default: # CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set # @@ -688,7 +626,6 @@ CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y # # GAP Appearance write permissions # -# default: # CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set # end of GAP Appearance write permissions @@ -704,7 +641,6 @@ CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 # # GAP device name write permissions # -# default: # CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set # end of GAP device name write permissions @@ -716,49 +652,33 @@ CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 -# default: # CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL is not set # end of GAP Service # # BLE Services # -# default: # CONFIG_BT_NIMBLE_HID_SERVICE is not set -# default: # CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY is not set # # Device Information Service # -# default: # CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED is not set # end of Device Information Service # end of BLE Services -# default: # CONFIG_BT_NIMBLE_VS_SUPPORT is not set -# default: # CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set -# default: # CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set -# default: # CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set -# default: # CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT is not set # @@ -772,7 +692,6 @@ CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 # end of Host-controller Transport CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 -# default: # CONFIG_BT_NIMBLE_SUBRATE is not set # end of NimBLE Options @@ -782,12 +701,12 @@ CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set # CONFIG_BTDM_CTRL_MODE_BTDM is not set -CONFIG_BTDM_CTRL_BLE_MAX_CONN=3 +CONFIG_BTDM_CTRL_BLE_MAX_CONN=7 CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 CONFIG_BTDM_CTRL_PCM_FSYNCSHP_EFF=0 -CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=3 +CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=7 CONFIG_BTDM_CTRL_BR_EDR_MIN_ENC_KEY_SZ_DFT_EFF=0 CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 @@ -815,12 +734,9 @@ CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y CONFIG_BTDM_SCAN_DUPL_TYPE=0 CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 -# default: # CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y -# default: # CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set -# default: # CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 @@ -829,15 +745,12 @@ CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # # BLE disconnects when Instant Passed (0x28) occurs # -# default: # CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set -# default: # CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set # end of BLE disconnects when Instant Passed (0x28) occurs CONFIG_BTDM_BLE_CHAN_ASS_EN=y CONFIG_BTDM_BLE_PING_EN=y -# default: # CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 is not set CONFIG_BTDM_RESERVE_DRAM=0xdb5c CONFIG_BTDM_CTRL_HLI=y @@ -847,21 +760,17 @@ CONFIG_BTDM_CTRL_HLI=y # Common Options # CONFIG_BT_ALARM_MAX_NUM=50 -# default: # CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set # end of Common Options -# default: # CONFIG_BT_HCI_LOG_DEBUG_EN is not set # end of Bluetooth -# default: # CONFIG_BLE_MESH is not set # # Console Library # -# default: # CONFIG_CONSOLE_SORTED_HELP is not set # end of Console Library @@ -872,7 +781,6 @@ CONFIG_BT_ALARM_MAX_NUM=50 # # TWAI Configuration # -# default: # CONFIG_TWAI_ISR_IN_IRAM is not set CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y @@ -885,9 +793,7 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # Legacy ADC Driver Configuration # CONFIG_ADC_DISABLE_DAC=y -# default: # CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set # @@ -896,7 +802,6 @@ CONFIG_ADC_DISABLE_DAC=y CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y CONFIG_ADC_CAL_LUT_ENABLE=y -# default: # CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set # end of Legacy ADC Calibration Configuration # end of Legacy ADC Driver Configuration @@ -904,63 +809,49 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # # Legacy DAC Driver Configurations # -# default: # CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy DAC Driver Configurations # # Legacy MCPWM Driver Configurations # -# default: # CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy MCPWM Driver Configurations # # Legacy Timer Group Driver Configurations # -# default: # CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Timer Group Driver Configurations # # Legacy RMT Driver Configurations # -# default: # CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy RMT Driver Configurations # # Legacy I2S Driver Configurations # -# default: # CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy I2S Driver Configurations # # Legacy PCNT Driver Configurations # -# default: # CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy PCNT Driver Configurations # # Legacy SDM Driver Configurations # -# default: # CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy SDM Driver Configurations # end of Driver Configurations @@ -968,9 +859,7 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # # eFuse Bit Manager # -# default: # CONFIG_EFUSE_CUSTOM_TABLE is not set -# default: # CONFIG_EFUSE_VIRTUAL is not set # CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y @@ -982,28 +871,19 @@ CONFIG_EFUSE_MAX_BLK_LEN=192 # ESP-TLS # CONFIG_ESP_TLS_USING_MBEDTLS=y -# default: # CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set -# default: # CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set -# default: # CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set -# default: # CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set -# default: # CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set -# default: # CONFIG_ESP_TLS_PSK_VERIFICATION is not set -# default: # CONFIG_ESP_TLS_INSECURE is not set # end of ESP-TLS # # ADC and ADC Calibration # -# default: # CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set # @@ -1015,7 +895,6 @@ CONFIG_ADC_CALI_LUT_ENABLE=y # end of ADC Calibration Configurations CONFIG_ADC_DISABLE_DAC_OUTPUT=y -# default: # CONFIG_ADC_ENABLE_DEBUG_LOG is not set # end of ADC and ADC Calibration @@ -1024,9 +903,7 @@ CONFIG_ADC_DISABLE_DAC_OUTPUT=y # CONFIG_ESP_COEX_ENABLED=y CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y -# default: # CONFIG_ESP_COEX_POWER_MANAGEMENT is not set -# default: # CONFIG_ESP_COEX_GPIO_DEBUG is not set # end of Wireless Coexistence @@ -1039,11 +916,8 @@ CONFIG_ESP_ERR_TO_NAME_LOOKUP=y # # ESP-Driver:DAC Configurations # -# default: # CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_DAC_ISR_IRAM_SAFE is not set -# default: # CONFIG_DAC_ENABLE_DEBUG_LOG is not set CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # end of ESP-Driver:DAC Configurations @@ -1051,9 +925,7 @@ CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # # ESP-Driver:GPIO Configurations # -# default: # CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set -# default: # CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:GPIO Configurations @@ -1061,90 +933,68 @@ CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # ESP-Driver:GPTimer Configurations # CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y -# default: # CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_GPTIMER_ISR_IRAM_SAFE is not set -# default: # CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:GPTimer Configurations # # ESP-Driver:I2C Configurations # -# default: # CONFIG_I2C_ISR_IRAM_SAFE is not set -# default: # CONFIG_I2C_ENABLE_DEBUG_LOG is not set -# default: # CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set # end of ESP-Driver:I2C Configurations # # ESP-Driver:I2S Configurations # -# default: # CONFIG_I2S_ISR_IRAM_SAFE is not set -# default: # CONFIG_I2S_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:I2S Configurations # # ESP-Driver:LEDC Configurations # -# default: # CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:LEDC Configurations # # ESP-Driver:MCPWM Configurations # -# default: # CONFIG_MCPWM_ISR_IRAM_SAFE is not set -# default: # CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:MCPWM Configurations # # ESP-Driver:PCNT Configurations # -# default: # CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_PCNT_ISR_IRAM_SAFE is not set -# default: # CONFIG_PCNT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:PCNT Configurations # # ESP-Driver:RMT Configurations # -# default: # CONFIG_RMT_ISR_IRAM_SAFE is not set -# default: # CONFIG_RMT_RECV_FUNC_IN_IRAM is not set -# default: # CONFIG_RMT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:RMT Configurations # # ESP-Driver:Sigma Delta Modulator Configurations # -# default: # CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_SDM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Sigma Delta Modulator Configurations # # ESP-Driver:SPI Configurations # -# default: # CONFIG_SPI_MASTER_IN_IRAM is not set CONFIG_SPI_MASTER_ISR_IN_IRAM=y -# default: # CONFIG_SPI_SLAVE_IN_IRAM is not set CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # end of ESP-Driver:SPI Configurations @@ -1152,36 +1002,28 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # # ESP-Driver:Touch Sensor Configurations # -# default: # CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_TOUCH_ISR_IRAM_SAFE is not set -# default: # CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Touch Sensor Configurations # # ESP-Driver:UART Configurations # -# default: # CONFIG_UART_ISR_IN_IRAM is not set # end of ESP-Driver:UART Configurations # # Ethernet # -# default: # CONFIG_ETH_USE_ESP32_EMAC is not set -# default: # CONFIG_ETH_USE_SPI_ETHERNET is not set -# default: # CONFIG_ETH_USE_OPENETH is not set # end of Ethernet # # Event Loop Library # -# default: # CONFIG_ESP_EVENT_LOOP_PROFILING is not set CONFIG_ESP_EVENT_POST_FROM_ISR=y CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y @@ -1191,7 +1033,6 @@ CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y # GDB Stub # CONFIG_ESP_GDBSTUB_ENABLED=y -# default: # CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y CONFIG_ESP_GDBSTUB_MAX_TASKS=32 @@ -1208,11 +1049,8 @@ CONFIG_ESPHID_TASK_SIZE_BLE=4096 # ESP HTTP client # CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y -# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set -# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set -# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 # end of ESP HTTP client @@ -1224,11 +1062,8 @@ CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 CONFIG_HTTPD_MAX_URI_LEN=512 CONFIG_HTTPD_ERR_RESP_NO_DELAY=y CONFIG_HTTPD_PURGE_BUF_LEN=32 -# default: # CONFIG_HTTPD_LOG_PURGE_DATA is not set -# default: # CONFIG_HTTPD_WS_SUPPORT is not set -# default: # CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # end of HTTP Server @@ -1236,9 +1071,7 @@ CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # # ESP HTTPS OTA # -# default: # CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set -# default: # CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS OTA @@ -1246,7 +1079,6 @@ CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # # ESP HTTPS server # -# default: # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS server @@ -1293,27 +1125,20 @@ CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 # CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 -# default: # CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set -# default: # CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set # end of MAC Config # # Sleep Config # -# default: # CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y -# default: # CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y -# default: # CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 -# default: # CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set -# default: # CONFIG_ESP_SLEEP_DEBUG is not set CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y # end of Sleep Config @@ -1350,7 +1175,6 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # # ESP-Driver:LCD Controller Configurations # -# default: # CONFIG_LCD_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:LCD Controller Configurations @@ -1363,19 +1187,14 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # ESP NETIF Adapter # CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 -# default: # CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set CONFIG_ESP_NETIF_TCPIP_LWIP=y # CONFIG_ESP_NETIF_LOOPBACK is not set CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y -# default: # CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set -# default: # CONFIG_ESP_NETIF_L2_TAP is not set -# default: # CONFIG_ESP_NETIF_BRIDGE_EN is not set -# default: # CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set # end of ESP NETIF Adapter @@ -1389,44 +1208,35 @@ CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y # CONFIG_ESP_PHY_ENABLED=y CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y -# default: # CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP_PHY_MAX_TX_POWER=20 -# default: # CONFIG_ESP_PHY_REDUCE_TX_POWER is not set -# default: # CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set CONFIG_ESP_PHY_RF_CAL_PARTIAL=y # CONFIG_ESP_PHY_RF_CAL_NONE is not set # CONFIG_ESP_PHY_RF_CAL_FULL is not set CONFIG_ESP_PHY_CALIBRATION_MODE=0 -# default: # CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set -# default: # CONFIG_ESP_PHY_RECORD_USED_TIME is not set # end of PHY # # Power Management # -# default: # CONFIG_PM_ENABLE is not set -# default: # CONFIG_PM_SLP_IRAM_OPT is not set # end of Power Management # # ESP PSRAM # -# default: # CONFIG_SPIRAM is not set # end of ESP PSRAM # # ESP Ringbuf # -# default: # CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set # end of ESP Ringbuf @@ -1446,13 +1256,11 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 # # Memory # -# default: # CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set # # Non-backward compatible options # -# default: # CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set # end of Non-backward compatible options # end of Memory @@ -1460,7 +1268,6 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 # # Trace memory # -# default: # CONFIG_ESP32_TRAX is not set CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 # end of Trace memory @@ -1496,14 +1303,11 @@ CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 CONFIG_ESP_INT_WDT_CHECK_CPU1=y CONFIG_ESP_TASK_WDT_EN=y CONFIG_ESP_TASK_WDT_INIT=y -# default: # CONFIG_ESP_TASK_WDT_PANIC is not set CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# default: # CONFIG_ESP_PANIC_HANDLER_IRAM is not set -# default: # CONFIG_ESP_DEBUG_STUBS_ENABLE is not set CONFIG_ESP_DEBUG_OCDAWARE=y CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y @@ -1523,7 +1327,6 @@ CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y CONFIG_ESP_BROWNOUT_DET_LVL=0 # end of Brownout Detector -# default: # CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y # end of ESP System Settings @@ -1539,18 +1342,15 @@ CONFIG_ESP_IPC_ISR_ENABLE=y # # ESP Timer (High Resolution Timer) # -# default: # CONFIG_ESP_TIMER_PROFILING is not set CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 -# default: # CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y -# default: # CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set CONFIG_ESP_TIMER_IMPL_TG0_LAC=y # end of ESP Timer (High Resolution Timer) @@ -1569,7 +1369,6 @@ CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y # CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 -# default: # CONFIG_ESP_WIFI_CSI_ENABLED is not set CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP_WIFI_TX_BA_WIN=6 @@ -1580,17 +1379,13 @@ CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 -# default: # CONFIG_ESP_WIFI_IRAM_OPT is not set -# default: # CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set -# default: # CONFIG_ESP_WIFI_RX_IRAM_OPT is not set CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y CONFIG_ESP_WIFI_ENABLE_SAE_PK=y CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y -# default: # CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 @@ -1598,41 +1393,28 @@ CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y CONFIG_ESP_WIFI_GMAC_SUPPORT=y CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y -# default: # CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 -# default: # CONFIG_ESP_WIFI_NAN_ENABLE is not set CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y -# default: # CONFIG_ESP_WIFI_WAPI_PSK is not set -# default: # CONFIG_ESP_WIFI_11KV_SUPPORT is not set -# default: # CONFIG_ESP_WIFI_MBO_SUPPORT is not set -# default: # CONFIG_ESP_WIFI_DPP_SUPPORT is not set -# default: # CONFIG_ESP_WIFI_11R_SUPPORT is not set -# default: # CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set # # WPS Configuration Options # -# default: # CONFIG_ESP_WIFI_WPS_STRICT is not set -# default: # CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set # end of WPS Configuration Options -# default: # CONFIG_ESP_WIFI_DEBUG_PRINT is not set -# default: # CONFIG_ESP_WIFI_TESTING_OPTIONS is not set CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y -# default: # CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set # end of Wi-Fi @@ -1679,15 +1461,12 @@ CONFIG_FATFS_CODEPAGE=437 CONFIG_FATFS_FS_LOCK=0 CONFIG_FATFS_TIMEOUT_MS=10000 CONFIG_FATFS_PER_FILE_CACHE=y -# default: # CONFIG_FATFS_USE_FASTSEEK is not set CONFIG_FATFS_USE_STRFUNC_NONE=y # CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set # CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 -# default: # CONFIG_FATFS_IMMEDIATE_FSYNC is not set -# default: # CONFIG_FATFS_USE_LABEL is not set CONFIG_FATFS_LINK_LOCK=y # end of FAT Filesystem support @@ -1699,9 +1478,7 @@ CONFIG_FATFS_LINK_LOCK=y # # Kernel # -# default: # CONFIG_FREERTOS_SMP is not set -# default: # CONFIG_FREERTOS_UNICORE is not set CONFIG_FREERTOS_HZ=1000 # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set @@ -1709,12 +1486,9 @@ CONFIG_FREERTOS_HZ=1000 CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 -# default: # CONFIG_FREERTOS_USE_IDLE_HOOK is not set -# default: # CONFIG_FREERTOS_USE_TICK_HOOK is not set CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 -# default: # CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set CONFIG_FREERTOS_USE_TIMERS=y CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" @@ -1727,38 +1501,28 @@ CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 -# default: # CONFIG_FREERTOS_USE_TRACE_FACILITY is not set -# default: # CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set -# default: # CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set -# default: # CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set # end of Kernel # # Port # -# default: # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y -# default: # CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set -# default: # CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y CONFIG_FREERTOS_ISR_STACKSIZE=1536 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y -# default: # CONFIG_FREERTOS_FPU_IN_ISR is not set CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y CONFIG_FREERTOS_CORETIMER_0=y # CONFIG_FREERTOS_CORETIMER_1 is not set CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y -# default: # CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set -# default: # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set # end of Port @@ -1797,13 +1561,9 @@ CONFIG_HEAP_POISONING_DISABLED=y CONFIG_HEAP_TRACING_OFF=y # CONFIG_HEAP_TRACING_STANDALONE is not set # CONFIG_HEAP_TRACING_TOHOST is not set -# default: # CONFIG_HEAP_USE_HOOKS is not set -# default: # CONFIG_HEAP_TASK_TRACKING is not set -# default: # CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set -# default: # CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set # end of Heap memory debugging @@ -1832,7 +1592,6 @@ CONFIG_LOG_MAXIMUM_LEVEL=0 # # Level Settings # -# default: # CONFIG_LOG_MASTER_LEVEL is not set CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y # CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set @@ -1847,7 +1606,6 @@ CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 # # Format # -# default: # CONFIG_LOG_COLORS is not set CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set @@ -1859,45 +1617,31 @@ CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LWIP_ENABLE=y CONFIG_LWIP_LOCAL_HOSTNAME="espressif" -# default: # CONFIG_LWIP_NETIF_API is not set CONFIG_LWIP_TCPIP_TASK_PRIO=18 -# default: # CONFIG_LWIP_TCPIP_CORE_LOCKING is not set -# default: # CONFIG_LWIP_CHECK_THREAD_SAFETY is not set CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -# default: # CONFIG_LWIP_L2_TO_L3_COPY is not set -# default: # CONFIG_LWIP_IRAM_OPTIMIZATION is not set -# default: # CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set CONFIG_LWIP_TIMERS_ONDEMAND=y CONFIG_LWIP_ND6=y -# default: # CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set CONFIG_LWIP_MAX_SOCKETS=10 -# default: # CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set -# default: # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y CONFIG_LWIP_SO_RCVBUF=y -# default: # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP_DEFAULT_TTL=64 CONFIG_LWIP_IP4_FRAG=y CONFIG_LWIP_IP6_FRAG=y -# default: # CONFIG_LWIP_IP4_REASSEMBLY is not set -# default: # CONFIG_LWIP_IP6_REASSEMBLY is not set CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 -# default: # CONFIG_LWIP_IP_FORWARD is not set -# default: # CONFIG_LWIP_STATS is not set CONFIG_LWIP_ESP_GRATUITOUS_ARP=y CONFIG_LWIP_GARP_TMR_INTERVAL=60 @@ -1907,10 +1651,8 @@ CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y # CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set # CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set -# default: # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y -# default: # CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set CONFIG_LWIP_DHCP_OPTIONS_LEN=68 CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 @@ -1926,16 +1668,12 @@ CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y CONFIG_LWIP_DHCPS_ADD_DNS=y # end of DHCP server -# default: # CONFIG_LWIP_AUTOIP is not set CONFIG_LWIP_IPV4=y CONFIG_LWIP_IPV6=y -# default: # CONFIG_LWIP_IPV6_AUTOCONFIG is not set CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 -# default: # CONFIG_LWIP_IPV6_FORWARD is not set -# default: # CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set CONFIG_LWIP_NETIF_LOOPBACK=y CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 @@ -1959,7 +1697,6 @@ CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 CONFIG_LWIP_TCP_QUEUE_OOSEQ=y CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 -# default: # CONFIG_LWIP_TCP_SACK_OUT is not set CONFIG_LWIP_TCP_OVERSIZE_MSS=y # CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set @@ -1977,9 +1714,7 @@ CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 # # Checksums # -# default: # CONFIG_LWIP_CHECKSUM_CHECK_IP is not set -# default: # CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums @@ -1994,18 +1729,14 @@ CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 -# default: # CONFIG_LWIP_PPP_SUPPORT is not set -# default: # CONFIG_LWIP_SLIP_SUPPORT is not set # # ICMP # CONFIG_LWIP_ICMP=y -# default: # CONFIG_LWIP_MULTICAST_PING is not set -# default: # CONFIG_LWIP_BROADCAST_PING is not set # end of ICMP @@ -2019,7 +1750,6 @@ CONFIG_LWIP_MAX_RAW_PCBS=16 # SNTP # CONFIG_LWIP_SNTP_MAX_SERVERS=1 -# default: # CONFIG_LWIP_DHCP_GET_NTP_SRV is not set CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 CONFIG_LWIP_SNTP_STARTUP_DELAY=y @@ -2031,9 +1761,7 @@ CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 # CONFIG_LWIP_DNS_MAX_HOST_IP=1 CONFIG_LWIP_DNS_MAX_SERVERS=3 -# default: # CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set -# default: # CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set # end of DNS @@ -2065,7 +1793,6 @@ CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y # CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set # end of Hooks -# default: # CONFIG_LWIP_DEBUG is not set # end of LWIP @@ -2078,21 +1805,15 @@ CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 -# default: # CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set -# default: # CONFIG_MBEDTLS_DEBUG is not set # # mbedTLS v3.x related # -# default: # CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set -# default: # CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set -# default: # CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set -# default: # CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y CONFIG_MBEDTLS_PKCS7_C=y @@ -2105,35 +1826,26 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set -# default: # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set -# default: # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 # end of Certificate Bundle -# default: # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set CONFIG_MBEDTLS_CMAC_C=y CONFIG_MBEDTLS_HARDWARE_AES=y CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y CONFIG_MBEDTLS_HARDWARE_MPI=y -# default: # CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set CONFIG_MBEDTLS_HARDWARE_SHA=y CONFIG_MBEDTLS_ROM_MD5=y -# default: # CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set -# default: # CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set CONFIG_MBEDTLS_HAVE_TIME=y -# default: # CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set -# default: # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y CONFIG_MBEDTLS_SHA512_C=y -# default: # CONFIG_MBEDTLS_SHA3_C is not set CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y # CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set @@ -2160,9 +1872,7 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y CONFIG_MBEDTLS_SSL_RENEGOTIATION=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y -# default: # CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set -# default: # CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set CONFIG_MBEDTLS_SSL_ALPN=y CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y @@ -2172,21 +1882,15 @@ CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y # Symmetric Ciphers # CONFIG_MBEDTLS_AES_C=y -# default: # CONFIG_MBEDTLS_CAMELLIA_C is not set -# default: # CONFIG_MBEDTLS_DES_C is not set -# default: # CONFIG_MBEDTLS_BLOWFISH_C is not set -# default: # CONFIG_MBEDTLS_XTEA_C is not set CONFIG_MBEDTLS_CCM_C=y CONFIG_MBEDTLS_GCM_C=y -# default: # CONFIG_MBEDTLS_NIST_KW_C is not set # end of Symmetric Ciphers -# default: # CONFIG_MBEDTLS_RIPEMD160_C is not set # @@ -2201,11 +1905,9 @@ CONFIG_MBEDTLS_X509_CSR_PARSE_C=y CONFIG_MBEDTLS_ECP_C=y CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y -# default: # CONFIG_MBEDTLS_DHM_C is not set CONFIG_MBEDTLS_ECDH_C=y CONFIG_MBEDTLS_ECDSA_C=y -# default: # CONFIG_MBEDTLS_ECJPAKE_C is not set CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y @@ -2220,15 +1922,10 @@ CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y CONFIG_MBEDTLS_ECP_NIST_OPTIM=y -# default: # CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set -# default: # CONFIG_MBEDTLS_POLY1305_C is not set -# default: # CONFIG_MBEDTLS_CHACHA20_C is not set -# default: # CONFIG_MBEDTLS_HKDF_C is not set -# default: # CONFIG_MBEDTLS_THREADING_C is not set CONFIG_MBEDTLS_ERROR_STRINGS=y CONFIG_MBEDTLS_FS_IO=y @@ -2237,25 +1934,15 @@ CONFIG_MBEDTLS_FS_IO=y # # ESP-MQTT Configurations # -# default: # CONFIG_MQTT_PROTOCOL_311 is not set -# default: # CONFIG_MQTT_PROTOCOL_5 is not set -# default: # CONFIG_MQTT_TRANSPORT_SSL is not set -# default: # CONFIG_MQTT_TRANSPORT_WEBSOCKET is not set -# default: # CONFIG_MQTT_MSG_ID_INCREMENTAL is not set -# default: # CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set -# default: # CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set -# default: # CONFIG_MQTT_USE_CUSTOM_CONFIG is not set -# default: # CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set -# default: # CONFIG_MQTT_CUSTOM_OUTBOX is not set # end of ESP-MQTT Configurations @@ -2268,7 +1955,6 @@ CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y # CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set # CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y -# default: # CONFIG_NEWLIB_NANO_FORMAT is not set CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y # CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set @@ -2279,22 +1965,18 @@ CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y # # NVS # -# default: # CONFIG_NVS_ASSERT_ERROR_CHECK is not set -# default: # CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set # end of NVS # # OpenThread # -# default: # CONFIG_OPENTHREAD_ENABLED is not set # # OpenThread Spinel # -# default: # CONFIG_OPENTHREAD_SPINEL_ONLY is not set # end of OpenThread Spinel # end of OpenThread @@ -2348,7 +2030,6 @@ CONFIG_SPI_FLASH_BROWNOUT_RESET=y # Features here require specific hardware (READ DOCS FIRST!) # CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 -# default: # CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set # end of Optional and Experimental Features (READ DOCS FIRST) # end of Main Flash configuration @@ -2356,27 +2037,20 @@ CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 # # SPI Flash driver # -# default: # CONFIG_SPI_FLASH_VERIFY_WRITE is not set -# default: # CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y # CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set # CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set -# default: # CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set -# default: # CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 -# default: # CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set -# default: # CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set -# default: # CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set # @@ -2391,9 +2065,7 @@ CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y -# default: # CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set -# default: # CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set # end of Auto-detect flash chips @@ -2410,17 +2082,14 @@ CONFIG_SPIFFS_MAX_PARTITIONS=3 # CONFIG_SPIFFS_CACHE=y CONFIG_SPIFFS_CACHE_WR=y -# default: # CONFIG_SPIFFS_CACHE_STATS is not set # end of SPIFFS Cache Configuration CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 -# default: # CONFIG_SPIFFS_GC_STATS is not set CONFIG_SPIFFS_PAGE_SIZE=256 CONFIG_SPIFFS_OBJ_NAME_LEN=32 -# default: # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y @@ -2430,17 +2099,11 @@ CONFIG_SPIFFS_USE_MTIME=y # # Debug Configuration # -# default: # CONFIG_SPIFFS_DBG is not set -# default: # CONFIG_SPIFFS_API_DBG is not set -# default: # CONFIG_SPIFFS_GC_DBG is not set -# default: # CONFIG_SPIFFS_CACHE_DBG is not set -# default: # CONFIG_SPIFFS_CHECK_DBG is not set -# default: # CONFIG_SPIFFS_TEST_VISUALISATION is not set # end of Debug Configuration # end of SPIFFS Configuration @@ -2454,7 +2117,6 @@ CONFIG_SPIFFS_USE_MTIME=y # CONFIG_WS_TRANSPORT=y CONFIG_WS_BUFFER_SIZE=1024 -# default: # CONFIG_WS_DYNAMIC_BUFFER is not set # end of Websocket # end of TCP Transport @@ -2462,7 +2124,6 @@ CONFIG_WS_BUFFER_SIZE=1024 # # Ultra Low Power (ULP) Co-processor # -# default: # CONFIG_ULP_COPROC_ENABLED is not set # @@ -2476,14 +2137,10 @@ CONFIG_WS_BUFFER_SIZE=1024 # CONFIG_UNITY_ENABLE_FLOAT=y CONFIG_UNITY_ENABLE_DOUBLE=y -# default: # CONFIG_UNITY_ENABLE_64BIT is not set -# default: # CONFIG_UNITY_ENABLE_COLOR is not set CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y -# default: # CONFIG_UNITY_ENABLE_FIXTURE is not set -# default: # CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set # end of Unity unit testing library @@ -2494,7 +2151,6 @@ CONFIG_VFS_SUPPORT_IO=y CONFIG_VFS_SUPPORT_DIR=y CONFIG_VFS_SUPPORT_SELECT=y CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y -# default: # CONFIG_VFS_SELECT_IN_RAM is not set CONFIG_VFS_SUPPORT_TERMIOS=y CONFIG_VFS_MAX_COUNT=8 @@ -2521,14 +2177,10 @@ CONFIG_WL_SECTOR_SIZE=4096 # CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 -# default: # CONFIG_WIFI_PROV_BLE_BONDING is not set CONFIG_WIFI_PROV_BLE_SEC_CONN=y -# default: # CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set -# default: # CONFIG_WIFI_PROV_BLE_NOTIFY is not set -# default: # CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set @@ -2537,33 +2189,9 @@ CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # # Zigbee # -# default: # CONFIG_ZB_ENABLED is not set # end of Zigbee -# -# esp-modem -# -# default: -CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y -# default: -# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set -# default: -CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 -# default: -# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set -# default: -# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set -# default: -CONFIG_ESP_MODEM_C_API_STR_MAX=128 -# default: -# CONFIG_ESP_MODEM_URC_HANDLER is not set -# default: -# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set -# default: -# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set -# end of esp-modem - # # mDNS # @@ -2582,20 +2210,15 @@ CONFIG_MDNS_TASK_AFFINITY=0x0 # CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y -# default: # CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set # end of MDNS Memory Configuration CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 CONFIG_MDNS_TIMER_PERIOD_MS=100 -# default: # CONFIG_MDNS_NETWORKING_SOCKET is not set -# default: # CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set -# default: # CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set CONFIG_MDNS_ENABLE_CONSOLE_CLI=y -# default: # CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set CONFIG_MDNS_MULTIPLE_INSTANCE=y @@ -2613,12 +2236,9 @@ CONFIG_MDNS_PREDEF_NETIF_AP=y CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 -# default: # CONFIG_NETWORK_PROV_BLE_BONDING is not set CONFIG_NETWORK_PROV_BLE_SEC_CONN=y -# default: # CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set -# default: # CONFIG_NETWORK_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y # CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set @@ -2627,7 +2247,6 @@ CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y # # LittleFS # -# default: # CONFIG_LITTLEFS_SDMMC_SUPPORT is not set CONFIG_LITTLEFS_MAX_PARTITIONS=3 CONFIG_LITTLEFS_PAGE_SIZE=256 @@ -2638,41 +2257,29 @@ CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 CONFIG_LITTLEFS_CACHE_SIZE=512 CONFIG_LITTLEFS_BLOCK_CYCLES=512 CONFIG_LITTLEFS_USE_MTIME=y -# default: # CONFIG_LITTLEFS_USE_ONLY_HASH is not set -# default: # CONFIG_LITTLEFS_HUMAN_READABLE is not set CONFIG_LITTLEFS_MTIME_USE_SECONDS=y # CONFIG_LITTLEFS_MTIME_USE_NONCE is not set -# default: # CONFIG_LITTLEFS_SPIFFS_COMPAT is not set -# default: # CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set -# default: # CONFIG_LITTLEFS_FCNTL_GET_PATH is not set -# default: # CONFIG_LITTLEFS_MULTIVERSION is not set # CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y # CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set CONFIG_LITTLEFS_ASSERTS=y -# default: # CONFIG_LITTLEFS_MMAP_PARTITION is not set # end of LittleFS # end of Component config -# default: # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set # Deprecated options for backward compatibility # CONFIG_APP_BUILD_TYPE_ELF_RAM is not set -# default: # CONFIG_NO_BLOBS is not set -# default: # CONFIG_ESP32_NO_BLOBS is not set -# default: # CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set -# default: # CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set # CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set # CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set @@ -2681,9 +2288,7 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y # CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set # CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set CONFIG_LOG_BOOTLOADER_LEVEL=3 -# default: # CONFIG_APP_ROLLBACK_ENABLE is not set -# default: # CONFIG_FLASH_ENCRYPTION_ENABLED is not set # CONFIG_FLASHMODE_QIO is not set # CONFIG_FLASHMODE_QOUT is not set @@ -2699,13 +2304,11 @@ CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y # CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set # CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 -# default: # CONFIG_CXX_EXCEPTIONS is not set CONFIG_STACK_CHECK_NONE=y # CONFIG_STACK_CHECK_NORM is not set # CONFIG_STACK_CHECK_STRONG is not set # CONFIG_STACK_CHECK_ALL is not set -# default: # CONFIG_WARN_WRITE_STRINGS is not set # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set CONFIG_ESP32_APPTRACE_DEST_NONE=y @@ -2727,9 +2330,7 @@ CONFIG_NIMBLE_ROLE_CENTRAL=y CONFIG_NIMBLE_ROLE_PERIPHERAL=y CONFIG_NIMBLE_ROLE_BROADCASTER=y CONFIG_NIMBLE_ROLE_OBSERVER=y -# default: # CONFIG_NIMBLE_NVS_PERSIST is not set -# default: # CONFIG_NIMBLE_DEBUG is not set CONFIG_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" CONFIG_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 @@ -2746,14 +2347,13 @@ CONFIG_NIMBLE_HS_FLOW_CTRL_ITVL=1000 CONFIG_NIMBLE_HS_FLOW_CTRL_THRESH=2 CONFIG_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y CONFIG_NIMBLE_RPA_TIMEOUT=900 -# default: # CONFIG_NIMBLE_MESH is not set CONFIG_NIMBLE_CRYPTO_STACK_MBEDTLS=y CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y # CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY is not set # CONFIG_BTDM_CONTROLLER_MODE_BTDM is not set -CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=3 -CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=3 +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=7 +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=7 CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0 CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 @@ -2766,7 +2366,6 @@ CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y # CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR is not set CONFIG_SCAN_DUPLICATE_TYPE=0 CONFIG_DUPLICATE_SCAN_CACHE_SIZE=100 -# default: # CONFIG_BLE_MESH_SCAN_DUPLICATE_EN is not set CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED=y @@ -2776,20 +2375,16 @@ CONFIG_ADC2_DISABLE_DAC=y CONFIG_SW_COEXIST_ENABLE=y CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y -# default: # CONFIG_MCPWM_ISR_IN_IRAM is not set -# default: # CONFIG_EVENT_LOOP_PROFILING is not set CONFIG_POST_EVENTS_FROM_ISR=y CONFIG_POST_EVENTS_FROM_IRAM_ISR=y CONFIG_GDBSTUB_SUPPORT_TASKS=y CONFIG_GDBSTUB_MAX_TASKS=32 -# default: # CONFIG_OTA_ALLOW_HTTP is not set # CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 -# default: # CONFIG_ESP_SYSTEM_PD_FLASH is not set CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 @@ -2807,17 +2402,12 @@ CONFIG_ESP32_XTAL_FREQ_40=y # CONFIG_ESP32_XTAL_FREQ_AUTO is not set CONFIG_ESP32_XTAL_FREQ=40 CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y -# default: # CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP32_PHY_MAX_TX_POWER=20 -# default: # CONFIG_REDUCE_PHY_TX_POWER is not set -# default: # CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set -# default: # CONFIG_SPIRAM_SUPPORT is not set -# default: # CONFIG_ESP32_SPIRAM_SUPPORT is not set # CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y @@ -2843,12 +2433,10 @@ CONFIG_INT_WDT_TIMEOUT_MS=300 CONFIG_INT_WDT_CHECK_CPU1=y CONFIG_TASK_WDT=y CONFIG_ESP_TASK_WDT=y -# default: # CONFIG_TASK_WDT_PANIC is not set CONFIG_TASK_WDT_TIMEOUT_S=5 CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# default: # CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set CONFIG_ESP32_DEBUG_OCDAWARE=y CONFIG_BROWNOUT_DET=y @@ -2871,7 +2459,6 @@ CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set CONFIG_BROWNOUT_DET_LVL=0 CONFIG_ESP32_BROWNOUT_DET_LVL=0 -# default: # CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set CONFIG_IPC_TASK_STACK_SIZE=1024 CONFIG_TIMER_TASK_STACK_SIZE=3584 @@ -2882,7 +2469,6 @@ CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 -# default: # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP32_WIFI_TX_BA_WIN=6 @@ -2893,31 +2479,20 @@ CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 -# default: # CONFIG_ESP32_WIFI_IRAM_OPT is not set -# default: # CONFIG_ESP32_WIFI_RX_IRAM_OPT is not set CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y CONFIG_WPA_MBEDTLS_CRYPTO=y CONFIG_WPA_MBEDTLS_TLS_CLIENT=y -# default: # CONFIG_WPA_WAPI_PSK is not set -# default: # CONFIG_WPA_11KV_SUPPORT is not set -# default: # CONFIG_WPA_MBO_SUPPORT is not set -# default: # CONFIG_WPA_DPP_SUPPORT is not set -# default: # CONFIG_WPA_11R_SUPPORT is not set -# default: # CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set -# default: # CONFIG_WPA_WPS_STRICT is not set -# default: # CONFIG_WPA_DEBUG_PRINT is not set -# default: # CONFIG_WPA_TESTING_OPTIONS is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set @@ -2925,10 +2500,8 @@ CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y CONFIG_TIMER_TASK_PRIORITY=1 CONFIG_TIMER_TASK_STACK_DEPTH=2048 CONFIG_TIMER_QUEUE_LENGTH=10 -# default: # CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set # CONFIG_HAL_ASSERTION_SILIENT is not set -# default: # CONFIG_L2_TO_L3_COPY is not set CONFIG_ESP_GRATUITOUS_ARP=y CONFIG_GARP_TMR_INTERVAL=60 @@ -2950,7 +2523,6 @@ CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set # CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF -# default: # CONFIG_PPP_SUPPORT is not set CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y @@ -2969,7 +2541,6 @@ CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set -# default: # CONFIG_ESP32_ULP_COPROC_ENABLED is not set CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y diff --git a/sdkconfig.release.old b/sdkconfig.release.old index 8017e96b..2d448110 100644 --- a/sdkconfig.release.old +++ b/sdkconfig.release.old @@ -1,6 +1,6 @@ # # Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) 5.3.2 Project Configuration +# Espressif IoT Development Framework (ESP-IDF) 5.4.1 Project Configuration # CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined" CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined" @@ -98,6 +98,7 @@ CONFIG_SOC_I2C_FIFO_LEN=32 CONFIG_SOC_I2C_CMD_REG_NUM=16 CONFIG_SOC_I2C_SUPPORT_SLAVE=y CONFIG_SOC_I2C_SUPPORT_APB=y +CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR=y CONFIG_SOC_I2C_STOP_INDEPENDENT=y CONFIG_SOC_I2S_NUM=2 CONFIG_SOC_I2S_HW_VERSION_1=y @@ -122,6 +123,7 @@ CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y +CONFIG_SOC_LEDC_TIMER_NUM=4 CONFIG_SOC_LEDC_CHANNEL_NUM=8 CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=20 CONFIG_SOC_MCPWM_GROUPS=2 @@ -174,6 +176,8 @@ CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y +CONFIG_SOC_LP_TIMER_BIT_WIDTH_LO=32 +CONFIG_SOC_LP_TIMER_BIT_WIDTH_HI=16 CONFIG_SOC_TOUCH_SENSOR_VERSION=1 CONFIG_SOC_TOUCH_SENSOR_NUM=10 CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1 @@ -216,6 +220,7 @@ CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y CONFIG_SOC_PM_SUPPORT_MODEM_PD=y CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y +CONFIG_SOC_PM_MODEM_PD_BY_SW=y CONFIG_SOC_CLK_APLL_SUPPORTED=y CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y @@ -238,6 +243,7 @@ CONFIG_SOC_PHY_COMBO_MODULE=y CONFIG_SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK=y CONFIG_IDF_CMAKE=y CONFIG_IDF_TOOLCHAIN="gcc" +CONFIG_IDF_TOOLCHAIN_GCC=y CONFIG_IDF_TARGET_ARCH_XTENSA=y CONFIG_IDF_TARGET_ARCH="xtensa" CONFIG_IDF_TARGET="esp32" @@ -275,6 +281,10 @@ CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set + +# +# Log +# # CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set # CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set # CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set @@ -283,6 +293,14 @@ CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y # CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set CONFIG_BOOTLOADER_LOG_LEVEL=3 +# +# Format +# +# CONFIG_BOOTLOADER_LOG_COLORS is not set +CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y +# end of Format +# end of Log + # # Serial Flash Configurations # @@ -338,6 +356,7 @@ CONFIG_ESP_ROM_HAS_SW_FLOAT=y CONFIG_ESP_ROM_USB_OTG_NUM=-1 CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1 CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y +CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y # # Serial flasher config @@ -379,6 +398,7 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 CONFIG_PARTITION_TABLE_SINGLE_APP=y # CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set # CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set # CONFIG_PARTITION_TABLE_CUSTOM is not set CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" @@ -475,13 +495,14 @@ CONFIG_ARDUINO_SELECTIVE_SimpleBLE=y # # Compiler options # -CONFIG_COMPILER_OPTIMIZATION_DEBUG=y -# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set +# CONFIG_COMPILER_OPTIMIZATION_DEBUG is not set +CONFIG_COMPILER_OPTIMIZATION_SIZE=y # CONFIG_COMPILER_OPTIMIZATION_PERF is not set # CONFIG_COMPILER_OPTIMIZATION_NONE is not set CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 # CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set @@ -492,14 +513,18 @@ CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set # CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set # CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set # CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y # CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set # CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set # CONFIG_COMPILER_DUMP_RTL_FILES is not set CONFIG_COMPILER_RT_LIB_GCCLIB=y CONFIG_COMPILER_RT_LIB_NAME="gcc" CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y # CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set +# CONFIG_COMPILER_STATIC_ANALYZER is not set # end of Compiler options # @@ -653,8 +678,8 @@ CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 # CONFIG_BT_NIMBLE_VS_SUPPORT is not set # CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set # CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set -# CONFIG_BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN is not set # CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set +# CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT is not set # # Host-controller Transport @@ -680,7 +705,9 @@ CONFIG_BTDM_CTRL_BLE_MAX_CONN=3 CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 +CONFIG_BTDM_CTRL_PCM_FSYNCSHP_EFF=0 CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=3 +CONFIG_BTDM_CTRL_BR_EDR_MIN_ENC_KEY_SZ_DFT_EFF=0 CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 CONFIG_BTDM_CTRL_PINNED_TO_CORE_0=y @@ -716,12 +743,15 @@ CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # -# BLE disconnect when instant passed +# BLE disconnects when Instant Passed (0x28) occurs # # CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set # CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set -# end of BLE disconnect when instant passed +# end of BLE disconnects when Instant Passed (0x28) occurs +CONFIG_BTDM_BLE_CHAN_ASS_EN=y +CONFIG_BTDM_BLE_PING_EN=y +# CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 is not set CONFIG_BTDM_RESERVE_DRAM=0xdb5c CONFIG_BTDM_CTRL_HLI=y # end of Controller Options @@ -730,6 +760,7 @@ CONFIG_BTDM_CTRL_HLI=y # Common Options # CONFIG_BT_ALARM_MAX_NUM=50 +# CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set # end of Common Options # CONFIG_BT_HCI_LOG_DEBUG_EN is not set @@ -763,6 +794,7 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # CONFIG_ADC_DISABLE_DAC=y # CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set # # Legacy ADC Calibration Configuration @@ -778,42 +810,49 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # Legacy DAC Driver Configurations # # CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy DAC Driver Configurations # # Legacy MCPWM Driver Configurations # # CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy MCPWM Driver Configurations # # Legacy Timer Group Driver Configurations # # CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Timer Group Driver Configurations # # Legacy RMT Driver Configurations # # CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy RMT Driver Configurations # # Legacy I2S Driver Configurations # # CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy I2S Driver Configurations # # Legacy PCNT Driver Configurations # # CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy PCNT Driver Configurations # # Legacy SDM Driver Configurations # # CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy SDM Driver Configurations # end of Driver Configurations @@ -904,6 +943,7 @@ CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y # # CONFIG_I2C_ISR_IRAM_SAFE is not set # CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set # end of ESP-Driver:I2C Configurations # @@ -998,6 +1038,13 @@ CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y CONFIG_ESP_GDBSTUB_MAX_TASKS=32 # end of GDB Stub +# +# ESP HID +# +CONFIG_ESPHID_TASK_SIZE_BT=2048 +CONFIG_ESPHID_TASK_SIZE_BLE=4096 +# end of ESP HID + # # ESP HTTP client # @@ -1005,6 +1052,7 @@ CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set # CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set # CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set +CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 # end of ESP HTTP client # @@ -1017,6 +1065,7 @@ CONFIG_HTTPD_PURGE_BUF_LEN=32 # CONFIG_HTTPD_LOG_PURGE_DATA is not set # CONFIG_HTTPD_WS_SUPPORT is not set # CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # end of HTTP Server # @@ -1024,12 +1073,14 @@ CONFIG_HTTPD_PURGE_BUF_LEN=32 # # CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set # CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS OTA # # ESP HTTPS server # # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS server # @@ -1112,6 +1163,7 @@ CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y # Main XTAL Config # # CONFIG_XTAL_FREQ_26 is not set +# CONFIG_XTAL_FREQ_32 is not set CONFIG_XTAL_FREQ_40=y # CONFIG_XTAL_FREQ_AUTO is not set CONFIG_XTAL_FREQ=40 @@ -1121,27 +1173,25 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # end of Hardware Settings # -# LCD and Touch Panel -# - -# -# LCD Touch Drivers are maintained in the IDF Component Registry +# ESP-Driver:LCD Controller Configurations # +# CONFIG_LCD_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:LCD Controller Configurations # -# LCD Peripheral Configuration +# ESP-MM: Memory Management Configurations # -# CONFIG_LCD_ENABLE_DEBUG_LOG is not set -# end of LCD Peripheral Configuration -# end of LCD and Touch Panel +# end of ESP-MM: Memory Management Configurations # # ESP NETIF Adapter # CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +# CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set CONFIG_ESP_NETIF_TCPIP_LWIP=y # CONFIG_ESP_NETIF_LOOPBACK is not set CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y # CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set # CONFIG_ESP_NETIF_L2_TAP is not set # CONFIG_ESP_NETIF_BRIDGE_EN is not set @@ -1168,6 +1218,7 @@ CONFIG_ESP_PHY_RF_CAL_PARTIAL=y # CONFIG_ESP_PHY_RF_CAL_FULL is not set CONFIG_ESP_PHY_CALIBRATION_MODE=0 # CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# CONFIG_ESP_PHY_RECORD_USED_TIME is not set # end of PHY # @@ -1189,6 +1240,11 @@ CONFIG_ESP_PHY_CALIBRATION_MODE=0 # CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set # end of ESP Ringbuf +# +# ESP Security Specific +# +# end of ESP Security Specific + # # ESP System Settings # @@ -1406,6 +1462,9 @@ CONFIG_FATFS_FS_LOCK=0 CONFIG_FATFS_TIMEOUT_MS=10000 CONFIG_FATFS_PER_FILE_CACHE=y # CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_USE_STRFUNC_NONE=y +# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set +# CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 # CONFIG_FATFS_IMMEDIATE_FSYNC is not set # CONFIG_FATFS_USE_LABEL is not set @@ -1431,6 +1490,7 @@ CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 # CONFIG_FREERTOS_USE_TICK_HOOK is not set CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 # CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_USE_TIMERS=y CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" # CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set # CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set @@ -1450,7 +1510,6 @@ CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 # # Port # -CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y # CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set @@ -1467,6 +1526,11 @@ CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set # end of Port +# +# Extra +# +# end of Extra + CONFIG_FREERTOS_PORT=y CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y @@ -1486,7 +1550,6 @@ CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y -# CONFIG_HAL_ECDSA_GEN_SIG_CM is not set # end of Hardware Abstraction Layer (HAL) and Low Level (LL) # @@ -1505,7 +1568,11 @@ CONFIG_HEAP_TRACING_OFF=y # end of Heap memory debugging # -# Log output +# Log +# + +# +# Log Level # CONFIG_LOG_DEFAULT_LEVEL_NONE=y # CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set @@ -1521,11 +1588,29 @@ CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y # CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set # CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set CONFIG_LOG_MAXIMUM_LEVEL=0 + +# +# Level Settings +# # CONFIG_LOG_MASTER_LEVEL is not set +CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y +# CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set +# CONFIG_LOG_TAG_LEVEL_IMPL_LINKED_LIST is not set +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_AND_LINKED_LIST=y +# CONFIG_LOG_TAG_LEVEL_CACHE_ARRAY is not set +CONFIG_LOG_TAG_LEVEL_CACHE_BINARY_MIN_HEAP=y +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 +# end of Level Settings +# end of Log Level + +# +# Format +# # CONFIG_LOG_COLORS is not set CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set -# end of Log output +# end of Format +# end of Log # # LWIP @@ -1564,6 +1649,8 @@ CONFIG_LWIP_ESP_MLDV6_REPORT=y CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set +# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set @@ -1578,6 +1665,7 @@ CONFIG_LWIP_DHCPS=y CONFIG_LWIP_DHCPS_LEASE_UNIT=60 CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y +CONFIG_LWIP_DHCPS_ADD_DNS=y # end of DHCP server # CONFIG_LWIP_AUTOIP is not set @@ -1636,12 +1724,12 @@ CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 # CONFIG_LWIP_PPP_SUPPORT is not set -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 # CONFIG_LWIP_SLIP_SUPPORT is not set # @@ -1815,6 +1903,8 @@ CONFIG_MBEDTLS_X509_CSR_PARSE_C=y # end of Certificates CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y +CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y # CONFIG_MBEDTLS_DHM_C is not set CONFIG_MBEDTLS_ECDH_C=y CONFIG_MBEDTLS_ECDSA_C=y @@ -1897,6 +1987,7 @@ CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_PATCH_VERSION=y # end of Protocomm # @@ -2069,6 +2160,8 @@ CONFIG_VFS_MAX_COUNT=8 # CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 # end of Host File System I/O (Semihosting) + +CONFIG_VFS_INITIALIZE_DEV_NULL=y # end of Virtual file system # @@ -2099,20 +2192,6 @@ CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_ZB_ENABLED is not set # end of Zigbee -# -# esp-modem -# -CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y -# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set -CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 -# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set -# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set -CONFIG_ESP_MODEM_C_API_STR_MAX=128 -# CONFIG_ESP_MODEM_URC_HANDLER is not set -# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set -# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set -# end of esp-modem - # # mDNS # From e9c8084b7a68346120e8ba392e4f3dd2326e5a20 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Fri, 27 Jun 2025 08:52:02 -0500 Subject: [PATCH 255/451] changed computation timeout and maintenance loop priority --- include/PowerTable_Helpers.h | 2 +- src/Main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/PowerTable_Helpers.h b/include/PowerTable_Helpers.h index f740bcce..b6d818d9 100644 --- a/include/PowerTable_Helpers.h +++ b/include/PowerTable_Helpers.h @@ -14,7 +14,7 @@ #define RETURN_ERROR INT32_MIN #define FREE_HEAP_FOR_COMPLEX_MATH 30000 -#define COMPUTATION_TIMEOUT_MS 50 +#define COMPUTATION_TIMEOUT_MS 25 class PowerEntry { public: diff --git a/src/Main.cpp b/src/Main.cpp index 92de8f73..3afce517 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -188,7 +188,7 @@ extern "C" void app_main() { "maintenanceLoopFunction", /* name of task. */ MAIN_STACK, /* Stack size of task */ NULL, /* parameter of the task */ - 2, /* priority of the task */ + 10, /* priority of the task */ &maintenanceLoopTask, /* Task handle to keep track of created task */ 0); /* pin task to core */ } From c8a5caca572f754b8210144943fbd4f967577cf7 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sun, 29 Jun 2025 19:06:09 -0500 Subject: [PATCH 256/451] updated connection params --- .gitignore | 1 + dependencies.lock | 13 +- include/BLE_Common.h | 8 + sdkconfig.release | 429 +++++++++++++++++++++++++++++++++++++++++++ src/BLE_Client.cpp | 4 +- 5 files changed, 452 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index ac2754f8..86f966d5 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ C/Users/ dependencies.lock .vscode/settings.json dependencies.lock +dependencies.lock diff --git a/dependencies.lock b/dependencies.lock index 3aef0ca5..17170be1 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -41,6 +41,16 @@ dependencies: registry_url: https://components.espressif.com/ type: service version: 1.6.3 + espressif/esp_modem: + component_hash: b541c3f5765d3ba062c0d004b9ca6da6d0af908293421c2dbe046c537fb2a011 + dependencies: + - name: idf + require: private + version: '>=4.1' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.4.0 espressif/mdns: component_hash: 3ec0af5f6bce310512e90f482388d21cc7c0e99668172d2f895356165fc6f7c5 dependencies: @@ -81,10 +91,11 @@ direct_dependencies: - espressif/cbor - espressif/esp-zboss-lib - espressif/esp-zigbee-lib +- espressif/esp_modem - espressif/mdns - espressif/network_provisioning - idf - joltwallet/littlefs -manifest_hash: cdea08c215af25ecb07f34a572afe529ccee1d11a022752ebfb3b54cbc0cb5f8 +manifest_hash: e871ea1e1aff9421b8e57e1c5a4db8daeef71b071a2a17f239e5feebc4acdfc3 target: esp32 version: 2.0.0 diff --git a/include/BLE_Common.h b/include/BLE_Common.h index e5686804..88fa5456 100644 --- a/include/BLE_Common.h +++ b/include/BLE_Common.h @@ -24,6 +24,14 @@ #define NOTIFY_DATA_QUEUE_SIZE 25 #define NOTIFY_DATA_QUEUE_LENGTH 10 + +// BLE Connection Parameters: +// minInterval – [in] The minimum connection interval in 1.25ms units. +// maxInterval – [in] The maximum connection interval in 1.25ms units. +// latency – [in] The number of packets allowed to skip (extends max interval). +// timeout – [in] The timeout time in 10ms units before disconnecting. +const uint16_t connectionParams[] = {24, 160, 1, 80}; + // Vector of supported BLE services and their corresponding characteristic UUIDs struct BLEServiceInfo { BLEUUID serviceUUID; diff --git a/sdkconfig.release b/sdkconfig.release index 7b3b88bf..a9f2dc38 100644 --- a/sdkconfig.release +++ b/sdkconfig.release @@ -259,9 +259,13 @@ CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y CONFIG_APP_BUILD_GENERATE_BINARIES=y CONFIG_APP_BUILD_BOOTLOADER=y CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# default: # CONFIG_APP_REPRODUCIBLE_BUILD is not set +# default: # CONFIG_APP_NO_BLOBS is not set +# default: # CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# default: # CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set # end of Build type @@ -296,6 +300,7 @@ CONFIG_BOOTLOADER_LOG_LEVEL=3 # # Format # +# default: # CONFIG_BOOTLOADER_LOG_COLORS is not set CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y # end of Format @@ -304,23 +309,32 @@ CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y # # Serial Flash Configurations # +# default: # CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y # end of Serial Flash Configurations # CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# default: # CONFIG_BOOTLOADER_FACTORY_RESET is not set +# default: # CONFIG_BOOTLOADER_APP_TEST is not set CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y CONFIG_BOOTLOADER_WDT_ENABLE=y +# default: # CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# default: # CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# default: # CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set # end of Bootloader config @@ -328,8 +342,11 @@ CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 # Security features # CONFIG_SECURE_BOOT_V1_SUPPORTED=y +# default: # CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# default: # CONFIG_SECURE_BOOT is not set +# default: # CONFIG_SECURE_FLASH_ENC_ENABLED is not set # end of Security features @@ -337,8 +354,11 @@ CONFIG_SECURE_BOOT_V1_SUPPORTED=y # Application manager # CONFIG_APP_COMPILE_TIME_DATE=y +# default: # CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# default: # CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# default: # CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 # end of Application manager @@ -361,6 +381,7 @@ CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y # # Serial flasher config # +# default: # CONFIG_ESPTOOLPY_NO_STUB is not set # CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set @@ -382,6 +403,7 @@ CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set CONFIG_ESPTOOLPY_FLASHSIZE="2MB" +# default: # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set @@ -411,6 +433,7 @@ CONFIG_PARTITION_TABLE_MD5=y # CONFIG_ARDUINO_VARIANT="esp32" CONFIG_ENABLE_ARDUINO_DEPENDS=y +# default: # CONFIG_AUTOSTART_ARDUINO is not set # CONFIG_ARDUINO_RUN_CORE0 is not set CONFIG_ARDUINO_RUN_CORE1=y @@ -432,7 +455,9 @@ CONFIG_ARDUINO_UDP_RUN_CORE0=y # CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set CONFIG_ARDUINO_UDP_RUNNING_CORE=0 CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 +# default: # CONFIG_ARDUINO_ISR_IRAM is not set +# default: # CONFIG_DISABLE_HAL_LOCKS is not set # @@ -445,7 +470,9 @@ CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE=y # CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set # CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=0 +# default: # CONFIG_ARDUHAL_LOG_COLORS is not set +# default: # CONFIG_ARDUHAL_ESP_LOG is not set # end of Debug Log Configuration @@ -460,17 +487,25 @@ CONFIG_ARDUINO_SELECTIVE_SPI=y CONFIG_ARDUINO_SELECTIVE_Wire=y CONFIG_ARDUINO_SELECTIVE_ESP_SR=y CONFIG_ARDUINO_SELECTIVE_EEPROM=y +# default: # CONFIG_ARDUINO_SELECTIVE_Preferences is not set +# default: # CONFIG_ARDUINO_SELECTIVE_Ticker is not set CONFIG_ARDUINO_SELECTIVE_Update=y +# default: # CONFIG_ARDUINO_SELECTIVE_Zigbee is not set CONFIG_ARDUINO_SELECTIVE_FS=y +# default: # CONFIG_ARDUINO_SELECTIVE_SD is not set +# default: # CONFIG_ARDUINO_SELECTIVE_SD_MMC is not set +# default: # CONFIG_ARDUINO_SELECTIVE_SPIFFS is not set +# default: # CONFIG_ARDUINO_SELECTIVE_FFat is not set CONFIG_ARDUINO_SELECTIVE_LittleFS=y CONFIG_ARDUINO_SELECTIVE_Network=y +# default: # CONFIG_ARDUINO_SELECTIVE_Ethernet is not set CONFIG_ARDUINO_SELECTIVE_PPP=y CONFIG_ARDUINO_SELECTIVE_ArduinoOTA=y @@ -478,17 +513,23 @@ CONFIG_ARDUINO_SELECTIVE_AsyncUDP=y CONFIG_ARDUINO_SELECTIVE_DNSServer=y CONFIG_ARDUINO_SELECTIVE_ESPmDNS=y CONFIG_ARDUINO_SELECTIVE_HTTPClient=y +# default: # CONFIG_ARDUINO_SELECTIVE_Matter is not set +# default: # CONFIG_ARDUINO_SELECTIVE_NetBIOS is not set CONFIG_ARDUINO_SELECTIVE_WebServer=y CONFIG_ARDUINO_SELECTIVE_WiFi=y CONFIG_ARDUINO_SELECTIVE_NetworkClientSecure=y CONFIG_ARDUINO_SELECTIVE_WiFiProv=y CONFIG_ARDUINO_SELECTIVE_BLE=y +# default: # CONFIG_ARDUINO_SELECTIVE_BluetoothSerial is not set CONFIG_ARDUINO_SELECTIVE_SimpleBLE=y +# default: # CONFIG_ARDUINO_SELECTIVE_RainMaker is not set +# default: # CONFIG_ARDUINO_SELECTIVE_OpenThread is not set +# default: # CONFIG_ARDUINO_SELECTIVE_Insights is not set # end of Arduino Configuration @@ -505,25 +546,35 @@ CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# default: # CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# default: # CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# default: # CONFIG_COMPILER_CXX_RTTI is not set CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set # CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set # CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# default: # CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set +# default: # CONFIG_COMPILER_WARN_WRITE_STRINGS is not set CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y +# default: # CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# default: # CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# default: # CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set +# default: # CONFIG_COMPILER_DUMP_RTL_FILES is not set CONFIG_COMPILER_RT_LIB_GCCLIB=y CONFIG_COMPILER_RT_LIB_NAME="gcc" CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y # CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set +# default: # CONFIG_COMPILER_STATIC_ANALYZER is not set # end of Compiler options @@ -576,10 +627,15 @@ CONFIG_BT_NIMBLE_ROLE_CENTRAL=y CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y CONFIG_BT_NIMBLE_ROLE_OBSERVER=y +# default: # CONFIG_BT_NIMBLE_NVS_PERSIST is not set +# default: # CONFIG_BT_NIMBLE_SMP_ID_RESET is not set +# default: # CONFIG_BT_NIMBLE_SECURITY_ENABLE is not set +# default: # CONFIG_BT_NIMBLE_DEBUG is not set +# default: # CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 @@ -607,16 +663,22 @@ CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 +# default: # CONFIG_BT_NIMBLE_MESH is not set CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 +# default: # CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set +# default: # CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set CONFIG_BT_NIMBLE_WHITELIST_SIZE=1 +# default: # CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set +# default: # CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set CONFIG_BT_NIMBLE_USE_ESP_TIMER=y CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y +# default: # CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set # @@ -626,6 +688,7 @@ CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y # # GAP Appearance write permissions # +# default: # CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set # end of GAP Appearance write permissions @@ -641,6 +704,7 @@ CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 # # GAP device name write permissions # +# default: # CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set # end of GAP device name write permissions @@ -652,33 +716,49 @@ CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 +# default: # CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL is not set # end of GAP Service # # BLE Services # +# default: # CONFIG_BT_NIMBLE_HID_SERVICE is not set +# default: # CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY is not set # # Device Information Service # +# default: # CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED is not set # end of Device Information Service # end of BLE Services +# default: # CONFIG_BT_NIMBLE_VS_SUPPORT is not set +# default: # CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set +# default: # CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set +# default: # CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set +# default: # CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT is not set # @@ -692,6 +772,7 @@ CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 # end of Host-controller Transport CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 +# default: # CONFIG_BT_NIMBLE_SUBRATE is not set # end of NimBLE Options @@ -734,9 +815,12 @@ CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y CONFIG_BTDM_SCAN_DUPL_TYPE=0 CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 +# default: # CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y +# default: # CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set +# default: # CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 @@ -745,12 +829,15 @@ CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # # BLE disconnects when Instant Passed (0x28) occurs # +# default: # CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set +# default: # CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set # end of BLE disconnects when Instant Passed (0x28) occurs CONFIG_BTDM_BLE_CHAN_ASS_EN=y CONFIG_BTDM_BLE_PING_EN=y +# default: # CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 is not set CONFIG_BTDM_RESERVE_DRAM=0xdb5c CONFIG_BTDM_CTRL_HLI=y @@ -760,17 +847,21 @@ CONFIG_BTDM_CTRL_HLI=y # Common Options # CONFIG_BT_ALARM_MAX_NUM=50 +# default: # CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set # end of Common Options +# default: # CONFIG_BT_HCI_LOG_DEBUG_EN is not set # end of Bluetooth +# default: # CONFIG_BLE_MESH is not set # # Console Library # +# default: # CONFIG_CONSOLE_SORTED_HELP is not set # end of Console Library @@ -781,6 +872,7 @@ CONFIG_BT_ALARM_MAX_NUM=50 # # TWAI Configuration # +# default: # CONFIG_TWAI_ISR_IN_IRAM is not set CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y @@ -793,7 +885,9 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # Legacy ADC Driver Configuration # CONFIG_ADC_DISABLE_DAC=y +# default: # CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set # @@ -802,6 +896,7 @@ CONFIG_ADC_DISABLE_DAC=y CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y CONFIG_ADC_CAL_LUT_ENABLE=y +# default: # CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set # end of Legacy ADC Calibration Configuration # end of Legacy ADC Driver Configuration @@ -809,49 +904,63 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # # Legacy DAC Driver Configurations # +# default: # CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy DAC Driver Configurations # # Legacy MCPWM Driver Configurations # +# default: # CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy MCPWM Driver Configurations # # Legacy Timer Group Driver Configurations # +# default: # CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Timer Group Driver Configurations # # Legacy RMT Driver Configurations # +# default: # CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy RMT Driver Configurations # # Legacy I2S Driver Configurations # +# default: # CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy I2S Driver Configurations # # Legacy PCNT Driver Configurations # +# default: # CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy PCNT Driver Configurations # # Legacy SDM Driver Configurations # +# default: # CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy SDM Driver Configurations # end of Driver Configurations @@ -859,7 +968,9 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # # eFuse Bit Manager # +# default: # CONFIG_EFUSE_CUSTOM_TABLE is not set +# default: # CONFIG_EFUSE_VIRTUAL is not set # CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y @@ -871,19 +982,28 @@ CONFIG_EFUSE_MAX_BLK_LEN=192 # ESP-TLS # CONFIG_ESP_TLS_USING_MBEDTLS=y +# default: # CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set +# default: # CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# default: # CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set +# default: # CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set +# default: # CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set +# default: # CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# default: # CONFIG_ESP_TLS_INSECURE is not set # end of ESP-TLS # # ADC and ADC Calibration # +# default: # CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set # @@ -895,6 +1015,7 @@ CONFIG_ADC_CALI_LUT_ENABLE=y # end of ADC Calibration Configurations CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# default: # CONFIG_ADC_ENABLE_DEBUG_LOG is not set # end of ADC and ADC Calibration @@ -903,7 +1024,9 @@ CONFIG_ADC_DISABLE_DAC_OUTPUT=y # CONFIG_ESP_COEX_ENABLED=y CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y +# default: # CONFIG_ESP_COEX_POWER_MANAGEMENT is not set +# default: # CONFIG_ESP_COEX_GPIO_DEBUG is not set # end of Wireless Coexistence @@ -916,8 +1039,11 @@ CONFIG_ESP_ERR_TO_NAME_LOOKUP=y # # ESP-Driver:DAC Configurations # +# default: # CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_DAC_ISR_IRAM_SAFE is not set +# default: # CONFIG_DAC_ENABLE_DEBUG_LOG is not set CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # end of ESP-Driver:DAC Configurations @@ -925,7 +1051,9 @@ CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # # ESP-Driver:GPIO Configurations # +# default: # CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set +# default: # CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:GPIO Configurations @@ -933,68 +1061,90 @@ CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # ESP-Driver:GPTimer Configurations # CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y +# default: # CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# default: # CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:GPTimer Configurations # # ESP-Driver:I2C Configurations # +# default: # CONFIG_I2C_ISR_IRAM_SAFE is not set +# default: # CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# default: # CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set # end of ESP-Driver:I2C Configurations # # ESP-Driver:I2S Configurations # +# default: # CONFIG_I2S_ISR_IRAM_SAFE is not set +# default: # CONFIG_I2S_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:I2S Configurations # # ESP-Driver:LEDC Configurations # +# default: # CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:LEDC Configurations # # ESP-Driver:MCPWM Configurations # +# default: # CONFIG_MCPWM_ISR_IRAM_SAFE is not set +# default: # CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:MCPWM Configurations # # ESP-Driver:PCNT Configurations # +# default: # CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_PCNT_ISR_IRAM_SAFE is not set +# default: # CONFIG_PCNT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:PCNT Configurations # # ESP-Driver:RMT Configurations # +# default: # CONFIG_RMT_ISR_IRAM_SAFE is not set +# default: # CONFIG_RMT_RECV_FUNC_IN_IRAM is not set +# default: # CONFIG_RMT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:RMT Configurations # # ESP-Driver:Sigma Delta Modulator Configurations # +# default: # CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_SDM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Sigma Delta Modulator Configurations # # ESP-Driver:SPI Configurations # +# default: # CONFIG_SPI_MASTER_IN_IRAM is not set CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# default: # CONFIG_SPI_SLAVE_IN_IRAM is not set CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # end of ESP-Driver:SPI Configurations @@ -1002,28 +1152,36 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # # ESP-Driver:Touch Sensor Configurations # +# default: # CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_TOUCH_ISR_IRAM_SAFE is not set +# default: # CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Touch Sensor Configurations # # ESP-Driver:UART Configurations # +# default: # CONFIG_UART_ISR_IN_IRAM is not set # end of ESP-Driver:UART Configurations # # Ethernet # +# default: # CONFIG_ETH_USE_ESP32_EMAC is not set +# default: # CONFIG_ETH_USE_SPI_ETHERNET is not set +# default: # CONFIG_ETH_USE_OPENETH is not set # end of Ethernet # # Event Loop Library # +# default: # CONFIG_ESP_EVENT_LOOP_PROFILING is not set CONFIG_ESP_EVENT_POST_FROM_ISR=y CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y @@ -1033,6 +1191,7 @@ CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y # GDB Stub # CONFIG_ESP_GDBSTUB_ENABLED=y +# default: # CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y CONFIG_ESP_GDBSTUB_MAX_TASKS=32 @@ -1049,8 +1208,11 @@ CONFIG_ESPHID_TASK_SIZE_BLE=4096 # ESP HTTP client # CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 # end of ESP HTTP client @@ -1062,8 +1224,11 @@ CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 CONFIG_HTTPD_MAX_URI_LEN=512 CONFIG_HTTPD_ERR_RESP_NO_DELAY=y CONFIG_HTTPD_PURGE_BUF_LEN=32 +# default: # CONFIG_HTTPD_LOG_PURGE_DATA is not set +# default: # CONFIG_HTTPD_WS_SUPPORT is not set +# default: # CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # end of HTTP Server @@ -1071,7 +1236,9 @@ CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # # ESP HTTPS OTA # +# default: # CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# default: # CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS OTA @@ -1079,6 +1246,7 @@ CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # # ESP HTTPS server # +# default: # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS server @@ -1125,20 +1293,27 @@ CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 # CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 +# default: # CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set +# default: # CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set # end of MAC Config # # Sleep Config # +# default: # CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +# default: # CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# default: # CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 +# default: # CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set +# default: # CONFIG_ESP_SLEEP_DEBUG is not set CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y # end of Sleep Config @@ -1175,6 +1350,7 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # # ESP-Driver:LCD Controller Configurations # +# default: # CONFIG_LCD_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:LCD Controller Configurations @@ -1187,14 +1363,19 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # ESP NETIF Adapter # CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +# default: # CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set CONFIG_ESP_NETIF_TCPIP_LWIP=y # CONFIG_ESP_NETIF_LOOPBACK is not set CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y +# default: # CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# default: # CONFIG_ESP_NETIF_L2_TAP is not set +# default: # CONFIG_ESP_NETIF_BRIDGE_EN is not set +# default: # CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set # end of ESP NETIF Adapter @@ -1208,35 +1389,44 @@ CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y # CONFIG_ESP_PHY_ENABLED=y CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# default: # CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP_PHY_MAX_TX_POWER=20 +# default: # CONFIG_ESP_PHY_REDUCE_TX_POWER is not set +# default: # CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set CONFIG_ESP_PHY_RF_CAL_PARTIAL=y # CONFIG_ESP_PHY_RF_CAL_NONE is not set # CONFIG_ESP_PHY_RF_CAL_FULL is not set CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# default: # CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# default: # CONFIG_ESP_PHY_RECORD_USED_TIME is not set # end of PHY # # Power Management # +# default: # CONFIG_PM_ENABLE is not set +# default: # CONFIG_PM_SLP_IRAM_OPT is not set # end of Power Management # # ESP PSRAM # +# default: # CONFIG_SPIRAM is not set # end of ESP PSRAM # # ESP Ringbuf # +# default: # CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set # end of ESP Ringbuf @@ -1256,11 +1446,13 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 # # Memory # +# default: # CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set # # Non-backward compatible options # +# default: # CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set # end of Non-backward compatible options # end of Memory @@ -1268,6 +1460,7 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 # # Trace memory # +# default: # CONFIG_ESP32_TRAX is not set CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 # end of Trace memory @@ -1303,11 +1496,14 @@ CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 CONFIG_ESP_INT_WDT_CHECK_CPU1=y CONFIG_ESP_TASK_WDT_EN=y CONFIG_ESP_TASK_WDT_INIT=y +# default: # CONFIG_ESP_TASK_WDT_PANIC is not set CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# default: # CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# default: # CONFIG_ESP_DEBUG_STUBS_ENABLE is not set CONFIG_ESP_DEBUG_OCDAWARE=y CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y @@ -1327,6 +1523,7 @@ CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y CONFIG_ESP_BROWNOUT_DET_LVL=0 # end of Brownout Detector +# default: # CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y # end of ESP System Settings @@ -1342,15 +1539,18 @@ CONFIG_ESP_IPC_ISR_ENABLE=y # # ESP Timer (High Resolution Timer) # +# default: # CONFIG_ESP_TIMER_PROFILING is not set CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# default: # CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# default: # CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set CONFIG_ESP_TIMER_IMPL_TG0_LAC=y # end of ESP Timer (High Resolution Timer) @@ -1369,6 +1569,7 @@ CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y # CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 +# default: # CONFIG_ESP_WIFI_CSI_ENABLED is not set CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP_WIFI_TX_BA_WIN=6 @@ -1379,13 +1580,17 @@ CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +# default: # CONFIG_ESP_WIFI_IRAM_OPT is not set +# default: # CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set +# default: # CONFIG_ESP_WIFI_RX_IRAM_OPT is not set CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y CONFIG_ESP_WIFI_ENABLE_SAE_PK=y CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# default: # CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 @@ -1393,28 +1598,41 @@ CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y CONFIG_ESP_WIFI_GMAC_SUPPORT=y CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# default: # CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# default: # CONFIG_ESP_WIFI_NAN_ENABLE is not set CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# default: # CONFIG_ESP_WIFI_WAPI_PSK is not set +# default: # CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_11R_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set # # WPS Configuration Options # +# default: # CONFIG_ESP_WIFI_WPS_STRICT is not set +# default: # CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set # end of WPS Configuration Options +# default: # CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# default: # CONFIG_ESP_WIFI_TESTING_OPTIONS is not set CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y +# default: # CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set # end of Wi-Fi @@ -1461,12 +1679,15 @@ CONFIG_FATFS_CODEPAGE=437 CONFIG_FATFS_FS_LOCK=0 CONFIG_FATFS_TIMEOUT_MS=10000 CONFIG_FATFS_PER_FILE_CACHE=y +# default: # CONFIG_FATFS_USE_FASTSEEK is not set CONFIG_FATFS_USE_STRFUNC_NONE=y # CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set # CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# default: # CONFIG_FATFS_IMMEDIATE_FSYNC is not set +# default: # CONFIG_FATFS_USE_LABEL is not set CONFIG_FATFS_LINK_LOCK=y # end of FAT Filesystem support @@ -1478,7 +1699,9 @@ CONFIG_FATFS_LINK_LOCK=y # # Kernel # +# default: # CONFIG_FREERTOS_SMP is not set +# default: # CONFIG_FREERTOS_UNICORE is not set CONFIG_FREERTOS_HZ=1000 # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set @@ -1486,9 +1709,12 @@ CONFIG_FREERTOS_HZ=1000 CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +# default: # CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# default: # CONFIG_FREERTOS_USE_TICK_HOOK is not set CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# default: # CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set CONFIG_FREERTOS_USE_TIMERS=y CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" @@ -1501,28 +1727,38 @@ CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# default: # CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# default: # CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set +# default: # CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# default: # CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set # end of Kernel # # Port # +# default: # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# default: # CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set +# default: # CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y CONFIG_FREERTOS_ISR_STACKSIZE=1536 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# default: # CONFIG_FREERTOS_FPU_IN_ISR is not set CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y CONFIG_FREERTOS_CORETIMER_0=y # CONFIG_FREERTOS_CORETIMER_1 is not set CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# default: # CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +# default: # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set # end of Port @@ -1561,9 +1797,13 @@ CONFIG_HEAP_POISONING_DISABLED=y CONFIG_HEAP_TRACING_OFF=y # CONFIG_HEAP_TRACING_STANDALONE is not set # CONFIG_HEAP_TRACING_TOHOST is not set +# default: # CONFIG_HEAP_USE_HOOKS is not set +# default: # CONFIG_HEAP_TASK_TRACKING is not set +# default: # CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# default: # CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set # end of Heap memory debugging @@ -1592,6 +1832,7 @@ CONFIG_LOG_MAXIMUM_LEVEL=0 # # Level Settings # +# default: # CONFIG_LOG_MASTER_LEVEL is not set CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y # CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set @@ -1606,6 +1847,7 @@ CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 # # Format # +# default: # CONFIG_LOG_COLORS is not set CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set @@ -1617,31 +1859,45 @@ CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LWIP_ENABLE=y CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# default: # CONFIG_LWIP_NETIF_API is not set CONFIG_LWIP_TCPIP_TASK_PRIO=18 +# default: # CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# default: # CONFIG_LWIP_CHECK_THREAD_SAFETY is not set CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# default: # CONFIG_LWIP_L2_TO_L3_COPY is not set +# default: # CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# default: # CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set CONFIG_LWIP_TIMERS_ONDEMAND=y CONFIG_LWIP_ND6=y +# default: # CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set CONFIG_LWIP_MAX_SOCKETS=10 +# default: # CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# default: # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y CONFIG_LWIP_SO_RCVBUF=y +# default: # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP_DEFAULT_TTL=64 CONFIG_LWIP_IP4_FRAG=y CONFIG_LWIP_IP6_FRAG=y +# default: # CONFIG_LWIP_IP4_REASSEMBLY is not set +# default: # CONFIG_LWIP_IP6_REASSEMBLY is not set CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# default: # CONFIG_LWIP_IP_FORWARD is not set +# default: # CONFIG_LWIP_STATS is not set CONFIG_LWIP_ESP_GRATUITOUS_ARP=y CONFIG_LWIP_GARP_TMR_INTERVAL=60 @@ -1651,8 +1907,10 @@ CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y # CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set # CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set +# default: # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# default: # CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set CONFIG_LWIP_DHCP_OPTIONS_LEN=68 CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 @@ -1668,12 +1926,16 @@ CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y CONFIG_LWIP_DHCPS_ADD_DNS=y # end of DHCP server +# default: # CONFIG_LWIP_AUTOIP is not set CONFIG_LWIP_IPV4=y CONFIG_LWIP_IPV6=y +# default: # CONFIG_LWIP_IPV6_AUTOCONFIG is not set CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# default: # CONFIG_LWIP_IPV6_FORWARD is not set +# default: # CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set CONFIG_LWIP_NETIF_LOOPBACK=y CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 @@ -1697,6 +1959,7 @@ CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 CONFIG_LWIP_TCP_QUEUE_OOSEQ=y CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 +# default: # CONFIG_LWIP_TCP_SACK_OUT is not set CONFIG_LWIP_TCP_OVERSIZE_MSS=y # CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set @@ -1714,7 +1977,9 @@ CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 # # Checksums # +# default: # CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# default: # CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums @@ -1729,14 +1994,18 @@ CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 +# default: # CONFIG_LWIP_PPP_SUPPORT is not set +# default: # CONFIG_LWIP_SLIP_SUPPORT is not set # # ICMP # CONFIG_LWIP_ICMP=y +# default: # CONFIG_LWIP_MULTICAST_PING is not set +# default: # CONFIG_LWIP_BROADCAST_PING is not set # end of ICMP @@ -1750,6 +2019,7 @@ CONFIG_LWIP_MAX_RAW_PCBS=16 # SNTP # CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# default: # CONFIG_LWIP_DHCP_GET_NTP_SRV is not set CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 CONFIG_LWIP_SNTP_STARTUP_DELAY=y @@ -1761,7 +2031,9 @@ CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 # CONFIG_LWIP_DNS_MAX_HOST_IP=1 CONFIG_LWIP_DNS_MAX_SERVERS=3 +# default: # CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set +# default: # CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set # end of DNS @@ -1793,6 +2065,7 @@ CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y # CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set # end of Hooks +# default: # CONFIG_LWIP_DEBUG is not set # end of LWIP @@ -1805,15 +2078,21 @@ CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# default: # CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# default: # CONFIG_MBEDTLS_DEBUG is not set # # mbedTLS v3.x related # +# default: # CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set +# default: # CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# default: # CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# default: # CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y CONFIG_MBEDTLS_PKCS7_C=y @@ -1826,26 +2105,35 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# default: # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# default: # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 # end of Certificate Bundle +# default: # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set CONFIG_MBEDTLS_CMAC_C=y CONFIG_MBEDTLS_HARDWARE_AES=y CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y CONFIG_MBEDTLS_HARDWARE_MPI=y +# default: # CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set CONFIG_MBEDTLS_HARDWARE_SHA=y CONFIG_MBEDTLS_ROM_MD5=y +# default: # CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# default: # CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set CONFIG_MBEDTLS_HAVE_TIME=y +# default: # CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set +# default: # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y CONFIG_MBEDTLS_SHA512_C=y +# default: # CONFIG_MBEDTLS_SHA3_C is not set CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y # CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set @@ -1872,7 +2160,9 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y CONFIG_MBEDTLS_SSL_RENEGOTIATION=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# default: # CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# default: # CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set CONFIG_MBEDTLS_SSL_ALPN=y CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y @@ -1882,15 +2172,21 @@ CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y # Symmetric Ciphers # CONFIG_MBEDTLS_AES_C=y +# default: # CONFIG_MBEDTLS_CAMELLIA_C is not set +# default: # CONFIG_MBEDTLS_DES_C is not set +# default: # CONFIG_MBEDTLS_BLOWFISH_C is not set +# default: # CONFIG_MBEDTLS_XTEA_C is not set CONFIG_MBEDTLS_CCM_C=y CONFIG_MBEDTLS_GCM_C=y +# default: # CONFIG_MBEDTLS_NIST_KW_C is not set # end of Symmetric Ciphers +# default: # CONFIG_MBEDTLS_RIPEMD160_C is not set # @@ -1905,9 +2201,11 @@ CONFIG_MBEDTLS_X509_CSR_PARSE_C=y CONFIG_MBEDTLS_ECP_C=y CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y +# default: # CONFIG_MBEDTLS_DHM_C is not set CONFIG_MBEDTLS_ECDH_C=y CONFIG_MBEDTLS_ECDSA_C=y +# default: # CONFIG_MBEDTLS_ECJPAKE_C is not set CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y @@ -1922,10 +2220,15 @@ CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# default: # CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set +# default: # CONFIG_MBEDTLS_POLY1305_C is not set +# default: # CONFIG_MBEDTLS_CHACHA20_C is not set +# default: # CONFIG_MBEDTLS_HKDF_C is not set +# default: # CONFIG_MBEDTLS_THREADING_C is not set CONFIG_MBEDTLS_ERROR_STRINGS=y CONFIG_MBEDTLS_FS_IO=y @@ -1934,15 +2237,25 @@ CONFIG_MBEDTLS_FS_IO=y # # ESP-MQTT Configurations # +# default: # CONFIG_MQTT_PROTOCOL_311 is not set +# default: # CONFIG_MQTT_PROTOCOL_5 is not set +# default: # CONFIG_MQTT_TRANSPORT_SSL is not set +# default: # CONFIG_MQTT_TRANSPORT_WEBSOCKET is not set +# default: # CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# default: # CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# default: # CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# default: # CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# default: # CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# default: # CONFIG_MQTT_CUSTOM_OUTBOX is not set # end of ESP-MQTT Configurations @@ -1955,6 +2268,7 @@ CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y # CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set # CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# default: # CONFIG_NEWLIB_NANO_FORMAT is not set CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y # CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set @@ -1965,18 +2279,22 @@ CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y # # NVS # +# default: # CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# default: # CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set # end of NVS # # OpenThread # +# default: # CONFIG_OPENTHREAD_ENABLED is not set # # OpenThread Spinel # +# default: # CONFIG_OPENTHREAD_SPINEL_ONLY is not set # end of OpenThread Spinel # end of OpenThread @@ -2030,6 +2348,7 @@ CONFIG_SPI_FLASH_BROWNOUT_RESET=y # Features here require specific hardware (READ DOCS FIRST!) # CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 +# default: # CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set # end of Optional and Experimental Features (READ DOCS FIRST) # end of Main Flash configuration @@ -2037,20 +2356,27 @@ CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 # # SPI Flash driver # +# default: # CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# default: # CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y # CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set # CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# default: # CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set +# default: # CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# default: # CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# default: # CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# default: # CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set # @@ -2065,7 +2391,9 @@ CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +# default: # CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# default: # CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set # end of Auto-detect flash chips @@ -2082,14 +2410,17 @@ CONFIG_SPIFFS_MAX_PARTITIONS=3 # CONFIG_SPIFFS_CACHE=y CONFIG_SPIFFS_CACHE_WR=y +# default: # CONFIG_SPIFFS_CACHE_STATS is not set # end of SPIFFS Cache Configuration CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 +# default: # CONFIG_SPIFFS_GC_STATS is not set CONFIG_SPIFFS_PAGE_SIZE=256 CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# default: # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y @@ -2099,11 +2430,17 @@ CONFIG_SPIFFS_USE_MTIME=y # # Debug Configuration # +# default: # CONFIG_SPIFFS_DBG is not set +# default: # CONFIG_SPIFFS_API_DBG is not set +# default: # CONFIG_SPIFFS_GC_DBG is not set +# default: # CONFIG_SPIFFS_CACHE_DBG is not set +# default: # CONFIG_SPIFFS_CHECK_DBG is not set +# default: # CONFIG_SPIFFS_TEST_VISUALISATION is not set # end of Debug Configuration # end of SPIFFS Configuration @@ -2117,6 +2454,7 @@ CONFIG_SPIFFS_USE_MTIME=y # CONFIG_WS_TRANSPORT=y CONFIG_WS_BUFFER_SIZE=1024 +# default: # CONFIG_WS_DYNAMIC_BUFFER is not set # end of Websocket # end of TCP Transport @@ -2124,6 +2462,7 @@ CONFIG_WS_BUFFER_SIZE=1024 # # Ultra Low Power (ULP) Co-processor # +# default: # CONFIG_ULP_COPROC_ENABLED is not set # @@ -2137,10 +2476,14 @@ CONFIG_WS_BUFFER_SIZE=1024 # CONFIG_UNITY_ENABLE_FLOAT=y CONFIG_UNITY_ENABLE_DOUBLE=y +# default: # CONFIG_UNITY_ENABLE_64BIT is not set +# default: # CONFIG_UNITY_ENABLE_COLOR is not set CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# default: # CONFIG_UNITY_ENABLE_FIXTURE is not set +# default: # CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set # end of Unity unit testing library @@ -2151,6 +2494,7 @@ CONFIG_VFS_SUPPORT_IO=y CONFIG_VFS_SUPPORT_DIR=y CONFIG_VFS_SUPPORT_SELECT=y CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +# default: # CONFIG_VFS_SELECT_IN_RAM is not set CONFIG_VFS_SUPPORT_TERMIOS=y CONFIG_VFS_MAX_COUNT=8 @@ -2177,10 +2521,14 @@ CONFIG_WL_SECTOR_SIZE=4096 # CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# default: # CONFIG_WIFI_PROV_BLE_BONDING is not set CONFIG_WIFI_PROV_BLE_SEC_CONN=y +# default: # CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set +# default: # CONFIG_WIFI_PROV_BLE_NOTIFY is not set +# default: # CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set @@ -2189,9 +2537,33 @@ CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # # Zigbee # +# default: # CONFIG_ZB_ENABLED is not set # end of Zigbee +# +# esp-modem +# +# default: +CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y +# default: +# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set +# default: +CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 +# default: +# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set +# default: +# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set +# default: +CONFIG_ESP_MODEM_C_API_STR_MAX=128 +# default: +# CONFIG_ESP_MODEM_URC_HANDLER is not set +# default: +# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set +# default: +# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set +# end of esp-modem + # # mDNS # @@ -2210,15 +2582,20 @@ CONFIG_MDNS_TASK_AFFINITY=0x0 # CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y +# default: # CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set # end of MDNS Memory Configuration CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 CONFIG_MDNS_TIMER_PERIOD_MS=100 +# default: # CONFIG_MDNS_NETWORKING_SOCKET is not set +# default: # CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set +# default: # CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set CONFIG_MDNS_ENABLE_CONSOLE_CLI=y +# default: # CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set CONFIG_MDNS_MULTIPLE_INSTANCE=y @@ -2236,9 +2613,12 @@ CONFIG_MDNS_PREDEF_NETIF_AP=y CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 +# default: # CONFIG_NETWORK_PROV_BLE_BONDING is not set CONFIG_NETWORK_PROV_BLE_SEC_CONN=y +# default: # CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set +# default: # CONFIG_NETWORK_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y # CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set @@ -2247,6 +2627,7 @@ CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y # # LittleFS # +# default: # CONFIG_LITTLEFS_SDMMC_SUPPORT is not set CONFIG_LITTLEFS_MAX_PARTITIONS=3 CONFIG_LITTLEFS_PAGE_SIZE=256 @@ -2257,29 +2638,41 @@ CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 CONFIG_LITTLEFS_CACHE_SIZE=512 CONFIG_LITTLEFS_BLOCK_CYCLES=512 CONFIG_LITTLEFS_USE_MTIME=y +# default: # CONFIG_LITTLEFS_USE_ONLY_HASH is not set +# default: # CONFIG_LITTLEFS_HUMAN_READABLE is not set CONFIG_LITTLEFS_MTIME_USE_SECONDS=y # CONFIG_LITTLEFS_MTIME_USE_NONCE is not set +# default: # CONFIG_LITTLEFS_SPIFFS_COMPAT is not set +# default: # CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set +# default: # CONFIG_LITTLEFS_FCNTL_GET_PATH is not set +# default: # CONFIG_LITTLEFS_MULTIVERSION is not set # CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y # CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set CONFIG_LITTLEFS_ASSERTS=y +# default: # CONFIG_LITTLEFS_MMAP_PARTITION is not set # end of LittleFS # end of Component config +# default: # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set # Deprecated options for backward compatibility # CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# default: # CONFIG_NO_BLOBS is not set +# default: # CONFIG_ESP32_NO_BLOBS is not set +# default: # CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# default: # CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set # CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set # CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set @@ -2288,7 +2681,9 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y # CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set # CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set CONFIG_LOG_BOOTLOADER_LEVEL=3 +# default: # CONFIG_APP_ROLLBACK_ENABLE is not set +# default: # CONFIG_FLASH_ENCRYPTION_ENABLED is not set # CONFIG_FLASHMODE_QIO is not set # CONFIG_FLASHMODE_QOUT is not set @@ -2304,11 +2699,13 @@ CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y # CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set # CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# default: # CONFIG_CXX_EXCEPTIONS is not set CONFIG_STACK_CHECK_NONE=y # CONFIG_STACK_CHECK_NORM is not set # CONFIG_STACK_CHECK_STRONG is not set # CONFIG_STACK_CHECK_ALL is not set +# default: # CONFIG_WARN_WRITE_STRINGS is not set # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set CONFIG_ESP32_APPTRACE_DEST_NONE=y @@ -2330,7 +2727,9 @@ CONFIG_NIMBLE_ROLE_CENTRAL=y CONFIG_NIMBLE_ROLE_PERIPHERAL=y CONFIG_NIMBLE_ROLE_BROADCASTER=y CONFIG_NIMBLE_ROLE_OBSERVER=y +# default: # CONFIG_NIMBLE_NVS_PERSIST is not set +# default: # CONFIG_NIMBLE_DEBUG is not set CONFIG_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" CONFIG_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 @@ -2347,6 +2746,7 @@ CONFIG_NIMBLE_HS_FLOW_CTRL_ITVL=1000 CONFIG_NIMBLE_HS_FLOW_CTRL_THRESH=2 CONFIG_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y CONFIG_NIMBLE_RPA_TIMEOUT=900 +# default: # CONFIG_NIMBLE_MESH is not set CONFIG_NIMBLE_CRYPTO_STACK_MBEDTLS=y CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y @@ -2366,6 +2766,7 @@ CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y # CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR is not set CONFIG_SCAN_DUPLICATE_TYPE=0 CONFIG_DUPLICATE_SCAN_CACHE_SIZE=100 +# default: # CONFIG_BLE_MESH_SCAN_DUPLICATE_EN is not set CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED=y @@ -2375,16 +2776,20 @@ CONFIG_ADC2_DISABLE_DAC=y CONFIG_SW_COEXIST_ENABLE=y CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y +# default: # CONFIG_MCPWM_ISR_IN_IRAM is not set +# default: # CONFIG_EVENT_LOOP_PROFILING is not set CONFIG_POST_EVENTS_FROM_ISR=y CONFIG_POST_EVENTS_FROM_IRAM_ISR=y CONFIG_GDBSTUB_SUPPORT_TASKS=y CONFIG_GDBSTUB_MAX_TASKS=32 +# default: # CONFIG_OTA_ALLOW_HTTP is not set # CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 +# default: # CONFIG_ESP_SYSTEM_PD_FLASH is not set CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 @@ -2402,12 +2807,17 @@ CONFIG_ESP32_XTAL_FREQ_40=y # CONFIG_ESP32_XTAL_FREQ_AUTO is not set CONFIG_ESP32_XTAL_FREQ=40 CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# default: # CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# default: # CONFIG_REDUCE_PHY_TX_POWER is not set +# default: # CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set +# default: # CONFIG_SPIRAM_SUPPORT is not set +# default: # CONFIG_ESP32_SPIRAM_SUPPORT is not set # CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y @@ -2433,10 +2843,12 @@ CONFIG_INT_WDT_TIMEOUT_MS=300 CONFIG_INT_WDT_CHECK_CPU1=y CONFIG_TASK_WDT=y CONFIG_ESP_TASK_WDT=y +# default: # CONFIG_TASK_WDT_PANIC is not set CONFIG_TASK_WDT_TIMEOUT_S=5 CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# default: # CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set CONFIG_ESP32_DEBUG_OCDAWARE=y CONFIG_BROWNOUT_DET=y @@ -2459,6 +2871,7 @@ CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set CONFIG_BROWNOUT_DET_LVL=0 CONFIG_ESP32_BROWNOUT_DET_LVL=0 +# default: # CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set CONFIG_IPC_TASK_STACK_SIZE=1024 CONFIG_TIMER_TASK_STACK_SIZE=3584 @@ -2469,6 +2882,7 @@ CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# default: # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP32_WIFI_TX_BA_WIN=6 @@ -2479,20 +2893,31 @@ CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +# default: # CONFIG_ESP32_WIFI_IRAM_OPT is not set +# default: # CONFIG_ESP32_WIFI_RX_IRAM_OPT is not set CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y CONFIG_WPA_MBEDTLS_CRYPTO=y CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# default: # CONFIG_WPA_WAPI_PSK is not set +# default: # CONFIG_WPA_11KV_SUPPORT is not set +# default: # CONFIG_WPA_MBO_SUPPORT is not set +# default: # CONFIG_WPA_DPP_SUPPORT is not set +# default: # CONFIG_WPA_11R_SUPPORT is not set +# default: # CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set +# default: # CONFIG_WPA_WPS_STRICT is not set +# default: # CONFIG_WPA_DEBUG_PRINT is not set +# default: # CONFIG_WPA_TESTING_OPTIONS is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set @@ -2500,8 +2925,10 @@ CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y CONFIG_TIMER_TASK_PRIORITY=1 CONFIG_TIMER_TASK_STACK_DEPTH=2048 CONFIG_TIMER_QUEUE_LENGTH=10 +# default: # CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set # CONFIG_HAL_ASSERTION_SILIENT is not set +# default: # CONFIG_L2_TO_L3_COPY is not set CONFIG_ESP_GRATUITOUS_ARP=y CONFIG_GARP_TMR_INTERVAL=60 @@ -2523,6 +2950,7 @@ CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set # CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# default: # CONFIG_PPP_SUPPORT is not set CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y @@ -2541,6 +2969,7 @@ CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +# default: # CONFIG_ESP32_ULP_COPROC_ENABLED is not set CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index 8506d251..3ddc517c 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -257,7 +257,7 @@ bool SpinBLEClient::connectToServer() { pClient = NimBLEDevice::getClientByPeerAddress(myDevice->getAddress()); if (pClient) { pClient->setConnectTimeout(10000); - pClient->setConnectionParams(24, 96, 1, 500); + pClient->setConnectionParams(connectionParams[0], connectionParams[1], connectionParams[2], connectionParams[3]); SS2K_LOG(BLE_CLIENT_LOG_TAG, "Reusing Client"); if (!pClient->connect(myDevice)) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Reconnect failed "); @@ -299,7 +299,7 @@ bool SpinBLEClient::connectToServer() { * connections. Timeout should be a multiple of the interval, minimum is 100ms. * Min interval: 12 * 1.25ms = 15, Max interval: 12 * 1.25ms = 15, 0 latency, 51 * 10ms = 510ms timeout */ - pClient->setConnectionParams(24, 96, 1, 500); + pClient->setConnectionParams(connectionParams[0], connectionParams[1], connectionParams[2], connectionParams[3]); /** Set how long we are willing to wait for the connection to complete (seconds), default is 30. */ pClient->setConnectTimeout(5000); // 5 seconds From 250ec951f070392a41394fd67819239b2e142fdf Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 1 Jul 2025 19:50:41 -0500 Subject: [PATCH 257/451] fixed reboot on firmware update page load. Fixed BLE connections being slow to initiate --- include/BLE_Common.h | 18 ++-- include/settings.h | 14 +-- platformio.ini | 2 +- src/BLE_Client.cpp | 135 +++++++++++++++++----------- src/BLE_Common.cpp | 20 +++++ src/BLE_Fitness_Machine_Service.cpp | 4 +- src/BLE_Heart_Service.cpp | 11 --- src/HTTP_Server_Basic.cpp | 18 ++-- src/Main.cpp | 15 +--- src/SensorCollector.cpp | 4 +- 10 files changed, 131 insertions(+), 110 deletions(-) diff --git a/include/BLE_Common.h b/include/BLE_Common.h index 88fa5456..45bba514 100644 --- a/include/BLE_Common.h +++ b/include/BLE_Common.h @@ -16,7 +16,7 @@ #include #include "Main.h" #include "BLE_Definitions.h" -//#include "BLE_Wattbike_Service.h" +// #include "BLE_Wattbike_Service.h" #include "BLE_SB20_Service.h" #include "Constants.h" @@ -24,13 +24,12 @@ #define NOTIFY_DATA_QUEUE_SIZE 25 #define NOTIFY_DATA_QUEUE_LENGTH 10 - // BLE Connection Parameters: // minInterval – [in] The minimum connection interval in 1.25ms units. // maxInterval – [in] The maximum connection interval in 1.25ms units. // latency – [in] The number of packets allowed to skip (extends max interval). // timeout – [in] The timeout time in 10ms units before disconnecting. -const uint16_t connectionParams[] = {24, 160, 1, 80}; +const uint16_t connectionParams[] = {24, 168, 1, 200}; // Vector of supported BLE services and their corresponding characteristic UUIDs struct BLEServiceInfo { @@ -79,10 +78,10 @@ const BLEServiceInfo* getDeviceServiceInfo(const NimBLEAdvertisedDevice* adverti // *****************************Server**************************** class MyServerCallbacks : public NimBLEServerCallbacks { public: - void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo); - void onDisconnect(NimBLEServer* pServer); - void onMTUChange(uint16_t MTU, NimBLEConnInfo& connInfo); - bool onConnParamsUpdateRequest(uint16_t handle, const ble_gap_upd_params* params); + void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo); + void onDisconnect(NimBLEServer* pServer); + void onMTUChange(uint16_t MTU, NimBLEConnInfo& connInfo); + bool onConnParamsUpdateRequest(uint16_t handle, const ble_gap_upd_params* params); }; // TODO add the rest of the server to this class @@ -111,7 +110,7 @@ class MyCharacteristicCallbacks : public NimBLECharacteristicCallbacks { }; extern SpinBLEServer spinBLEServer; -//extern BLE_Wattbike_Service wattbikeService; +// extern BLE_Wattbike_Service wattbikeService; void startBLEServer(); void logCharacteristic(char* buffer, const size_t bufferCapacity, const byte* data, const size_t dataLength, const NimBLEUUID serviceUUID, const NimBLEUUID charUUID, @@ -174,7 +173,7 @@ class SpinBLEAdvertisedDevice { bool getPostConnected() { return isPostConnected; } void set(const NimBLEAdvertisedDevice* device, int id = BLE_HS_CONN_HANDLE_NONE, BLEUUID inServiceUUID = (uint16_t)0x0000, BLEUUID inCharUUID = (uint16_t)0x0000); void reset(bool resetAdvertisedDevice = true); - bool enqueueData(uint8_t *data, size_t length, NimBLEUUID serviceUUID, NimBLEUUID charUUID); + bool enqueueData(uint8_t* data, size_t length, NimBLEUUID serviceUUID, NimBLEUUID charUUID); NotifyData dequeueData(); }; @@ -189,7 +188,6 @@ class SpinBLEClient { boolean connectedSpeed = false; boolean connectedRemote = false; boolean doScan = false; - bool dontBlockScan = true; int intentionalDisconnect = 0; long int cscCumulativeCrankRev = 0; double cscLastCrankEvtTime = 0.0; diff --git a/include/settings.h b/include/settings.h index 5eab577e..9e8592f0 100644 --- a/include/settings.h +++ b/include/settings.h @@ -219,17 +219,21 @@ const char* const DEFAULT_PASSWORD = "password"; // loop speed for the Webserver #define WEBSERVER_DELAY 7 +// BLE Device Generic Names +constexpr const char* NONE = "none"; +constexpr const char* ANY = "any"; + // Name of default Power Meter. any connects to anything, none connects to // nothing. -#define CONNECTED_POWER_METER "none" +#define CONNECTED_POWER_METER NONE // Name of default heart monitor. any connects to anything, none connects to // nothing. -#define CONNECTED_HEART_MONITOR "none" +#define CONNECTED_HEART_MONITOR NONE // Name of default remote. any connects to anything, none connects to // nothing. -#define CONNECTED_REMOTE "none" +#define CONNECTED_REMOTE NONE // number of main loops the shifters need to be held before a BLE scan is // initiated. @@ -329,8 +333,8 @@ const char* const DEFAULT_PASSWORD = "password"; // Default homing sensitivity value #define DEFAULT_HOMING_SENSITIVITY 50 -// BLE automatic reconnect duration in milliseconds. Set this low to avoid interruption. -#define BLE_RECONNECT_SCAN_DURATION 1000 +// BLE automatic reconnect interval in milliseconds. +#define BLE_RECONNECT_SCAN_INTERVAL 5000 // Task Stack Sizes // In theory you can subtract whatever is left in the report from DEBUG_STACK for each task diff --git a/platformio.ini b/platformio.ini index 0414362f..79641cbc 100644 --- a/platformio.ini +++ b/platformio.ini @@ -66,7 +66,7 @@ build_flags = ;-D CONFIG_BT_NIMBLE_BLOCK_COUNT=20 -std=gnu++17 lib_deps = - https://github.com/h2zero/esp-nimble-cpp/ + https://github.com/doudar/esp-nimble-cpp/ https://github.com/teemuatlut/TMCStepper/archive/refs/tags/v0.7.3.zip https://github.com/bblanchon/ArduinoJson/archive/refs/tags/v7.3.1.zip ;https://github.com/gin66/FastAccelStepper/archive/refs/tags/0.31.2.zip diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index 3ddc517c..fd86d316 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -85,10 +85,11 @@ static void notifyCB(NimBLERemoteCharacteristic *pBLERemoteCharacteristic, uint8 * @param pClient Pointer to the NimBLEClient object representing the BLE client. * The client must be connected for the function to proceed. */ -void subscribeToAllNotifications(NimBLEClient *pClient) { +bool subscribeToAllNotifications(NimBLEClient *pClient) { + bool isSubscribed = false; if (!pClient || !pClient->isConnected()) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Client not connected for notifications"); - return; + return false; } for (const auto &service : BLEServices::SUPPORTED_SERVICES) { NimBLERemoteService *pSvc = pClient->getService(service.serviceUUID); @@ -100,6 +101,7 @@ void subscribeToAllNotifications(NimBLEClient *pClient) { if (pChr->canNotify() || pChr->canIndicate()) { if (pChr->canNotify() ? pChr->subscribe(true, notifyCB) : pChr->subscribe(false, notifyCB)) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Subscribed to %s %s handle: %d", service.name.c_str(), pChr->getUUID().toString().c_str(), pChr->getHandle()); + isSubscribed = true; } else { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to subscribe to %s %s", service.name.c_str(), pChr->getUUID().toString().c_str()); } @@ -108,6 +110,7 @@ void subscribeToAllNotifications(NimBLEClient *pClient) { } } } + return isSubscribed; } // BLE Client loop task. @@ -155,24 +158,23 @@ void bleClientTask(void *pvParameters) { } } } + while (ss2k->isUpdating) { // wait until the update is done + delay(100); + } } - // Scan for BLE devices that we should connect to this client - static unsigned long scanDelay = millis(); - if ((millis() - scanDelay) > BLE_RECONNECT_SCAN_DURATION) { - spinBLEClient.checkBLEReconnect(); - scanDelay = millis(); - } - - if (spinBLEClient.doScan && (!ss2k->isUpdating)) { - spinBLEClient.scanProcess(DEFAULT_SCAN_DURATION); - } - + // Post connect previously connected clients. This needs to be before connect, as it takes a while to complete the connection (let it loop once.) spinBLEClient.postConnect(); // Connect BLE Servers to this client for (int x = 0; x < NUM_BLE_DEVICES; x++) { if (spinBLEClient.myBLEDevices[x].doConnect == true && !ss2k->isUpdating) { + // stop in process scans + NimBLEScan *pBLEScan = NimBLEDevice::getScan(); + if (pBLEScan->isScanning()) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Stopping scan before connecting to device on slot %d ...", x); + pBLEScan->stop(); + } SS2K_LOG(BLE_CLIENT_LOG_TAG, "Connecting device on slot %d ...", x); if (spinBLEClient.connectToServer()) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "We are now connected to the BLE Server."); @@ -182,6 +184,16 @@ void bleClientTask(void *pvParameters) { } } + // Scan for BLE devices that we should connect to this client + static unsigned long scanDelay = millis(); + if ((millis() - scanDelay) > BLE_RECONNECT_SCAN_INTERVAL) { + spinBLEClient.checkBLEReconnect(); + if (spinBLEClient.doScan && (!ss2k->isUpdating)) { + spinBLEClient.scanProcess(DEFAULT_SCAN_DURATION); + } + scanDelay = millis(); + } + // Spin Down process for the Server. It's here because it needs to be non-blocking for the maintenance loop. // Checking for cadence also so that we don't home when nobody is around. if (spinBLEServer.spinDownFlag && rtConfig->cad.getValue()) { @@ -246,7 +258,17 @@ bool SpinBLEClient::connectToServer() { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Forming a connection to: %s", this->adevName2UniqueName(myDevice).c_str()); - NimBLEClient *pClient = nullptr; + NimBLEClient *pClient = nullptr; + auto handleFailedClientConnect = [&]() { + SS2K_LOG(BLE_CLIENT_LOG_TAG, " - Failed to connect client"); + /** Created a client but failed to connect, don't need to keep it as it has no data */ + spinBLEClient.myBLEDevices[device_number].reset(); + spinBLEClient.resetDevices(pClient); + pClient->deleteServices(); + NimBLEDevice::getScan()->erase(pClient->getPeerAddress()); + NimBLEDevice::deleteClient(pClient); + return false; + }; /** Check if we have a client we should reuse first **/ if (NimBLEDevice::getCreatedClientCount()) { @@ -257,18 +279,14 @@ bool SpinBLEClient::connectToServer() { pClient = NimBLEDevice::getClientByPeerAddress(myDevice->getAddress()); if (pClient) { pClient->setConnectTimeout(10000); - pClient->setConnectionParams(connectionParams[0], connectionParams[1], connectionParams[2], connectionParams[3]); + pClient->setConnectionParams(connectionParams[0], connectionParams[1], connectionParams[2], connectionParams[3] * 2); SS2K_LOG(BLE_CLIENT_LOG_TAG, "Reusing Client"); - if (!pClient->connect(myDevice)) { + if (!pClient->connect(myDevice, false, true, true)) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Reconnect failed "); this->reconnectTries--; SS2K_LOG(BLE_CLIENT_LOG_TAG, "%d left.", reconnectTries); if (reconnectTries < 1) { - spinBLEClient.myBLEDevices[device_number].reset(); - spinBLEClient.resetDevices(pClient); - pClient->deleteServices(); - NimBLEDevice::getScan()->erase(pClient->getPeerAddress()); - NimBLEDevice::deleteClient(pClient); + handleFailedClientConnect(); } return false; } @@ -299,23 +317,16 @@ bool SpinBLEClient::connectToServer() { * connections. Timeout should be a multiple of the interval, minimum is 100ms. * Min interval: 12 * 1.25ms = 15, Max interval: 12 * 1.25ms = 15, 0 latency, 51 * 10ms = 510ms timeout */ - pClient->setConnectionParams(connectionParams[0], connectionParams[1], connectionParams[2], connectionParams[3]); + pClient->setConnectionParams(connectionParams[0], connectionParams[1], connectionParams[2], connectionParams[3] * 2); /** Set how long we are willing to wait for the connection to complete (seconds), default is 30. */ pClient->setConnectTimeout(5000); // 5 seconds if (!pClient->connect(myDevice)) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, " - Failed to connect client"); - /** Created a client but failed to connect, don't need to keep it as it has no data */ - spinBLEClient.myBLEDevices[device_number].reset(); - pClient->deleteServices(); - NimBLEDevice::getScan()->erase(pClient->getPeerAddress()); - NimBLEDevice::deleteClient(pClient); - return false; + return handleFailedClientConnect(); } } SS2K_LOG(BLE_CLIENT_LOG_TAG, "Connected to: %s - %s RSSI %d", this->adevName2UniqueName(myDevice).c_str(), pClient->getPeerAddress().toString().c_str(), pClient->getRssi()); - if (serviceUUID == HID_SERVICE_UUID) { connectBLE_HID(pClient); this->reconnectTries = MAX_RECONNECT_TRIES; @@ -345,6 +356,7 @@ bool SpinBLEClient::connectToServer() { removeDuplicates(pClient); } else { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to find service: %s", serviceUUID.toString().c_str()); + return handleFailedClientConnect(); } SS2K_LOG(BLE_CLIENT_LOG_TAG, "Device Connected"); return true; @@ -356,7 +368,7 @@ bool SpinBLEClient::connectToServer() { void MyClientCallback::onConnect(NimBLEClient *pClient) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Connected, %s", pClient->getPeerAddress().toString().c_str()); } void MyClientCallback::onDisconnect(NimBLEClient *pClient, int reason) { - if (!pClient->isConnected()) { + if (!pClient->isConnected() && !ss2k->isUpdating) { NimBLEAddress addr = pClient->getPeerAddress(); SS2K_LOG(BLE_CLIENT_LOG_TAG, "Client %s Disconnected, reason = %d", addr.toString().c_str(), reason); for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { @@ -426,16 +438,16 @@ void ScanCallbacks::onResult(const NimBLEAdvertisedDevice *advertisedDevice) { const char *aDevAddr = advertisedDevice->getAddress().toString().c_str(); if (advertisedDevice->haveServiceUUID() && isDeviceSupported(advertisedDevice, aDevName)) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Trying to match found device name: %s", aDevName.c_str()); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Found Device: %s", aDevName.c_str()); // Handling for BLE connected remotes if (advertisedDevice->getServiceUUID() == HID_SERVICE_UUID) { - if (strcmp(userConfig->getConnectedRemote(), "any") == 0) { + if (strcmp(userConfig->getConnectedRemote(), ANY) == 0) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s", REMOTE, STRING_MATCHED_ANY); } else { bool nameMatched = (aDevName = userConfig->getConnectedRemote()) ? true : false; bool addrMatched = strcmp(aDevAddr, userConfig->getConnectedRemote()) == 0; - if (!nameMatched && !addrMatched || strcmp(userConfig->getConnectedRemote(), "none") == 0) { + if (!nameMatched && !addrMatched || strcmp(userConfig->getConnectedRemote(), NONE) == 0) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s%s%s", THIS, REMOTE, DIDNT_MATCH_THE_SAVED, userConfig->getConnectedRemote()); return; // Ignore this device; } else { @@ -443,12 +455,12 @@ void ScanCallbacks::onResult(const NimBLEAdvertisedDevice *advertisedDevice) { } } } else if (advertisedDevice->getServiceUUID() == HEARTSERVICE_UUID) { - if (strcmp(userConfig->getConnectedHeartMonitor(), "any") == 0) { + if (strcmp(userConfig->getConnectedHeartMonitor(), ANY) == 0) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s", HRM, STRING_MATCHED_ANY); } else { bool nameMatched = (aDevName == userConfig->getConnectedHeartMonitor()) ? true : false; bool addrMatched = strcmp(aDevAddr, userConfig->getConnectedHeartMonitor()) == 0; - if (!nameMatched && !addrMatched || strcmp(userConfig->getConnectedHeartMonitor(), "none") == 0) { + if (!nameMatched && !addrMatched || strcmp(userConfig->getConnectedHeartMonitor(), NONE) == 0) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s%s%s", THIS, HRM, DIDNT_MATCH_THE_SAVED, userConfig->getConnectedHeartMonitor()); return; // Ignore this device; } else { @@ -457,11 +469,11 @@ void ScanCallbacks::onResult(const NimBLEAdvertisedDevice *advertisedDevice) { } } else { // Power Meter - if (strcmp(userConfig->getConnectedPowerMeter(), "any") == 0) { + if (strcmp(userConfig->getConnectedPowerMeter(), ANY) == 0) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s", PM, STRING_MATCHED_ANY); } else { bool nameMatched = (aDevName == userConfig->getConnectedPowerMeter()) ? true : false; - if (!nameMatched || strcmp(userConfig->getConnectedPowerMeter(), "none") == 0) { + if (!nameMatched || strcmp(userConfig->getConnectedPowerMeter(), NONE) == 0) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s%s%s%s", THIS, PM, DIDNT_MATCH_THE_SAVED, userConfig->getConnectedPowerMeter()); return; // Ignore this device; } else { @@ -485,14 +497,16 @@ void ScanCallbacks::onResult(const NimBLEAdvertisedDevice *advertisedDevice) { void SpinBLEClient::scanProcess(int duration) { this->doScan = false; // Confirming we did the scan - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Scanning for BLE servers and putting them into a list..."); - NimBLEScan *pBLEScan = NimBLEDevice::getScan(); if (pBLEScan->isScanning()) { return; } - pBLEScan->start(duration, false, false); - this->dontBlockScan = false; + + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Scanning for BLE servers and putting them into a list..."); + pBLEScan->start(duration, false, true); + while (pBLEScan->isScanning()) { + delay(10); // Wait for the scan to finish + } } void ScanCallbacks::onScanEnd(const NimBLEScanResults &results, int reason) { @@ -626,9 +640,13 @@ void SpinBLEClient::postConnect() { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Post connecting: %s , ConnID %d, PrimaryChar %s", _BLEd.peerAddress.toString().c_str(), _BLEd.connectedClientID, _BLEd.charUUID.toString().c_str()); if (NimBLEDevice::getClientByPeerAddress(_BLEd.peerAddress)) { - _BLEd.setPostConnected(true); NimBLEClient *pClient = NimBLEDevice::getClientByPeerAddress(_BLEd.peerAddress); - subscribeToAllNotifications(pClient); + BLEDevice::getServer()->updateConnParams(pClient->getConnHandle(), connectionParams[0], connectionParams[1], connectionParams[2], connectionParams[3]); + _BLEd.setPostConnected(subscribeToAllNotifications(pClient)); + if (!_BLEd.getPostConnected()) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Failed to subscribe to notifications for %s", _BLEd.peerAddress.toString().c_str()); + return; + } if (_BLEd.charUUID == ECHELON_DATA_UUID) { NimBLERemoteCharacteristic *writeCharacteristic = pClient->getService(ECHELON_SERVICE_UUID)->getCharacteristic(ECHELON_WRITE_UUID); if (writeCharacteristic == nullptr) { @@ -646,7 +664,6 @@ void SpinBLEClient::postConnect() { if ((_BLEd.charUUID == FITNESSMACHINEINDOORBIKEDATA_UUID)) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Updating Connection Params for: %s", _BLEd.peerAddress.toString().c_str()); - BLEDevice::getServer()->updateConnParams(pClient->getConnHandle(), 100, 100, 2, 1000); spinBLEClient.handleBattInfo(pClient, true); auto featuresCharacteristic = pClient->getService(FITNESSMACHINESERVICE_UUID)->getCharacteristic(FITNESSMACHINEFEATURE_UUID); @@ -745,8 +762,8 @@ NotifyData SpinBLEAdvertisedDevice::dequeueData() { } void SpinBLEClient::connectBLE_HID(NimBLEClient *pClient) { - NimBLERemoteService *pSvc = nullptr; - pSvc = pClient->getService(HID_SERVICE_UUID); + NimBLERemoteService *pSvc = nullptr; + pSvc = pClient->getService(HID_SERVICE_UUID); if (pSvc) { /** make sure it's not null */ // This returns the HID report descriptor like this // HID_REPORT_MAP 0x2a4b Value: 5,1,9,2,A1,1,9,1,A1,0,5,9,19,1,29,5,15,0,25,1,75,1, @@ -817,17 +834,23 @@ void SpinBLEClient::keepAliveBLE_HID(NimBLEClient *pClient) { } void SpinBLEClient::checkBLEReconnect() { - if ((String(userConfig->getConnectedHeartMonitor()) != "none") && !spinBLEClient.connectedHRM) { + char notConnectedDevices[32] = {0}; + size_t offset = 0; + + if ((strcmp(userConfig->getConnectedHeartMonitor(), NONE) != 0) && !spinBLEClient.connectedHRM) { this->doScan = true; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "No HRM Connected"); + offset += snprintf(notConnectedDevices + offset, sizeof(notConnectedDevices) - offset, "HRM "); } - if ((String(userConfig->getConnectedPowerMeter()) != "none") && !(spinBLEClient.connectedPM || spinBLEClient.connectedCD)) { + if ((strcmp(userConfig->getConnectedPowerMeter(), NONE) != 0) && !(spinBLEClient.connectedPM || spinBLEClient.connectedCD)) { this->doScan = true; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "No PM Connected"); + offset += snprintf(notConnectedDevices + offset, sizeof(notConnectedDevices) - offset, "PM "); } - if ((String(userConfig->getConnectedRemote()) != "none") && !(spinBLEClient.connectedRemote)) { + if ((strcmp(userConfig->getConnectedRemote(), NONE) != 0) && !(spinBLEClient.connectedRemote)) { this->doScan = true; - SS2K_LOG(BLE_CLIENT_LOG_TAG, "No Rem Connected"); + offset += snprintf(notConnectedDevices + offset, sizeof(notConnectedDevices) - offset, "Remote "); + } + if (offset > 0) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Devices not connected: %s", notConnectedDevices); } } @@ -939,9 +962,13 @@ void SpinBLEAdvertisedDevice::set(const NimBLEAdvertisedDevice *device, int id, SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered Remote on Connect"); } } + } else { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "No pClient in Set()"); } + } else { + // During initial discovery, just store the device info without registering services + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Set %s with no current connection.", device->getAddress().toString().c_str()); } - // During initial discovery, just store the device info without registering services } /** diff --git a/src/BLE_Common.cpp b/src/BLE_Common.cpp index c15e6f08..96d51af8 100644 --- a/src/BLE_Common.cpp +++ b/src/BLE_Common.cpp @@ -15,6 +15,17 @@ #include #include +/** + * @brief Retrieves the BLE service information for a given advertised device and device name. + * + * This function checks if the advertised device is advertising any of the supported BLE services. + * For the Flywheel UART service, it additionally verifies that the device name matches the expected Flywheel BLE name. + * If a matching service is found, a pointer to the corresponding BLEServiceInfo is returned. + * + * @param advertisedDevice Pointer to the NimBLEAdvertisedDevice representing the BLE device being checked. + * @param deviceName The name of the BLE device as a String. + * @return Pointer to the matching BLEServiceInfo if found; otherwise, nullptr. + */ const BLEServiceInfo* getDeviceServiceInfo(const NimBLEAdvertisedDevice* advertisedDevice, const String& deviceName) { if (!advertisedDevice->haveServiceUUID()) { return nullptr; @@ -36,6 +47,15 @@ const BLEServiceInfo* getDeviceServiceInfo(const NimBLEAdvertisedDevice* adverti return nullptr; } +/** + * @brief Checks if a BLE device is supported based on its advertised information and name. + * + * Determines whether the specified BLE device is supported by attempting to retrieve its service information. + * + * @param advertisedDevice Pointer to the advertised BLE device to check. + * @param deviceName The name of the device to match against. + * @return true if the device is supported; false otherwise. + */ bool isDeviceSupported(const NimBLEAdvertisedDevice* advertisedDevice, const String& deviceName) { return getDeviceServiceInfo(advertisedDevice, deviceName) != nullptr; } void BLECommunications() { diff --git a/src/BLE_Fitness_Machine_Service.cpp b/src/BLE_Fitness_Machine_Service.cpp index b66f3e0a..501731b8 100644 --- a/src/BLE_Fitness_Machine_Service.cpp +++ b/src/BLE_Fitness_Machine_Service.cpp @@ -79,7 +79,7 @@ void BLE_Fitness_Machine_Service::update() { FitnessMachineIndoorBikeDataFlags::Types ftmsIBDFlags = FitnessMachineIndoorBikeDataFlags::InstantaneousCadencePresent | FitnessMachineIndoorBikeDataFlags::ResistanceLevelPresent | FitnessMachineIndoorBikeDataFlags::InstantaneousPowerPresent; - if (String(userConfig->getConnectedHeartMonitor()) != "none") { + if (strcmp(userConfig->getConnectedHeartMonitor(), NONE) != 0) { ftmsIBDFlags = ftmsIBDFlags | FitnessMachineIndoorBikeDataFlags::HeartRatePresent; } @@ -104,7 +104,7 @@ void BLE_Fitness_Machine_Service::update() { ftmsIndoorBikeData.push_back(static_cast(rtConfig->watts.getValue() >> 8)); // Add heart rate if HRM is connected - if (String(userConfig->getConnectedHeartMonitor()) != "none") { + if (strcmp(userConfig->getConnectedHeartMonitor(), NONE) != 0) { ftmsIndoorBikeData.push_back(static_cast(rtConfig->hr.getValue())); } diff --git a/src/BLE_Heart_Service.cpp b/src/BLE_Heart_Service.cpp index 6e7a20c5..0810810f 100644 --- a/src/BLE_Heart_Service.cpp +++ b/src/BLE_Heart_Service.cpp @@ -37,17 +37,6 @@ void BLE_Heart_Service::deinit() { } void BLE_Heart_Service::update() { - /* Check if heart rate monitor is connected - if (String(userConfig->getConnectedHeartMonitor()) == "none") { - deinit(); - return; - } - - if (!pHeartService) { - // Re-initialize if needed, most likely after changing HRM from none to a specific device - MyCharacteristicCallbacks* chrCallbacks; - setupService(spinBLEServer.pServer, chrCallbacks); - }*/ byte heartRateMeasurement[2] = {0x00, (byte)rtConfig->hr.getValue()}; // Notify the cycling power measurement characteristic diff --git a/src/HTTP_Server_Basic.cpp b/src/HTTP_Server_Basic.cpp index 3fa22855..98341437 100644 --- a/src/HTTP_Server_Basic.cpp +++ b/src/HTTP_Server_Basic.cpp @@ -110,12 +110,6 @@ void startWifi() { SS2K_LOG(HTTP_SERVER_LOG_TAG, "Connected to %s IP address: %s", userConfig->getSsid(), myIP.toString().c_str()); SS2K_LOG(HTTP_SERVER_LOG_TAG, "Open http://%s.local/", userConfig->getDeviceName()); - // Initialize DirCon MDNS service - if (DirConManager::start()) { - SS2K_LOG(HTTP_SERVER_LOG_TAG, "DirCon service started successfully"); - } else { - SS2K_LOG(HTTP_SERVER_LOG_TAG, "Error starting DirCon service"); - } WiFi.setTxPower(WIFI_POWER_19_5dBm); @@ -170,7 +164,6 @@ void HTTP_Server::start() { "15 seconds."; // spinBLEClient.resetDevices(); - spinBLEClient.dontBlockScan = true; spinBLEClient.doScan = true; server.send(200, "text/html", response); }); @@ -321,6 +314,7 @@ void HTTP_Server::start() { []() { HTTPUpload &upload = server.upload(); if (upload.filename == String("firmware.bin").c_str()) { + ss2k->isUpdating = true; // Set the updating flag to true if (upload.status == UPLOAD_FILE_START) { SS2K_LOG(HTTP_SERVER_LOG_TAG, "Update: %s", upload.filename.c_str()); if (!Update.begin(UPDATE_SIZE_UNKNOWN, U_FLASH)) { // start with max @@ -341,6 +335,7 @@ void HTTP_Server::start() { Update.printError(Serial); } } + ss2k->isUpdating = false; // Reset the updating flag } else if (upload.filename == String("littlefs.bin").c_str()) { if (upload.status == UPLOAD_FILE_START) { SS2K_LOG(HTTP_SERVER_LOG_TAG, "Update: %s", upload.filename.c_str()); @@ -558,7 +553,7 @@ void HTTP_Server::settingsProcessor() { spinBLEClient.reconnectAllDevices(); } } else { - userConfig->setConnectedPowerMeter("any"); + userConfig->setConnectedPowerMeter(String(ANY)); } } if (!server.arg("bleHRDropdown").isEmpty()) { @@ -570,7 +565,7 @@ void HTTP_Server::settingsProcessor() { } userConfig->setConnectedHeartMonitor(server.arg("bleHRDropdown")); } else { - userConfig->setConnectedHeartMonitor("any"); + userConfig->setConnectedHeartMonitor(String(NONE)); } } if (!server.arg("bleRemoteDropdown").isEmpty()) { @@ -582,7 +577,7 @@ void HTTP_Server::settingsProcessor() { } userConfig->setConnectedRemote(server.arg("bleRemoteDropdown")); } else { - userConfig->setConnectedRemote("any"); + userConfig->setConnectedRemote(String(NONE)); } } @@ -663,8 +658,7 @@ void HTTP_Server::FirmwareUpdate() { if (((availableVer > currentVer) && (userConfig->getAutoUpdate())) || (!LittleFS.exists("/index.html"))) { //////////////// Update LittleFS////////////// SS2K_LOG(HTTP_SERVER_LOG_TAG, "Updating FileSystem"); - http.begin(DATA_UPDATEURL + String(DATA_FILELIST), - rootCACertificate); // check version URL + http.begin(DATA_UPDATEURL DATA_FILELIST, rootCACertificate); // check version URL delay(100); httpCode = http.GET(); // get data from version file delay(100); diff --git a/src/Main.cpp b/src/Main.cpp index 3afce517..91d42268 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -61,18 +61,7 @@ void SS2K::startTasks() { } void SS2K::stopTasks() { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Shutting Down all BLE services"); - spinBLEClient.reconnectTries = 0; - spinBLEClient.intentionalDisconnect = NUM_BLE_DEVICES; - if (NimBLEDevice::isInitialized()) { - NimBLEDevice::deinit(); - ss2k->stopTasks(); - } - SS2K_LOG(MAIN_LOG_TAG, "Stop BLE + ERG Tasks"); - if (BLEClientTask != NULL) { - vTaskDelete(BLEClientTask); - BLEClientTask = NULL; - } + // In favor of stopping the tasks, BLE communications loop just disconnects all connected devices. } extern "C" void app_main() { @@ -332,7 +321,7 @@ void SS2K::maintenanceLoop(void *pvParameters) { SS2K_LOG(MAIN_LOG_TAG, "Best Block: %d", heap_caps_get_largest_free_block(MALLOC_CAP_8BIT)); #endif // DEBUG_STACK // Log userParameters - SS2K_LOG(MAIN_LOG_TAG, "PM Con %d, HRM Con %d, W %d, Cad %d, HR %d, Gear %d, Target Position %d", spinBLEClient.connectedPM, spinBLEClient.connectedHRM, + SS2K_LOG(MAIN_LOG_TAG, "PM Con %d, CAD con %d, HRM Con %d, W %d, Cad %d, HR %d, Gear %d, Target Position %d", spinBLEClient.connectedPM, spinBLEClient.connectedCD, spinBLEClient.connectedHRM, rtConfig->watts.getValue(), rtConfig->cad.getValue(), rtConfig->hr.getValue(), rtConfig->getShifterPosition(), ss2k->targetPosition); intervalTimer2 = millis(); diff --git a/src/SensorCollector.cpp b/src/SensorCollector.cpp index 1dc5c739..4f1bda5c 100644 --- a/src/SensorCollector.cpp +++ b/src/SensorCollector.cpp @@ -46,7 +46,7 @@ void collectAndSet(NimBLEUUID charUUID, NimBLEUUID serviceUUID, NimBLEAddress ad } if (sensorData->hasCadence() && !rtConfig->cad.getSimulate()) { - if ((charUUID == PELOTON_DATA_UUID) && !((String(userConfig->getConnectedPowerMeter()) == "none") || (String(userConfig->getConnectedPowerMeter()) == "any"))) { + if ((charUUID == PELOTON_DATA_UUID) && !(strcmp(userConfig->getConnectedPowerMeter(), NONE) == 0 || strcmp(userConfig->getConnectedPowerMeter(), ANY) == 0)) { // Peloton connected but using BLE Power Meter. So skip cad for Peloton UUID. } else { float cadence = sensorData->getCadence(); @@ -57,7 +57,7 @@ void collectAndSet(NimBLEUUID charUUID, NimBLEUUID serviceUUID, NimBLEAddress ad } if (sensorData->hasPower() && !rtConfig->watts.getSimulate() && !userConfig->getPTab4Pwr()) { - if ((charUUID == PELOTON_DATA_UUID) && !((String(userConfig->getConnectedPowerMeter()) == "none") || (String(userConfig->getConnectedPowerMeter()) == "any"))) { + if ((charUUID == PELOTON_DATA_UUID) && !((strcmp(userConfig->getConnectedPowerMeter(), NONE) == 0) || (strcmp(userConfig->getConnectedPowerMeter(), ANY) == 0))) { // Peloton connected but using BLE Power Meter. So skip power for Peloton UUID. } else { int power = sensorData->getPower() * userConfig->getPowerCorrectionFactor(); From cbbf52b6025c4554209e0b48c32631310efe27bb Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Tue, 1 Jul 2025 20:15:32 -0500 Subject: [PATCH 258/451] fixed Dircon --- src/HTTP_Server_Basic.cpp | 14 ++++++++++---- src/Main.cpp | 4 ---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/HTTP_Server_Basic.cpp b/src/HTTP_Server_Basic.cpp index 98341437..b3097496 100644 --- a/src/HTTP_Server_Basic.cpp +++ b/src/HTTP_Server_Basic.cpp @@ -110,6 +110,12 @@ void startWifi() { SS2K_LOG(HTTP_SERVER_LOG_TAG, "Connected to %s IP address: %s", userConfig->getSsid(), myIP.toString().c_str()); SS2K_LOG(HTTP_SERVER_LOG_TAG, "Open http://%s.local/", userConfig->getDeviceName()); + // Initialize DirCon MDNS service + if (DirConManager::start()) { + SS2K_LOG(HTTP_SERVER_LOG_TAG, "DirCon service started successfully"); + } else { + SS2K_LOG(HTTP_SERVER_LOG_TAG, "Error starting DirCon service"); + } WiFi.setTxPower(WIFI_POWER_19_5dBm); @@ -164,7 +170,7 @@ void HTTP_Server::start() { "15 seconds."; // spinBLEClient.resetDevices(); - spinBLEClient.doScan = true; + spinBLEClient.doScan = true; server.send(200, "text/html", response); }); @@ -559,7 +565,7 @@ void HTTP_Server::settingsProcessor() { if (!server.arg("bleHRDropdown").isEmpty()) { wasBTUpdate = true; if (server.arg("bleHRDropdown")) { - tString = server.arg("bleHRDropdown"); + tString = server.arg("bleHRDropdown"); if (tString != userConfig->getConnectedHeartMonitor()) { spinBLEClient.reconnectAllDevices(); } @@ -571,7 +577,7 @@ void HTTP_Server::settingsProcessor() { if (!server.arg("bleRemoteDropdown").isEmpty()) { wasBTUpdate = true; if (server.arg("bleRemoteDropdown")) { - tString = server.arg("bleRemoteDropdown"); + tString = server.arg("bleRemoteDropdown"); if (tString != userConfig->getConnectedRemote()) { spinBLEClient.reconnectAllDevices(); } @@ -664,7 +670,7 @@ void HTTP_Server::FirmwareUpdate() { delay(100); JsonDocument doc; if (httpCode == HTTP_CODE_OK) { // if version received - payload = http.getString(); // save received version + payload = http.getString(); // save received version payload.trim(); // Deserialize the JSON document DeserializationError error = deserializeJson(doc, payload); diff --git a/src/Main.cpp b/src/Main.cpp index 91d42268..5e3ce7b9 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -137,14 +137,10 @@ extern "C" void app_main() { // moves don't cause problems) digitalWrite(LED_PIN, HIGH); - Serial.println("Starting BLE"); // Configure and Initialize Logger logHandler.addAppender(&webSocketAppender); - Serial.println("Starting BLE"); logHandler.addAppender(&udpAppender); - Serial.println("Starting BLE"); logHandler.initialize(); - Serial.println("Starting BLE"); ss2k->startTasks(); httpServer.start(); From 3b2731e6b61d15c67f430b3a7c7609cdfc5d8084 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 2 Jul 2025 14:16:43 -0500 Subject: [PATCH 259/451] Improved BLE connection speed --- src/BLE_Client.cpp | 11 ++++------- src/Main.cpp | 4 ++-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index fd86d316..f9a05fc1 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -34,7 +34,7 @@ void SpinBLEClient::start() { "BLEClientTask", /* name of task. */ BLE_CLIENT_STACK, /* Stack size of task */ NULL, /* parameter of the task */ - 1, /* priority of the task */ + 21, /* priority of the task */ &BLEClientTask, /* Task handle to keep track of created task */ 1); /* pin task to core */ @@ -279,9 +279,9 @@ bool SpinBLEClient::connectToServer() { pClient = NimBLEDevice::getClientByPeerAddress(myDevice->getAddress()); if (pClient) { pClient->setConnectTimeout(10000); - pClient->setConnectionParams(connectionParams[0], connectionParams[1], connectionParams[2], connectionParams[3] * 2); + pClient->setConnectionParams(connectionParams[0], connectionParams[1], connectionParams[2], 1000); SS2K_LOG(BLE_CLIENT_LOG_TAG, "Reusing Client"); - if (!pClient->connect(myDevice, false, true, true)) { + if (!pClient->connect(myDevice, false, false, true)) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Reconnect failed "); this->reconnectTries--; SS2K_LOG(BLE_CLIENT_LOG_TAG, "%d left.", reconnectTries); @@ -317,7 +317,7 @@ bool SpinBLEClient::connectToServer() { * connections. Timeout should be a multiple of the interval, minimum is 100ms. * Min interval: 12 * 1.25ms = 15, Max interval: 12 * 1.25ms = 15, 0 latency, 51 * 10ms = 510ms timeout */ - pClient->setConnectionParams(connectionParams[0], connectionParams[1], connectionParams[2], connectionParams[3] * 2); + pClient->setConnectionParams(connectionParams[0], connectionParams[1], connectionParams[2], 1000); /** Set how long we are willing to wait for the connection to complete (seconds), default is 30. */ pClient->setConnectTimeout(5000); // 5 seconds @@ -504,9 +504,6 @@ void SpinBLEClient::scanProcess(int duration) { SS2K_LOG(BLE_CLIENT_LOG_TAG, "Scanning for BLE servers and putting them into a list..."); pBLEScan->start(duration, false, true); - while (pBLEScan->isScanning()) { - delay(10); // Wait for the scan to finish - } } void ScanCallbacks::onScanEnd(const NimBLEScanResults &results, int reason) { diff --git a/src/Main.cpp b/src/Main.cpp index 5e3ce7b9..f801866c 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -173,9 +173,9 @@ extern "C" void app_main() { "maintenanceLoopFunction", /* name of task. */ MAIN_STACK, /* Stack size of task */ NULL, /* parameter of the task */ - 10, /* priority of the task */ + 20, /* priority of the task */ &maintenanceLoopTask, /* Task handle to keep track of created task */ - 0); /* pin task to core */ + 1); /* pin task to core */ } void loop() { // Delete this task so we can make one that's more memory efficient. From 10b2584533f3e2cb99e138dab53549c109e130c4 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 2 Jul 2025 18:02:06 -0500 Subject: [PATCH 260/451] added new fillByAverage() --- include/PowerTable_Helpers.h | 5 +- include/Power_Table.h | 5 - src/PowerTable_Helpers.cpp | 233 +++++++++++++++++++++++++++++++---- src/Power_Table.cpp | 45 ++----- 4 files changed, 224 insertions(+), 64 deletions(-) diff --git a/include/PowerTable_Helpers.h b/include/PowerTable_Helpers.h index b6d818d9..9743e4ec 100644 --- a/include/PowerTable_Helpers.h +++ b/include/PowerTable_Helpers.h @@ -128,8 +128,11 @@ class PTHelpers { int32_t lookupWatts(int cad, int32_t targetPosition, PTData& ptData); int32_t extrapolateCadenceWatts(int cad, float targetPosition, PTData& ptData); int extrapolateWattsFromCadence(int cad, int32_t targetPosition, PTData& ptData); + // return number of readings in the table. If minReadings is set, it will only count entries with at least that many readings. + int getNumEntries(PTData& ptData, int minReadings = 0); + int getTotalReadings(PTData& ptData); + void fillByAverage(PTData& ptData); ptIndex calculateIndex(int watts, int cad); - int dataPoints(PTData& ptData); std::pair, std::vector> getRow(int row, PTData& ptData); std::pair, std::vector> getColumn(int column, PTData& ptData); }; \ No newline at end of file diff --git a/include/Power_Table.h b/include/Power_Table.h index 0c7fa4be..69042403 100644 --- a/include/Power_Table.h +++ b/include/Power_Table.h @@ -57,9 +57,6 @@ class PowerTable { // Reset the active power table and delete the saved power table. bool reset(); - // return number of readings in the table. - int getNumReadings(); - // Display power table in log void toLog(); @@ -73,8 +70,6 @@ class PowerTable { private: unsigned long lastSaveTime = millis(); - int getNumEntries(); - // remove entries with < 1 readings void clean(); }; diff --git a/src/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp index c15868e9..0fc054dc 100644 --- a/src/PowerTable_Helpers.cpp +++ b/src/PowerTable_Helpers.cpp @@ -126,19 +126,6 @@ ptIndex PTHelpers::calculateIndex(int watts, int cad) { return index; } -// find the number of data points in the table -int PTHelpers::dataPoints(PTData& ptData) { - int count = 0; - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - count++; - } - } - } - return count; -} - /** * @brief Retrieves the x and y values from a specific row of the power table. * @@ -325,7 +312,6 @@ int32_t PTHelpers::lookup(int watts, int cad, PTData& ptData) { */ bool PTHelpers::extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, std::pair, std::vector> xy, size_t n, bool horizontal, bool naturalSpline, PTData& ptData) { - unsigned long timeout = millis() + COMPUTATION_TIMEOUT_MS; // Set timeout for computation ptIndex index; if (n >= 3) { @@ -353,7 +339,9 @@ bool PTHelpers::extrapolateEmptyIndices(int outerIndex, const std::vector& float maxVal = *std::max_element(xy.second.begin(), xy.second.end()); float range = maxVal - minVal; extrapolated_value = std::max(minVal - 0.1f * range, std::min(extrapolated_value, maxVal + 0.1f * range)); - int tempValue = static_cast(round(extrapolated_value)); + int tempValue = (ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition == INT16_MIN) + ? round(extrapolated_value) + : round((extrapolated_value + ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition) / 2.0f); if (testNeighbors(index, tempValue, ptData).allNeighborsPassed) { // Blend with nearby valid neighbors to ensure smoothness @@ -397,9 +385,8 @@ bool PTHelpers::extrapolateEmptyIndices(int outerIndex, const std::vector& blendedValue = (originalWeight * tempValue + neighborWeight * (blendedValue - tempValue) / (totalWeight - 1.0f)); } - ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition = static_cast(round(blendedValue)); - if( millis() > timeout) { + if (millis() > timeout) { SS2K_LOG(PTDATA_LOG_TAG, "Spline fill operation timed out!"); return false; // Exit if computation takes too long } @@ -409,6 +396,154 @@ bool PTHelpers::extrapolateEmptyIndices(int outerIndex, const std::vector& return true; } +/** + * @brief Fills missing or invalid entries in the power table by estimating values using averages. + * + * This function processes the provided PTData structure, which represents a power table with + * cadence and wattage dimensions. It performs the following steps: + * 1. Calculates the average target position for each wattage column across all valid cadence rows. + * 2. Computes the average increase in target position per cadence increment for each wattage column. + * 3. For each empty or invalid cell, estimates its value based on the center average and the average + * increase per cadence step, filling in the missing data accordingly. + * + * If a cell was previously filled by another method, the function averages the new estimate with the + * existing value to provide a smoother result. + * + * @param ptData Reference to the PTData structure containing the power table to be filled. + */ +void PTHelpers::fillByAverage(PTData& ptData) { + std::vector centerAverageRow(POWERTABLE_WATT_SIZE, 0.0f); + std::vector validCounts(POWERTABLE_WATT_SIZE, 0); + int mid_cad_index = POWERTABLE_CAD_SIZE / 2; + float center_cad = static_cast(MINIMUM_TABLE_CAD + mid_cad_index * POWERTABLE_CAD_INCREMENT); + + // 1. Calculate the center average row using improved regression + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + std::vector> points; + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + float cad = static_cast(MINIMUM_TABLE_CAD + i * POWERTABLE_CAD_INCREMENT); + points.push_back({cad, static_cast(ptData.tableRow[i].tableEntry[j].targetPosition)}); + } + } + validCounts[j] = points.size(); + + if (points.size() >= 2) { + // Check if data is clustered far from center + float min_cad = points.front().first; + float max_cad = points.back().first; + float cad_range = max_cad - min_cad; + float distance_from_center = std::min(std::abs(center_cad - min_cad), std::abs(center_cad - max_cad)); + + // If data is too far from center or range is too small, use neighbor interpolation instead + if (distance_from_center > 20.0f || cad_range < 10.0f) { + // Try to interpolate from neighboring power levels + float neighborAvg = 0.0f; + int neighborCount = 0; + + // Check left and right neighbors + for (int neighbor_j = std::max(0, j-2); neighbor_j <= std::min(POWERTABLE_WATT_SIZE-1, j+2); neighbor_j++) { + if (neighbor_j != j && validCounts[neighbor_j] > 0) { + // Get neighbor's data and check if it has data near center + std::vector> neighborPoints; + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (ptData.tableRow[i].tableEntry[neighbor_j].targetPosition != INT16_MIN) { + float cad = static_cast(MINIMUM_TABLE_CAD + i * POWERTABLE_CAD_INCREMENT); + neighborPoints.push_back({cad, static_cast(ptData.tableRow[i].tableEntry[neighbor_j].targetPosition)}); + } + } + + if (neighborPoints.size() >= 2) { + // Calculate neighbor's center value + float sum_x = 0, sum_y = 0, sum_xy = 0, sum_x2 = 0; + for (const auto& p : neighborPoints) { + sum_x += p.first; + sum_y += p.second; + sum_xy += p.first * p.second; + sum_x2 += p.first * p.first; + } + float n = neighborPoints.size(); + float denom = (n * sum_x2 - sum_x * sum_x); + if (denom != 0) { + float slope = (n * sum_xy - sum_x * sum_y) / denom; + float intercept = (sum_y - slope * sum_x) / n; + float neighborCenterValue = slope * center_cad + intercept; + + // Weight by proximity and data quality + float weight = 1.0f / (1.0f + std::abs(neighbor_j - j)); + neighborAvg += neighborCenterValue * weight; + neighborCount += weight; + } + } + } + } + + if (neighborCount > 0) { + centerAverageRow[j] = neighborAvg / neighborCount; + } else { + // Fallback to simple average of available points + float sum = 0; + for (const auto& p : points) sum += p.second; + centerAverageRow[j] = sum / points.size(); + } + } else { + // Use normal linear regression for well-distributed data + float sum_x = 0, sum_y = 0, sum_xy = 0, sum_x2 = 0; + for (const auto& p : points) { + sum_x += p.first; + sum_y += p.second; + sum_xy += p.first * p.second; + sum_x2 += p.first * p.first; + } + float n = points.size(); + float denom = (n * sum_x2 - sum_x * sum_x); + float slope = (denom != 0) ? (n * sum_xy - sum_x * sum_y) / denom : 0; + float intercept = (sum_y - slope * sum_x) / n; + centerAverageRow[j] = slope * center_cad + intercept; + } + } else if (points.size() == 1) { + centerAverageRow[j] = points[0].second; + } + } + + // 2. Calculate the average increase in target position per cadence increment for each column + std::vector averageIncreasePerCadence(POWERTABLE_WATT_SIZE, 0.0f); + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + float totalIncrease = 0.0f; + int increaseCount = 0; + for (int i = 0; i < POWERTABLE_CAD_SIZE - 1; ++i) { + if (ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN && ptData.tableRow[i + 1].tableEntry[j].targetPosition != INT16_MIN) { + totalIncrease += (ptData.tableRow[i + 1].tableEntry[j].targetPosition - ptData.tableRow[i].tableEntry[j].targetPosition); + increaseCount++; + } + } + if (increaseCount > 0) { + averageIncreasePerCadence[j] = totalIncrease / increaseCount; + } + } + + // 3. Fill empty cells based on the average row and average increase + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + // Only fill cells that have not been populated with real data + if (ptData.tableRow[i].tableEntry[j].readings < 1) { + if (validCounts[j] > 0) { // Only fill if there was data in this column to create an average + int distance = i - mid_cad_index; + float newValue = centerAverageRow[j] + (averageIncreasePerCadence[j] * distance); + int16_t intNewValue = static_cast(round(newValue)); + + // If the cell was already filled by another method, average with the new value + if (ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + ptData.tableRow[i].tableEntry[j].targetPosition = round((ptData.tableRow[i].tableEntry[j].targetPosition + intNewValue) / 2.0f); + } else { + ptData.tableRow[i].tableEntry[j].targetPosition = intNewValue; + } + } + } + } + } +} + /** * @brief Fills missing entries in the power table using cubic spline interpolation. * @@ -423,9 +558,9 @@ bool PTHelpers::extrapolateEmptyIndices(int outerIndex, const std::vector& * @param horizontal (optional) If true, fills across watt indices (rows); if false, fills across cadence indices (columns). Default is true. */ bool PTHelpers::splineFill(PTData& ptData, bool firstHalf /*= true*/, bool horizontal /*= true*/) { - bool completedWithoutTimeout = true;; - int outerSize = horizontal ? POWERTABLE_CAD_SIZE : POWERTABLE_WATT_SIZE; - int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; + bool completedWithoutTimeout = true; + int outerSize = horizontal ? POWERTABLE_CAD_SIZE : POWERTABLE_WATT_SIZE; + int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; std::vector> unique_xy; std::vector emptyIndices; @@ -469,7 +604,8 @@ bool PTHelpers::splineFill(PTData& ptData, bool firstHalf /*= true*/, bool horiz continue; } - if (ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition != INT16_MIN) { + // Gather valid data points. Exclude points with 0 readings and a valid targetPosition - those are previously interpolated points. + if (ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings > 0 && ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition != INT16_MIN) { unique_xy.emplace_back(innerIndex, static_cast(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition)); } else { emptyIndices.push_back(innerIndex); @@ -495,7 +631,7 @@ bool PTHelpers::splineFill(PTData& ptData, bool firstHalf /*= true*/, bool horiz }; for (int k = 0; k <= max_k_outer; ++k) { - if(!completedWithoutTimeout) { + if (!completedWithoutTimeout) { return false; // Exit if computation takes too long } int outer_upper = mid_outer + k; @@ -564,7 +700,7 @@ bool PTHelpers::linearFill(PTData& ptData) { // Define a lambda for processing a single cell auto processCell = [this, &ptData](int currentRowIndex, int currentColIndex) { - if (ptData.tableRow[currentRowIndex].tableEntry[currentColIndex].targetPosition == INT16_MIN) { + if (ptData.tableRow[currentRowIndex].tableEntry[currentColIndex].readings == 0) { int watts = currentColIndex * POWERTABLE_WATT_INCREMENT; int cad = currentRowIndex * POWERTABLE_CAD_INCREMENT + MINIMUM_TABLE_CAD; int resistance = this->lookup(watts, cad, ptData); @@ -579,7 +715,10 @@ bool PTHelpers::linearFill(PTData& ptData) { current_pt_idx.cadIndex = currentRowIndex; TestResults results = this->testNeighbors(current_pt_idx, resistance, ptData); if (results.allNeighborsPassed == 1) { - ptData.tableRow[currentRowIndex].tableEntry[currentColIndex].targetPosition = resistance; + ptData.tableRow[currentRowIndex].tableEntry[currentColIndex].targetPosition = + (ptData.tableRow[currentRowIndex].tableEntry[currentColIndex].targetPosition == INT16_MIN) + ? resistance + : round((ptData.tableRow[currentRowIndex].tableEntry[currentColIndex].targetPosition + resistance) / 2.0f); // SS2K_LOG(PTDATA_LOG_TAG, "Filled position (%d, %d) with resistance: %d", currentRowIndex, currentColIndex, resistance); } else { // log the failure to in insert the value // Serial.printf("Failed to fill position (%d, %d) with resistance: %d\n", currentRowIndex, currentColIndex, resistance); @@ -609,6 +748,50 @@ bool PTHelpers::linearFill(PTData& ptData) { return true; // Return true if all operations completed without timeout } +/** + * @brief Counts the number of valid entries in the power table. + * + * This function iterates through the power table and counts entries that are considered valid. + * If minReadings is 0 (the default), an entry is valid if its targetPosition is not INT16_MIN. + * Otherwise, an entry is valid if its readings count is greater than or equal to minReadings. + * + * @param ptData Reference to the PTData structure containing the power table. + * @param minReadings (optional) Minimum number of readings required for an entry to be considered valid. Default is 0. + * @return int The number of valid entries in the power table. + */ +int PTHelpers::getNumEntries(PTData& ptData, int minReadings /*= 0*/) { + int ret = 0; + if (minReadings == 0) { + for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + if (ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + ret++; + } + } + } + } else { + for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + if (ptData.tableRow[i].tableEntry[j].readings >= minReadings) { + ret++; + } + } + } + } + return ret; +} + +// returns the total number of readings in the power table +int PTHelpers::getTotalReadings(PTData& ptData) { + int totalReadings = 0; + for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { + for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { + totalReadings += ptData.tableRow[i].tableEntry[j].readings; + } + } + return totalReadings; +} + // Use the powertable to preform a reverse lookup of the target position to find the watts at a given cadence. int32_t PTHelpers::lookupWatts(int cad, int32_t targetPosition, PTData& ptData) { if (cad < POWERTABLE_CAD_INCREMENT * 2) { @@ -676,7 +859,7 @@ int PTHelpers::extrapolateWattsFromCadence(int cad, int32_t targetPosition, PTDa for (int i = 0; i < xy.second.size(); i++) { for (int j = 0; j < xyUsed4Offset.second.size(); j++) { if (xy.first[i] == xyUsed4Offset.first[j]) { - offset = (((xyUsed4Offset.second[j] - xy.second[i]) * cadDelta) + offset) / 2; + offset = (((xyUsed4Offset.second[j] - xy.second[i]) * cadDelta) + offset) / 2; } } } diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index befc71a5..5c7bfa40 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -58,7 +58,7 @@ void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, Measur int currentPos = ss2k->getCurrentPosition() / TABLE_DIVISOR; int targetPos = powerBuffer.powerEntry[0].targetPosition; - int range = (userConfig->getShiftStep() / 2) / TABLE_DIVISOR; + int range = (userConfig->getShiftStep() * 2) / TABLE_DIVISOR; if (currentPos >= (targetPos - range) && currentPos <= (targetPos + range)) { for (int i = 1; i < POWER_SAMPLES; i++) { @@ -137,18 +137,6 @@ void PowerTable::setStepperMinMax() { } } -int PowerTable::getNumEntries() { - int ret = 0; - for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - if (this->ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - ret++; - } - } - } - return ret; -} - void PowerTable::clean() { SS2K_LOG(POWERTABLE_LOG_TAG, "Clean Power Table"); for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { @@ -192,7 +180,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } // clean previously extrapolated data so we don't fill with trash. - this->clean(); + // this->clean(); // To start working on the PowerTable, we need to calculate position in the table for the new entry ptIndex index = ptHelpers.calculateIndex(watts, cad); @@ -280,13 +268,13 @@ void PowerTable::fillTable() { return; } - if (this->getNumEntries() > 4) { + if (ptHelpers.getNumEntries(ptData) > 4) { // set flag to stop execution after we can't add any more entries. if (esp_get_free_heap_size() < FREE_HEAP_FOR_COMPLEX_MATH) { // SS2K_LOG(POWERTABLE_LOG_TAG, "%d Heap too low for step %d.", esp_get_free_heap_size(), step); return; } - entries = getNumEntries(); + entries = ptHelpers.getNumEntries(ptData); if (step == 0) { SS2K_LOG(POWERTABLE_LOG_TAG, "Fill start with %d entries", entries); prevEntries = entries; @@ -295,18 +283,21 @@ void PowerTable::fillTable() { completed = ptHelpers.splineFill(ptData, false); } else if (step == 2) { completed = ptHelpers.linearFill(ptData); + }else if (step == 3) { + ptHelpers.fillByAverage(ptData); + completed = true; // this step is always completed. } - newEntries = getNumEntries(); + newEntries = ptHelpers.getNumEntries(ptData); SS2K_LOG(POWERTABLE_LOG_TAG, "Fill step %d added %d new entries", step, newEntries - prevEntries); if (newEntries > prevEntries) { prevEntries = newEntries; - } else if (step == 2) { + } else if (step == 3) { SS2K_LOG(POWERTABLE_LOG_TAG, "No more entries can be added, stopping fill."); fillTableFlag = false; step = 0; return; } - if (completed) step = (step + 1) % 3; + if (completed) step = (step + 1) % 4; } } @@ -493,7 +484,7 @@ bool PowerTable::_manageSaveState(bool canSkipReliabilityChecks) { } // Is the data we are working with better than the saved file? - int activeReadings = this->getNumReadings(); + int activeReadings = ptHelpers.getTotalReadings(ptData); if (activeReadings > savedQuality) { SS2K_LOG(POWERTABLE_LOG_TAG, "Active table had a reliability of %d, vs %d for the saved file. Overwriting save.", activeReadings, savedQuality); file.close(); @@ -618,7 +609,7 @@ bool PowerTable::_save() { Serial.printf("LittleFS Total Bytes:%d, Used Bytes:%d", LittleFS.totalBytes(), LittleFS.usedBytes()); // Count valid readings before saving - int validReadings = getNumReadings(); + int validReadings = ptHelpers.getTotalReadings(ptData); // Only proceed with saving if we have enough data to make the file useful if (validReadings < 1) { @@ -753,16 +744,4 @@ void PowerTable::toLog() { SS2K_LOG(POWERTABLE_LOG_TAG, "%s", logString.c_str()); } #endif -} - -int PowerTable::getNumReadings() { - int ret = 0; - for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - if (this->ptData.tableRow[i].tableEntry[j].readings > 0) { - ret++; - } - } - } - return ret; } \ No newline at end of file From ef2333e005ed046f9aff5ec4653777a432612905 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 2 Jul 2025 18:09:49 -0500 Subject: [PATCH 261/451] ptab4pwr skips reliability checks --- src/Power_Table.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 5c7bfa40..395baa7a 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -473,7 +473,7 @@ bool PowerTable::_manageSaveState(bool canSkipReliabilityChecks) { // If both current and saved tables were created with homing, we can skip position reliability checks if (!canSkipReliabilityChecks) { - canSkipReliabilityChecks = savedHomed && rtConfig->getHomed(); + canSkipReliabilityChecks = (savedHomed && rtConfig->getHomed()) || userConfig->getPTab4Pwr(); } if (version != TABLE_VERSION) { From c1af5e8dbab10671b0c94fd9230b1af06632117b Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 2 Jul 2025 18:25:29 -0500 Subject: [PATCH 262/451] load table faster if ptab4pwr and always provide power output if there is cadence even if no table. --- src/ERG_Mode.cpp | 20 ++++++++++---------- src/Power_Table.cpp | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 4b7672de..e02d8668 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -26,7 +26,6 @@ void ErgMode::runERG() { static bool hasConnectedPowerMeter = false; static bool simulationRunning = false; static int loopCounter = 0; - static bool pTabUsed4Pwr = false; if ((millis() - ergTimer) > ERG_MODE_DELAY) { // reset the timer. @@ -53,7 +52,7 @@ void ErgMode::runERG() { simulationRunning = rtConfig->watts.getSimulate(); } - if (!pTabUsed4Pwr) { + if (userConfig->getPTab4Pwr()) { // add values to Power table powerTable->processPowerValue(powerBuffer, rtConfig->cad.getValue(), rtConfig->watts); } @@ -87,19 +86,18 @@ void ErgMode::runERG() { loopCounter++; } - if (userConfig->getPTab4Pwr() && rtConfig->getHomed()) { + if (userConfig->getPTab4Pwr()) { // only do this twice as often as ERG_MODE_DELAY - static float previousPower = 0; + static float previousPower = 0; static unsigned long int pTab4pwrTimer = millis(); + int _smoothPWR = 0; if (millis() - pTab4pwrTimer > ERG_MODE_DELAY / 2) { // reset the timer. pTab4pwrTimer = millis(); // Lookup watts using the Power Table. - pTabUsed4Pwr = true; if (powerTable->_hasBeenLoadedThisSession) { - //Instead of directly outputting this, we should smooth the output by averaging it with the last value. - rtConfig->watts.setValue((previousPower + powerTable->lookupWatts(rtConfig->cad.getValue(), ss2k->getCurrentPosition()))/2); - previousPower = (rtConfig->watts.getValue() + previousPower) / 2; + // Instead of directly outputting this, we should smooth the output by averaging it with the last value. + _smoothPWR = ((previousPower + powerTable->lookupWatts(rtConfig->cad.getValue(), ss2k->getCurrentPosition())) / 2); } else { // only run _manageSaveState every 5 seconds static unsigned long int saveStateTimer = millis(); @@ -109,9 +107,11 @@ void ErgMode::runERG() { saveStateTimer = millis(); } } + // So the user knows pTab4PWR is enabled, provide some cadence feedback even if the value returned by the table is 0. + _smoothPWR = _smoothPWR < rtConfig->cad.getValue() ? round((rtConfig->cad.getValue() + previousPower) / 2.0f) : _smoothPWR; + rtConfig->watts.setValue(_smoothPWR); + previousPower = (rtConfig->watts.getValue() + previousPower) / 2; } - } else { - pTabUsed4Pwr = false; } } diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 395baa7a..ced36193 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -473,7 +473,7 @@ bool PowerTable::_manageSaveState(bool canSkipReliabilityChecks) { // If both current and saved tables were created with homing, we can skip position reliability checks if (!canSkipReliabilityChecks) { - canSkipReliabilityChecks = (savedHomed && rtConfig->getHomed()) || userConfig->getPTab4Pwr(); + canSkipReliabilityChecks = (savedHomed && rtConfig->getHomed()); } if (version != TABLE_VERSION) { From 6eb914361dbbbc7b7481b5e256c1cd72a9656663 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 2 Jul 2025 18:46:46 -0500 Subject: [PATCH 263/451] bugfix --- dependencies.lock | 13 +- sdkconfig.release | 429 ---------------------------------------------- src/ERG_Mode.cpp | 2 +- 3 files changed, 2 insertions(+), 442 deletions(-) diff --git a/dependencies.lock b/dependencies.lock index 17170be1..3aef0ca5 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -41,16 +41,6 @@ dependencies: registry_url: https://components.espressif.com/ type: service version: 1.6.3 - espressif/esp_modem: - component_hash: b541c3f5765d3ba062c0d004b9ca6da6d0af908293421c2dbe046c537fb2a011 - dependencies: - - name: idf - require: private - version: '>=4.1' - source: - registry_url: https://components.espressif.com/ - type: service - version: 1.4.0 espressif/mdns: component_hash: 3ec0af5f6bce310512e90f482388d21cc7c0e99668172d2f895356165fc6f7c5 dependencies: @@ -91,11 +81,10 @@ direct_dependencies: - espressif/cbor - espressif/esp-zboss-lib - espressif/esp-zigbee-lib -- espressif/esp_modem - espressif/mdns - espressif/network_provisioning - idf - joltwallet/littlefs -manifest_hash: e871ea1e1aff9421b8e57e1c5a4db8daeef71b071a2a17f239e5feebc4acdfc3 +manifest_hash: cdea08c215af25ecb07f34a572afe529ccee1d11a022752ebfb3b54cbc0cb5f8 target: esp32 version: 2.0.0 diff --git a/sdkconfig.release b/sdkconfig.release index a9f2dc38..7b3b88bf 100644 --- a/sdkconfig.release +++ b/sdkconfig.release @@ -259,13 +259,9 @@ CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y CONFIG_APP_BUILD_GENERATE_BINARIES=y CONFIG_APP_BUILD_BOOTLOADER=y CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y -# default: # CONFIG_APP_REPRODUCIBLE_BUILD is not set -# default: # CONFIG_APP_NO_BLOBS is not set -# default: # CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set -# default: # CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set # end of Build type @@ -300,7 +296,6 @@ CONFIG_BOOTLOADER_LOG_LEVEL=3 # # Format # -# default: # CONFIG_BOOTLOADER_LOG_COLORS is not set CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y # end of Format @@ -309,32 +304,23 @@ CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y # # Serial Flash Configurations # -# default: # CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y # end of Serial Flash Configurations # CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y -# default: # CONFIG_BOOTLOADER_FACTORY_RESET is not set -# default: # CONFIG_BOOTLOADER_APP_TEST is not set CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y CONFIG_BOOTLOADER_WDT_ENABLE=y -# default: # CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set CONFIG_BOOTLOADER_WDT_TIME_MS=9000 -# default: # CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set -# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set -# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set -# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 -# default: # CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set # end of Bootloader config @@ -342,11 +328,8 @@ CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 # Security features # CONFIG_SECURE_BOOT_V1_SUPPORTED=y -# default: # CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set -# default: # CONFIG_SECURE_BOOT is not set -# default: # CONFIG_SECURE_FLASH_ENC_ENABLED is not set # end of Security features @@ -354,11 +337,8 @@ CONFIG_SECURE_BOOT_V1_SUPPORTED=y # Application manager # CONFIG_APP_COMPILE_TIME_DATE=y -# default: # CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set -# default: # CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set -# default: # CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 # end of Application manager @@ -381,7 +361,6 @@ CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y # # Serial flasher config # -# default: # CONFIG_ESPTOOLPY_NO_STUB is not set # CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set @@ -403,7 +382,6 @@ CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set CONFIG_ESPTOOLPY_FLASHSIZE="2MB" -# default: # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set @@ -433,7 +411,6 @@ CONFIG_PARTITION_TABLE_MD5=y # CONFIG_ARDUINO_VARIANT="esp32" CONFIG_ENABLE_ARDUINO_DEPENDS=y -# default: # CONFIG_AUTOSTART_ARDUINO is not set # CONFIG_ARDUINO_RUN_CORE0 is not set CONFIG_ARDUINO_RUN_CORE1=y @@ -455,9 +432,7 @@ CONFIG_ARDUINO_UDP_RUN_CORE0=y # CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set CONFIG_ARDUINO_UDP_RUNNING_CORE=0 CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 -# default: # CONFIG_ARDUINO_ISR_IRAM is not set -# default: # CONFIG_DISABLE_HAL_LOCKS is not set # @@ -470,9 +445,7 @@ CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE=y # CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set # CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=0 -# default: # CONFIG_ARDUHAL_LOG_COLORS is not set -# default: # CONFIG_ARDUHAL_ESP_LOG is not set # end of Debug Log Configuration @@ -487,25 +460,17 @@ CONFIG_ARDUINO_SELECTIVE_SPI=y CONFIG_ARDUINO_SELECTIVE_Wire=y CONFIG_ARDUINO_SELECTIVE_ESP_SR=y CONFIG_ARDUINO_SELECTIVE_EEPROM=y -# default: # CONFIG_ARDUINO_SELECTIVE_Preferences is not set -# default: # CONFIG_ARDUINO_SELECTIVE_Ticker is not set CONFIG_ARDUINO_SELECTIVE_Update=y -# default: # CONFIG_ARDUINO_SELECTIVE_Zigbee is not set CONFIG_ARDUINO_SELECTIVE_FS=y -# default: # CONFIG_ARDUINO_SELECTIVE_SD is not set -# default: # CONFIG_ARDUINO_SELECTIVE_SD_MMC is not set -# default: # CONFIG_ARDUINO_SELECTIVE_SPIFFS is not set -# default: # CONFIG_ARDUINO_SELECTIVE_FFat is not set CONFIG_ARDUINO_SELECTIVE_LittleFS=y CONFIG_ARDUINO_SELECTIVE_Network=y -# default: # CONFIG_ARDUINO_SELECTIVE_Ethernet is not set CONFIG_ARDUINO_SELECTIVE_PPP=y CONFIG_ARDUINO_SELECTIVE_ArduinoOTA=y @@ -513,23 +478,17 @@ CONFIG_ARDUINO_SELECTIVE_AsyncUDP=y CONFIG_ARDUINO_SELECTIVE_DNSServer=y CONFIG_ARDUINO_SELECTIVE_ESPmDNS=y CONFIG_ARDUINO_SELECTIVE_HTTPClient=y -# default: # CONFIG_ARDUINO_SELECTIVE_Matter is not set -# default: # CONFIG_ARDUINO_SELECTIVE_NetBIOS is not set CONFIG_ARDUINO_SELECTIVE_WebServer=y CONFIG_ARDUINO_SELECTIVE_WiFi=y CONFIG_ARDUINO_SELECTIVE_NetworkClientSecure=y CONFIG_ARDUINO_SELECTIVE_WiFiProv=y CONFIG_ARDUINO_SELECTIVE_BLE=y -# default: # CONFIG_ARDUINO_SELECTIVE_BluetoothSerial is not set CONFIG_ARDUINO_SELECTIVE_SimpleBLE=y -# default: # CONFIG_ARDUINO_SELECTIVE_RainMaker is not set -# default: # CONFIG_ARDUINO_SELECTIVE_OpenThread is not set -# default: # CONFIG_ARDUINO_SELECTIVE_Insights is not set # end of Arduino Configuration @@ -546,35 +505,25 @@ CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 -# default: # CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set CONFIG_COMPILER_HIDE_PATHS_MACROS=y -# default: # CONFIG_COMPILER_CXX_EXCEPTIONS is not set -# default: # CONFIG_COMPILER_CXX_RTTI is not set CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set # CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set # CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set -# default: # CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set -# default: # CONFIG_COMPILER_WARN_WRITE_STRINGS is not set CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y -# default: # CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set -# default: # CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set -# default: # CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set -# default: # CONFIG_COMPILER_DUMP_RTL_FILES is not set CONFIG_COMPILER_RT_LIB_GCCLIB=y CONFIG_COMPILER_RT_LIB_NAME="gcc" CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y # CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set -# default: # CONFIG_COMPILER_STATIC_ANALYZER is not set # end of Compiler options @@ -627,15 +576,10 @@ CONFIG_BT_NIMBLE_ROLE_CENTRAL=y CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y CONFIG_BT_NIMBLE_ROLE_OBSERVER=y -# default: # CONFIG_BT_NIMBLE_NVS_PERSIST is not set -# default: # CONFIG_BT_NIMBLE_SMP_ID_RESET is not set -# default: # CONFIG_BT_NIMBLE_SECURITY_ENABLE is not set -# default: # CONFIG_BT_NIMBLE_DEBUG is not set -# default: # CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 @@ -663,22 +607,16 @@ CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 -# default: # CONFIG_BT_NIMBLE_MESH is not set CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 -# default: # CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set -# default: # CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set CONFIG_BT_NIMBLE_WHITELIST_SIZE=1 -# default: # CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set -# default: # CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set CONFIG_BT_NIMBLE_USE_ESP_TIMER=y CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y -# default: # CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set # @@ -688,7 +626,6 @@ CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y # # GAP Appearance write permissions # -# default: # CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set # end of GAP Appearance write permissions @@ -704,7 +641,6 @@ CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 # # GAP device name write permissions # -# default: # CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set # end of GAP device name write permissions @@ -716,49 +652,33 @@ CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 -# default: # CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL is not set # end of GAP Service # # BLE Services # -# default: # CONFIG_BT_NIMBLE_HID_SERVICE is not set -# default: # CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY is not set # # Device Information Service # -# default: # CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED is not set # end of Device Information Service # end of BLE Services -# default: # CONFIG_BT_NIMBLE_VS_SUPPORT is not set -# default: # CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set -# default: # CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set -# default: # CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set -# default: # CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT is not set # @@ -772,7 +692,6 @@ CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 # end of Host-controller Transport CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 -# default: # CONFIG_BT_NIMBLE_SUBRATE is not set # end of NimBLE Options @@ -815,12 +734,9 @@ CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y CONFIG_BTDM_SCAN_DUPL_TYPE=0 CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 -# default: # CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y -# default: # CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set -# default: # CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 @@ -829,15 +745,12 @@ CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # # BLE disconnects when Instant Passed (0x28) occurs # -# default: # CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set -# default: # CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set # end of BLE disconnects when Instant Passed (0x28) occurs CONFIG_BTDM_BLE_CHAN_ASS_EN=y CONFIG_BTDM_BLE_PING_EN=y -# default: # CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 is not set CONFIG_BTDM_RESERVE_DRAM=0xdb5c CONFIG_BTDM_CTRL_HLI=y @@ -847,21 +760,17 @@ CONFIG_BTDM_CTRL_HLI=y # Common Options # CONFIG_BT_ALARM_MAX_NUM=50 -# default: # CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set # end of Common Options -# default: # CONFIG_BT_HCI_LOG_DEBUG_EN is not set # end of Bluetooth -# default: # CONFIG_BLE_MESH is not set # # Console Library # -# default: # CONFIG_CONSOLE_SORTED_HELP is not set # end of Console Library @@ -872,7 +781,6 @@ CONFIG_BT_ALARM_MAX_NUM=50 # # TWAI Configuration # -# default: # CONFIG_TWAI_ISR_IN_IRAM is not set CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y @@ -885,9 +793,7 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # Legacy ADC Driver Configuration # CONFIG_ADC_DISABLE_DAC=y -# default: # CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set # @@ -896,7 +802,6 @@ CONFIG_ADC_DISABLE_DAC=y CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y CONFIG_ADC_CAL_LUT_ENABLE=y -# default: # CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set # end of Legacy ADC Calibration Configuration # end of Legacy ADC Driver Configuration @@ -904,63 +809,49 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # # Legacy DAC Driver Configurations # -# default: # CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy DAC Driver Configurations # # Legacy MCPWM Driver Configurations # -# default: # CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy MCPWM Driver Configurations # # Legacy Timer Group Driver Configurations # -# default: # CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Timer Group Driver Configurations # # Legacy RMT Driver Configurations # -# default: # CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy RMT Driver Configurations # # Legacy I2S Driver Configurations # -# default: # CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy I2S Driver Configurations # # Legacy PCNT Driver Configurations # -# default: # CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy PCNT Driver Configurations # # Legacy SDM Driver Configurations # -# default: # CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy SDM Driver Configurations # end of Driver Configurations @@ -968,9 +859,7 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # # eFuse Bit Manager # -# default: # CONFIG_EFUSE_CUSTOM_TABLE is not set -# default: # CONFIG_EFUSE_VIRTUAL is not set # CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y @@ -982,28 +871,19 @@ CONFIG_EFUSE_MAX_BLK_LEN=192 # ESP-TLS # CONFIG_ESP_TLS_USING_MBEDTLS=y -# default: # CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set -# default: # CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set -# default: # CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set -# default: # CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set -# default: # CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set -# default: # CONFIG_ESP_TLS_PSK_VERIFICATION is not set -# default: # CONFIG_ESP_TLS_INSECURE is not set # end of ESP-TLS # # ADC and ADC Calibration # -# default: # CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set # @@ -1015,7 +895,6 @@ CONFIG_ADC_CALI_LUT_ENABLE=y # end of ADC Calibration Configurations CONFIG_ADC_DISABLE_DAC_OUTPUT=y -# default: # CONFIG_ADC_ENABLE_DEBUG_LOG is not set # end of ADC and ADC Calibration @@ -1024,9 +903,7 @@ CONFIG_ADC_DISABLE_DAC_OUTPUT=y # CONFIG_ESP_COEX_ENABLED=y CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y -# default: # CONFIG_ESP_COEX_POWER_MANAGEMENT is not set -# default: # CONFIG_ESP_COEX_GPIO_DEBUG is not set # end of Wireless Coexistence @@ -1039,11 +916,8 @@ CONFIG_ESP_ERR_TO_NAME_LOOKUP=y # # ESP-Driver:DAC Configurations # -# default: # CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_DAC_ISR_IRAM_SAFE is not set -# default: # CONFIG_DAC_ENABLE_DEBUG_LOG is not set CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # end of ESP-Driver:DAC Configurations @@ -1051,9 +925,7 @@ CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # # ESP-Driver:GPIO Configurations # -# default: # CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set -# default: # CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:GPIO Configurations @@ -1061,90 +933,68 @@ CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # ESP-Driver:GPTimer Configurations # CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y -# default: # CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_GPTIMER_ISR_IRAM_SAFE is not set -# default: # CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:GPTimer Configurations # # ESP-Driver:I2C Configurations # -# default: # CONFIG_I2C_ISR_IRAM_SAFE is not set -# default: # CONFIG_I2C_ENABLE_DEBUG_LOG is not set -# default: # CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set # end of ESP-Driver:I2C Configurations # # ESP-Driver:I2S Configurations # -# default: # CONFIG_I2S_ISR_IRAM_SAFE is not set -# default: # CONFIG_I2S_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:I2S Configurations # # ESP-Driver:LEDC Configurations # -# default: # CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:LEDC Configurations # # ESP-Driver:MCPWM Configurations # -# default: # CONFIG_MCPWM_ISR_IRAM_SAFE is not set -# default: # CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:MCPWM Configurations # # ESP-Driver:PCNT Configurations # -# default: # CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_PCNT_ISR_IRAM_SAFE is not set -# default: # CONFIG_PCNT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:PCNT Configurations # # ESP-Driver:RMT Configurations # -# default: # CONFIG_RMT_ISR_IRAM_SAFE is not set -# default: # CONFIG_RMT_RECV_FUNC_IN_IRAM is not set -# default: # CONFIG_RMT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:RMT Configurations # # ESP-Driver:Sigma Delta Modulator Configurations # -# default: # CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_SDM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Sigma Delta Modulator Configurations # # ESP-Driver:SPI Configurations # -# default: # CONFIG_SPI_MASTER_IN_IRAM is not set CONFIG_SPI_MASTER_ISR_IN_IRAM=y -# default: # CONFIG_SPI_SLAVE_IN_IRAM is not set CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # end of ESP-Driver:SPI Configurations @@ -1152,36 +1002,28 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # # ESP-Driver:Touch Sensor Configurations # -# default: # CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_TOUCH_ISR_IRAM_SAFE is not set -# default: # CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Touch Sensor Configurations # # ESP-Driver:UART Configurations # -# default: # CONFIG_UART_ISR_IN_IRAM is not set # end of ESP-Driver:UART Configurations # # Ethernet # -# default: # CONFIG_ETH_USE_ESP32_EMAC is not set -# default: # CONFIG_ETH_USE_SPI_ETHERNET is not set -# default: # CONFIG_ETH_USE_OPENETH is not set # end of Ethernet # # Event Loop Library # -# default: # CONFIG_ESP_EVENT_LOOP_PROFILING is not set CONFIG_ESP_EVENT_POST_FROM_ISR=y CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y @@ -1191,7 +1033,6 @@ CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y # GDB Stub # CONFIG_ESP_GDBSTUB_ENABLED=y -# default: # CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y CONFIG_ESP_GDBSTUB_MAX_TASKS=32 @@ -1208,11 +1049,8 @@ CONFIG_ESPHID_TASK_SIZE_BLE=4096 # ESP HTTP client # CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y -# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set -# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set -# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 # end of ESP HTTP client @@ -1224,11 +1062,8 @@ CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 CONFIG_HTTPD_MAX_URI_LEN=512 CONFIG_HTTPD_ERR_RESP_NO_DELAY=y CONFIG_HTTPD_PURGE_BUF_LEN=32 -# default: # CONFIG_HTTPD_LOG_PURGE_DATA is not set -# default: # CONFIG_HTTPD_WS_SUPPORT is not set -# default: # CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # end of HTTP Server @@ -1236,9 +1071,7 @@ CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # # ESP HTTPS OTA # -# default: # CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set -# default: # CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS OTA @@ -1246,7 +1079,6 @@ CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # # ESP HTTPS server # -# default: # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS server @@ -1293,27 +1125,20 @@ CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 # CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 -# default: # CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set -# default: # CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set # end of MAC Config # # Sleep Config # -# default: # CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y -# default: # CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y -# default: # CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 -# default: # CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set -# default: # CONFIG_ESP_SLEEP_DEBUG is not set CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y # end of Sleep Config @@ -1350,7 +1175,6 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # # ESP-Driver:LCD Controller Configurations # -# default: # CONFIG_LCD_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:LCD Controller Configurations @@ -1363,19 +1187,14 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # ESP NETIF Adapter # CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 -# default: # CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set CONFIG_ESP_NETIF_TCPIP_LWIP=y # CONFIG_ESP_NETIF_LOOPBACK is not set CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y -# default: # CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set -# default: # CONFIG_ESP_NETIF_L2_TAP is not set -# default: # CONFIG_ESP_NETIF_BRIDGE_EN is not set -# default: # CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set # end of ESP NETIF Adapter @@ -1389,44 +1208,35 @@ CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y # CONFIG_ESP_PHY_ENABLED=y CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y -# default: # CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP_PHY_MAX_TX_POWER=20 -# default: # CONFIG_ESP_PHY_REDUCE_TX_POWER is not set -# default: # CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set CONFIG_ESP_PHY_RF_CAL_PARTIAL=y # CONFIG_ESP_PHY_RF_CAL_NONE is not set # CONFIG_ESP_PHY_RF_CAL_FULL is not set CONFIG_ESP_PHY_CALIBRATION_MODE=0 -# default: # CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set -# default: # CONFIG_ESP_PHY_RECORD_USED_TIME is not set # end of PHY # # Power Management # -# default: # CONFIG_PM_ENABLE is not set -# default: # CONFIG_PM_SLP_IRAM_OPT is not set # end of Power Management # # ESP PSRAM # -# default: # CONFIG_SPIRAM is not set # end of ESP PSRAM # # ESP Ringbuf # -# default: # CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set # end of ESP Ringbuf @@ -1446,13 +1256,11 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 # # Memory # -# default: # CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set # # Non-backward compatible options # -# default: # CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set # end of Non-backward compatible options # end of Memory @@ -1460,7 +1268,6 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 # # Trace memory # -# default: # CONFIG_ESP32_TRAX is not set CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 # end of Trace memory @@ -1496,14 +1303,11 @@ CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 CONFIG_ESP_INT_WDT_CHECK_CPU1=y CONFIG_ESP_TASK_WDT_EN=y CONFIG_ESP_TASK_WDT_INIT=y -# default: # CONFIG_ESP_TASK_WDT_PANIC is not set CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# default: # CONFIG_ESP_PANIC_HANDLER_IRAM is not set -# default: # CONFIG_ESP_DEBUG_STUBS_ENABLE is not set CONFIG_ESP_DEBUG_OCDAWARE=y CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y @@ -1523,7 +1327,6 @@ CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y CONFIG_ESP_BROWNOUT_DET_LVL=0 # end of Brownout Detector -# default: # CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y # end of ESP System Settings @@ -1539,18 +1342,15 @@ CONFIG_ESP_IPC_ISR_ENABLE=y # # ESP Timer (High Resolution Timer) # -# default: # CONFIG_ESP_TIMER_PROFILING is not set CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 -# default: # CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y -# default: # CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set CONFIG_ESP_TIMER_IMPL_TG0_LAC=y # end of ESP Timer (High Resolution Timer) @@ -1569,7 +1369,6 @@ CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y # CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 -# default: # CONFIG_ESP_WIFI_CSI_ENABLED is not set CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP_WIFI_TX_BA_WIN=6 @@ -1580,17 +1379,13 @@ CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 -# default: # CONFIG_ESP_WIFI_IRAM_OPT is not set -# default: # CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set -# default: # CONFIG_ESP_WIFI_RX_IRAM_OPT is not set CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y CONFIG_ESP_WIFI_ENABLE_SAE_PK=y CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y -# default: # CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 @@ -1598,41 +1393,28 @@ CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y CONFIG_ESP_WIFI_GMAC_SUPPORT=y CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y -# default: # CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 -# default: # CONFIG_ESP_WIFI_NAN_ENABLE is not set CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y -# default: # CONFIG_ESP_WIFI_WAPI_PSK is not set -# default: # CONFIG_ESP_WIFI_11KV_SUPPORT is not set -# default: # CONFIG_ESP_WIFI_MBO_SUPPORT is not set -# default: # CONFIG_ESP_WIFI_DPP_SUPPORT is not set -# default: # CONFIG_ESP_WIFI_11R_SUPPORT is not set -# default: # CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set # # WPS Configuration Options # -# default: # CONFIG_ESP_WIFI_WPS_STRICT is not set -# default: # CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set # end of WPS Configuration Options -# default: # CONFIG_ESP_WIFI_DEBUG_PRINT is not set -# default: # CONFIG_ESP_WIFI_TESTING_OPTIONS is not set CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y -# default: # CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set # end of Wi-Fi @@ -1679,15 +1461,12 @@ CONFIG_FATFS_CODEPAGE=437 CONFIG_FATFS_FS_LOCK=0 CONFIG_FATFS_TIMEOUT_MS=10000 CONFIG_FATFS_PER_FILE_CACHE=y -# default: # CONFIG_FATFS_USE_FASTSEEK is not set CONFIG_FATFS_USE_STRFUNC_NONE=y # CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set # CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 -# default: # CONFIG_FATFS_IMMEDIATE_FSYNC is not set -# default: # CONFIG_FATFS_USE_LABEL is not set CONFIG_FATFS_LINK_LOCK=y # end of FAT Filesystem support @@ -1699,9 +1478,7 @@ CONFIG_FATFS_LINK_LOCK=y # # Kernel # -# default: # CONFIG_FREERTOS_SMP is not set -# default: # CONFIG_FREERTOS_UNICORE is not set CONFIG_FREERTOS_HZ=1000 # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set @@ -1709,12 +1486,9 @@ CONFIG_FREERTOS_HZ=1000 CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 -# default: # CONFIG_FREERTOS_USE_IDLE_HOOK is not set -# default: # CONFIG_FREERTOS_USE_TICK_HOOK is not set CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 -# default: # CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set CONFIG_FREERTOS_USE_TIMERS=y CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" @@ -1727,38 +1501,28 @@ CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 -# default: # CONFIG_FREERTOS_USE_TRACE_FACILITY is not set -# default: # CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set -# default: # CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set -# default: # CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set # end of Kernel # # Port # -# default: # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y -# default: # CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set -# default: # CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y CONFIG_FREERTOS_ISR_STACKSIZE=1536 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y -# default: # CONFIG_FREERTOS_FPU_IN_ISR is not set CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y CONFIG_FREERTOS_CORETIMER_0=y # CONFIG_FREERTOS_CORETIMER_1 is not set CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y -# default: # CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set -# default: # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set # end of Port @@ -1797,13 +1561,9 @@ CONFIG_HEAP_POISONING_DISABLED=y CONFIG_HEAP_TRACING_OFF=y # CONFIG_HEAP_TRACING_STANDALONE is not set # CONFIG_HEAP_TRACING_TOHOST is not set -# default: # CONFIG_HEAP_USE_HOOKS is not set -# default: # CONFIG_HEAP_TASK_TRACKING is not set -# default: # CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set -# default: # CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set # end of Heap memory debugging @@ -1832,7 +1592,6 @@ CONFIG_LOG_MAXIMUM_LEVEL=0 # # Level Settings # -# default: # CONFIG_LOG_MASTER_LEVEL is not set CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y # CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set @@ -1847,7 +1606,6 @@ CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 # # Format # -# default: # CONFIG_LOG_COLORS is not set CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set @@ -1859,45 +1617,31 @@ CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LWIP_ENABLE=y CONFIG_LWIP_LOCAL_HOSTNAME="espressif" -# default: # CONFIG_LWIP_NETIF_API is not set CONFIG_LWIP_TCPIP_TASK_PRIO=18 -# default: # CONFIG_LWIP_TCPIP_CORE_LOCKING is not set -# default: # CONFIG_LWIP_CHECK_THREAD_SAFETY is not set CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -# default: # CONFIG_LWIP_L2_TO_L3_COPY is not set -# default: # CONFIG_LWIP_IRAM_OPTIMIZATION is not set -# default: # CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set CONFIG_LWIP_TIMERS_ONDEMAND=y CONFIG_LWIP_ND6=y -# default: # CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set CONFIG_LWIP_MAX_SOCKETS=10 -# default: # CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set -# default: # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y CONFIG_LWIP_SO_RCVBUF=y -# default: # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP_DEFAULT_TTL=64 CONFIG_LWIP_IP4_FRAG=y CONFIG_LWIP_IP6_FRAG=y -# default: # CONFIG_LWIP_IP4_REASSEMBLY is not set -# default: # CONFIG_LWIP_IP6_REASSEMBLY is not set CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 -# default: # CONFIG_LWIP_IP_FORWARD is not set -# default: # CONFIG_LWIP_STATS is not set CONFIG_LWIP_ESP_GRATUITOUS_ARP=y CONFIG_LWIP_GARP_TMR_INTERVAL=60 @@ -1907,10 +1651,8 @@ CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y # CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set # CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set -# default: # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y -# default: # CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set CONFIG_LWIP_DHCP_OPTIONS_LEN=68 CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 @@ -1926,16 +1668,12 @@ CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y CONFIG_LWIP_DHCPS_ADD_DNS=y # end of DHCP server -# default: # CONFIG_LWIP_AUTOIP is not set CONFIG_LWIP_IPV4=y CONFIG_LWIP_IPV6=y -# default: # CONFIG_LWIP_IPV6_AUTOCONFIG is not set CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 -# default: # CONFIG_LWIP_IPV6_FORWARD is not set -# default: # CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set CONFIG_LWIP_NETIF_LOOPBACK=y CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 @@ -1959,7 +1697,6 @@ CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 CONFIG_LWIP_TCP_QUEUE_OOSEQ=y CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 -# default: # CONFIG_LWIP_TCP_SACK_OUT is not set CONFIG_LWIP_TCP_OVERSIZE_MSS=y # CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set @@ -1977,9 +1714,7 @@ CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 # # Checksums # -# default: # CONFIG_LWIP_CHECKSUM_CHECK_IP is not set -# default: # CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums @@ -1994,18 +1729,14 @@ CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 -# default: # CONFIG_LWIP_PPP_SUPPORT is not set -# default: # CONFIG_LWIP_SLIP_SUPPORT is not set # # ICMP # CONFIG_LWIP_ICMP=y -# default: # CONFIG_LWIP_MULTICAST_PING is not set -# default: # CONFIG_LWIP_BROADCAST_PING is not set # end of ICMP @@ -2019,7 +1750,6 @@ CONFIG_LWIP_MAX_RAW_PCBS=16 # SNTP # CONFIG_LWIP_SNTP_MAX_SERVERS=1 -# default: # CONFIG_LWIP_DHCP_GET_NTP_SRV is not set CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 CONFIG_LWIP_SNTP_STARTUP_DELAY=y @@ -2031,9 +1761,7 @@ CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 # CONFIG_LWIP_DNS_MAX_HOST_IP=1 CONFIG_LWIP_DNS_MAX_SERVERS=3 -# default: # CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set -# default: # CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set # end of DNS @@ -2065,7 +1793,6 @@ CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y # CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set # end of Hooks -# default: # CONFIG_LWIP_DEBUG is not set # end of LWIP @@ -2078,21 +1805,15 @@ CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 -# default: # CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set -# default: # CONFIG_MBEDTLS_DEBUG is not set # # mbedTLS v3.x related # -# default: # CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set -# default: # CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set -# default: # CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set -# default: # CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y CONFIG_MBEDTLS_PKCS7_C=y @@ -2105,35 +1826,26 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set -# default: # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set -# default: # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 # end of Certificate Bundle -# default: # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set CONFIG_MBEDTLS_CMAC_C=y CONFIG_MBEDTLS_HARDWARE_AES=y CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y CONFIG_MBEDTLS_HARDWARE_MPI=y -# default: # CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set CONFIG_MBEDTLS_HARDWARE_SHA=y CONFIG_MBEDTLS_ROM_MD5=y -# default: # CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set -# default: # CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set CONFIG_MBEDTLS_HAVE_TIME=y -# default: # CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set -# default: # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y CONFIG_MBEDTLS_SHA512_C=y -# default: # CONFIG_MBEDTLS_SHA3_C is not set CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y # CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set @@ -2160,9 +1872,7 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y CONFIG_MBEDTLS_SSL_RENEGOTIATION=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y -# default: # CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set -# default: # CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set CONFIG_MBEDTLS_SSL_ALPN=y CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y @@ -2172,21 +1882,15 @@ CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y # Symmetric Ciphers # CONFIG_MBEDTLS_AES_C=y -# default: # CONFIG_MBEDTLS_CAMELLIA_C is not set -# default: # CONFIG_MBEDTLS_DES_C is not set -# default: # CONFIG_MBEDTLS_BLOWFISH_C is not set -# default: # CONFIG_MBEDTLS_XTEA_C is not set CONFIG_MBEDTLS_CCM_C=y CONFIG_MBEDTLS_GCM_C=y -# default: # CONFIG_MBEDTLS_NIST_KW_C is not set # end of Symmetric Ciphers -# default: # CONFIG_MBEDTLS_RIPEMD160_C is not set # @@ -2201,11 +1905,9 @@ CONFIG_MBEDTLS_X509_CSR_PARSE_C=y CONFIG_MBEDTLS_ECP_C=y CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y -# default: # CONFIG_MBEDTLS_DHM_C is not set CONFIG_MBEDTLS_ECDH_C=y CONFIG_MBEDTLS_ECDSA_C=y -# default: # CONFIG_MBEDTLS_ECJPAKE_C is not set CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y @@ -2220,15 +1922,10 @@ CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y CONFIG_MBEDTLS_ECP_NIST_OPTIM=y -# default: # CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set -# default: # CONFIG_MBEDTLS_POLY1305_C is not set -# default: # CONFIG_MBEDTLS_CHACHA20_C is not set -# default: # CONFIG_MBEDTLS_HKDF_C is not set -# default: # CONFIG_MBEDTLS_THREADING_C is not set CONFIG_MBEDTLS_ERROR_STRINGS=y CONFIG_MBEDTLS_FS_IO=y @@ -2237,25 +1934,15 @@ CONFIG_MBEDTLS_FS_IO=y # # ESP-MQTT Configurations # -# default: # CONFIG_MQTT_PROTOCOL_311 is not set -# default: # CONFIG_MQTT_PROTOCOL_5 is not set -# default: # CONFIG_MQTT_TRANSPORT_SSL is not set -# default: # CONFIG_MQTT_TRANSPORT_WEBSOCKET is not set -# default: # CONFIG_MQTT_MSG_ID_INCREMENTAL is not set -# default: # CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set -# default: # CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set -# default: # CONFIG_MQTT_USE_CUSTOM_CONFIG is not set -# default: # CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set -# default: # CONFIG_MQTT_CUSTOM_OUTBOX is not set # end of ESP-MQTT Configurations @@ -2268,7 +1955,6 @@ CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y # CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set # CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y -# default: # CONFIG_NEWLIB_NANO_FORMAT is not set CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y # CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set @@ -2279,22 +1965,18 @@ CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y # # NVS # -# default: # CONFIG_NVS_ASSERT_ERROR_CHECK is not set -# default: # CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set # end of NVS # # OpenThread # -# default: # CONFIG_OPENTHREAD_ENABLED is not set # # OpenThread Spinel # -# default: # CONFIG_OPENTHREAD_SPINEL_ONLY is not set # end of OpenThread Spinel # end of OpenThread @@ -2348,7 +2030,6 @@ CONFIG_SPI_FLASH_BROWNOUT_RESET=y # Features here require specific hardware (READ DOCS FIRST!) # CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 -# default: # CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set # end of Optional and Experimental Features (READ DOCS FIRST) # end of Main Flash configuration @@ -2356,27 +2037,20 @@ CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 # # SPI Flash driver # -# default: # CONFIG_SPI_FLASH_VERIFY_WRITE is not set -# default: # CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y # CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set # CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set -# default: # CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set -# default: # CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 -# default: # CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set -# default: # CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set -# default: # CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set # @@ -2391,9 +2065,7 @@ CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y -# default: # CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set -# default: # CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set # end of Auto-detect flash chips @@ -2410,17 +2082,14 @@ CONFIG_SPIFFS_MAX_PARTITIONS=3 # CONFIG_SPIFFS_CACHE=y CONFIG_SPIFFS_CACHE_WR=y -# default: # CONFIG_SPIFFS_CACHE_STATS is not set # end of SPIFFS Cache Configuration CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 -# default: # CONFIG_SPIFFS_GC_STATS is not set CONFIG_SPIFFS_PAGE_SIZE=256 CONFIG_SPIFFS_OBJ_NAME_LEN=32 -# default: # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y @@ -2430,17 +2099,11 @@ CONFIG_SPIFFS_USE_MTIME=y # # Debug Configuration # -# default: # CONFIG_SPIFFS_DBG is not set -# default: # CONFIG_SPIFFS_API_DBG is not set -# default: # CONFIG_SPIFFS_GC_DBG is not set -# default: # CONFIG_SPIFFS_CACHE_DBG is not set -# default: # CONFIG_SPIFFS_CHECK_DBG is not set -# default: # CONFIG_SPIFFS_TEST_VISUALISATION is not set # end of Debug Configuration # end of SPIFFS Configuration @@ -2454,7 +2117,6 @@ CONFIG_SPIFFS_USE_MTIME=y # CONFIG_WS_TRANSPORT=y CONFIG_WS_BUFFER_SIZE=1024 -# default: # CONFIG_WS_DYNAMIC_BUFFER is not set # end of Websocket # end of TCP Transport @@ -2462,7 +2124,6 @@ CONFIG_WS_BUFFER_SIZE=1024 # # Ultra Low Power (ULP) Co-processor # -# default: # CONFIG_ULP_COPROC_ENABLED is not set # @@ -2476,14 +2137,10 @@ CONFIG_WS_BUFFER_SIZE=1024 # CONFIG_UNITY_ENABLE_FLOAT=y CONFIG_UNITY_ENABLE_DOUBLE=y -# default: # CONFIG_UNITY_ENABLE_64BIT is not set -# default: # CONFIG_UNITY_ENABLE_COLOR is not set CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y -# default: # CONFIG_UNITY_ENABLE_FIXTURE is not set -# default: # CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set # end of Unity unit testing library @@ -2494,7 +2151,6 @@ CONFIG_VFS_SUPPORT_IO=y CONFIG_VFS_SUPPORT_DIR=y CONFIG_VFS_SUPPORT_SELECT=y CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y -# default: # CONFIG_VFS_SELECT_IN_RAM is not set CONFIG_VFS_SUPPORT_TERMIOS=y CONFIG_VFS_MAX_COUNT=8 @@ -2521,14 +2177,10 @@ CONFIG_WL_SECTOR_SIZE=4096 # CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 -# default: # CONFIG_WIFI_PROV_BLE_BONDING is not set CONFIG_WIFI_PROV_BLE_SEC_CONN=y -# default: # CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set -# default: # CONFIG_WIFI_PROV_BLE_NOTIFY is not set -# default: # CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set @@ -2537,33 +2189,9 @@ CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # # Zigbee # -# default: # CONFIG_ZB_ENABLED is not set # end of Zigbee -# -# esp-modem -# -# default: -CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y -# default: -# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set -# default: -CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 -# default: -# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set -# default: -# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set -# default: -CONFIG_ESP_MODEM_C_API_STR_MAX=128 -# default: -# CONFIG_ESP_MODEM_URC_HANDLER is not set -# default: -# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set -# default: -# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set -# end of esp-modem - # # mDNS # @@ -2582,20 +2210,15 @@ CONFIG_MDNS_TASK_AFFINITY=0x0 # CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y -# default: # CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set # end of MDNS Memory Configuration CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 CONFIG_MDNS_TIMER_PERIOD_MS=100 -# default: # CONFIG_MDNS_NETWORKING_SOCKET is not set -# default: # CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set -# default: # CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set CONFIG_MDNS_ENABLE_CONSOLE_CLI=y -# default: # CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set CONFIG_MDNS_MULTIPLE_INSTANCE=y @@ -2613,12 +2236,9 @@ CONFIG_MDNS_PREDEF_NETIF_AP=y CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 -# default: # CONFIG_NETWORK_PROV_BLE_BONDING is not set CONFIG_NETWORK_PROV_BLE_SEC_CONN=y -# default: # CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set -# default: # CONFIG_NETWORK_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y # CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set @@ -2627,7 +2247,6 @@ CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y # # LittleFS # -# default: # CONFIG_LITTLEFS_SDMMC_SUPPORT is not set CONFIG_LITTLEFS_MAX_PARTITIONS=3 CONFIG_LITTLEFS_PAGE_SIZE=256 @@ -2638,41 +2257,29 @@ CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 CONFIG_LITTLEFS_CACHE_SIZE=512 CONFIG_LITTLEFS_BLOCK_CYCLES=512 CONFIG_LITTLEFS_USE_MTIME=y -# default: # CONFIG_LITTLEFS_USE_ONLY_HASH is not set -# default: # CONFIG_LITTLEFS_HUMAN_READABLE is not set CONFIG_LITTLEFS_MTIME_USE_SECONDS=y # CONFIG_LITTLEFS_MTIME_USE_NONCE is not set -# default: # CONFIG_LITTLEFS_SPIFFS_COMPAT is not set -# default: # CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set -# default: # CONFIG_LITTLEFS_FCNTL_GET_PATH is not set -# default: # CONFIG_LITTLEFS_MULTIVERSION is not set # CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y # CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set CONFIG_LITTLEFS_ASSERTS=y -# default: # CONFIG_LITTLEFS_MMAP_PARTITION is not set # end of LittleFS # end of Component config -# default: # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set # Deprecated options for backward compatibility # CONFIG_APP_BUILD_TYPE_ELF_RAM is not set -# default: # CONFIG_NO_BLOBS is not set -# default: # CONFIG_ESP32_NO_BLOBS is not set -# default: # CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set -# default: # CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set # CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set # CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set @@ -2681,9 +2288,7 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y # CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set # CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set CONFIG_LOG_BOOTLOADER_LEVEL=3 -# default: # CONFIG_APP_ROLLBACK_ENABLE is not set -# default: # CONFIG_FLASH_ENCRYPTION_ENABLED is not set # CONFIG_FLASHMODE_QIO is not set # CONFIG_FLASHMODE_QOUT is not set @@ -2699,13 +2304,11 @@ CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y # CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set # CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 -# default: # CONFIG_CXX_EXCEPTIONS is not set CONFIG_STACK_CHECK_NONE=y # CONFIG_STACK_CHECK_NORM is not set # CONFIG_STACK_CHECK_STRONG is not set # CONFIG_STACK_CHECK_ALL is not set -# default: # CONFIG_WARN_WRITE_STRINGS is not set # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set CONFIG_ESP32_APPTRACE_DEST_NONE=y @@ -2727,9 +2330,7 @@ CONFIG_NIMBLE_ROLE_CENTRAL=y CONFIG_NIMBLE_ROLE_PERIPHERAL=y CONFIG_NIMBLE_ROLE_BROADCASTER=y CONFIG_NIMBLE_ROLE_OBSERVER=y -# default: # CONFIG_NIMBLE_NVS_PERSIST is not set -# default: # CONFIG_NIMBLE_DEBUG is not set CONFIG_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" CONFIG_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 @@ -2746,7 +2347,6 @@ CONFIG_NIMBLE_HS_FLOW_CTRL_ITVL=1000 CONFIG_NIMBLE_HS_FLOW_CTRL_THRESH=2 CONFIG_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y CONFIG_NIMBLE_RPA_TIMEOUT=900 -# default: # CONFIG_NIMBLE_MESH is not set CONFIG_NIMBLE_CRYPTO_STACK_MBEDTLS=y CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y @@ -2766,7 +2366,6 @@ CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y # CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR is not set CONFIG_SCAN_DUPLICATE_TYPE=0 CONFIG_DUPLICATE_SCAN_CACHE_SIZE=100 -# default: # CONFIG_BLE_MESH_SCAN_DUPLICATE_EN is not set CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED=y @@ -2776,20 +2375,16 @@ CONFIG_ADC2_DISABLE_DAC=y CONFIG_SW_COEXIST_ENABLE=y CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y -# default: # CONFIG_MCPWM_ISR_IN_IRAM is not set -# default: # CONFIG_EVENT_LOOP_PROFILING is not set CONFIG_POST_EVENTS_FROM_ISR=y CONFIG_POST_EVENTS_FROM_IRAM_ISR=y CONFIG_GDBSTUB_SUPPORT_TASKS=y CONFIG_GDBSTUB_MAX_TASKS=32 -# default: # CONFIG_OTA_ALLOW_HTTP is not set # CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 -# default: # CONFIG_ESP_SYSTEM_PD_FLASH is not set CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 @@ -2807,17 +2402,12 @@ CONFIG_ESP32_XTAL_FREQ_40=y # CONFIG_ESP32_XTAL_FREQ_AUTO is not set CONFIG_ESP32_XTAL_FREQ=40 CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y -# default: # CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP32_PHY_MAX_TX_POWER=20 -# default: # CONFIG_REDUCE_PHY_TX_POWER is not set -# default: # CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set -# default: # CONFIG_SPIRAM_SUPPORT is not set -# default: # CONFIG_ESP32_SPIRAM_SUPPORT is not set # CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y @@ -2843,12 +2433,10 @@ CONFIG_INT_WDT_TIMEOUT_MS=300 CONFIG_INT_WDT_CHECK_CPU1=y CONFIG_TASK_WDT=y CONFIG_ESP_TASK_WDT=y -# default: # CONFIG_TASK_WDT_PANIC is not set CONFIG_TASK_WDT_TIMEOUT_S=5 CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# default: # CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set CONFIG_ESP32_DEBUG_OCDAWARE=y CONFIG_BROWNOUT_DET=y @@ -2871,7 +2459,6 @@ CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set CONFIG_BROWNOUT_DET_LVL=0 CONFIG_ESP32_BROWNOUT_DET_LVL=0 -# default: # CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set CONFIG_IPC_TASK_STACK_SIZE=1024 CONFIG_TIMER_TASK_STACK_SIZE=3584 @@ -2882,7 +2469,6 @@ CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 -# default: # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP32_WIFI_TX_BA_WIN=6 @@ -2893,31 +2479,20 @@ CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 -# default: # CONFIG_ESP32_WIFI_IRAM_OPT is not set -# default: # CONFIG_ESP32_WIFI_RX_IRAM_OPT is not set CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y CONFIG_WPA_MBEDTLS_CRYPTO=y CONFIG_WPA_MBEDTLS_TLS_CLIENT=y -# default: # CONFIG_WPA_WAPI_PSK is not set -# default: # CONFIG_WPA_11KV_SUPPORT is not set -# default: # CONFIG_WPA_MBO_SUPPORT is not set -# default: # CONFIG_WPA_DPP_SUPPORT is not set -# default: # CONFIG_WPA_11R_SUPPORT is not set -# default: # CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set -# default: # CONFIG_WPA_WPS_STRICT is not set -# default: # CONFIG_WPA_DEBUG_PRINT is not set -# default: # CONFIG_WPA_TESTING_OPTIONS is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set @@ -2925,10 +2500,8 @@ CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y CONFIG_TIMER_TASK_PRIORITY=1 CONFIG_TIMER_TASK_STACK_DEPTH=2048 CONFIG_TIMER_QUEUE_LENGTH=10 -# default: # CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set # CONFIG_HAL_ASSERTION_SILIENT is not set -# default: # CONFIG_L2_TO_L3_COPY is not set CONFIG_ESP_GRATUITOUS_ARP=y CONFIG_GARP_TMR_INTERVAL=60 @@ -2950,7 +2523,6 @@ CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set # CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF -# default: # CONFIG_PPP_SUPPORT is not set CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y @@ -2969,7 +2541,6 @@ CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set -# default: # CONFIG_ESP32_ULP_COPROC_ENABLED is not set CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index e02d8668..5ac6230f 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -52,7 +52,7 @@ void ErgMode::runERG() { simulationRunning = rtConfig->watts.getSimulate(); } - if (userConfig->getPTab4Pwr()) { + if (!userConfig->getPTab4Pwr()) { // add values to Power table powerTable->processPowerValue(powerBuffer, rtConfig->cad.getValue(), rtConfig->watts); } From d67268bedd73070d1219ff00be6af4c84afb19d5 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 2 Jul 2025 19:30:14 -0500 Subject: [PATCH 264/451] turned off fillbyaverage --- src/Power_Table.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index ced36193..7c6b510b 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -284,7 +284,7 @@ void PowerTable::fillTable() { } else if (step == 2) { completed = ptHelpers.linearFill(ptData); }else if (step == 3) { - ptHelpers.fillByAverage(ptData); + //ptHelpers.fillByAverage(ptData); completed = true; // this step is always completed. } newEntries = ptHelpers.getNumEntries(ptData); From e3b1715dde602c18cfd9dd70d47c1ae1b363c95a Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 2 Jul 2025 20:08:56 -0500 Subject: [PATCH 265/451] remove weighted downvoting --- src/Power_Table.cpp | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 7c6b510b..d4fc6970 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -402,31 +402,6 @@ float PowerTable::calculatePosition(float watts, float cad, float targetPos, ptI return targetPos; } -/** - * @brief Calculates a penalty value for downvoting a neighbor entry in the power table. - * - * This function computes a penalty based on the difference between the target value - * and the neighbor value. The penalty is scaled by a predefined penalty factor and - * is used to reduce the reliability of a neighbor entry when it fails validation. - * - * @param targetValue The target position value being evaluated. - * @param neighborValue The neighbor position value being compared. - * @return The calculated penalty value to be applied to the neighbor entry. - */ -int weightedDownVote(int targetValue, int neighborValue) { - // calculate diff between target and neighbor - int delta = abs(targetValue - neighborValue); - int penalty; - float penaltyFactor = 0.2; - - SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Target Value: (%d), NeighborValue: (%d)", targetValue, neighborValue); - - penalty = (delta * penaltyFactor); - - SS2K_LOG(POWERTABLE_LOG_TAG, "WEIGHTED DOWNVOTING: Delta: (%d), Penalty: (%d)", delta, penalty); - return penalty; -} - /** * @brief Applies a downvote penalty to a specific entry in the power table. * @@ -440,10 +415,11 @@ int weightedDownVote(int targetValue, int neighborValue) { */ void PowerTable::downVoteData(ptIndex index, float target, int neighbor) { // determine penalty amount before applying to failed neighbor - int penalty = weightedDownVote(target, neighbor); + int penalty = 1; if (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings < penalty) { this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings = 0; + this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition = INT16_MIN; // remove target position if readings are zero. } else { this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings -= penalty; } From 897d9fc3e68de0ceb0d1935991b445325b79ddc2 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Thu, 3 Jul 2025 14:14:37 -0500 Subject: [PATCH 266/451] fixed tests --- src/PowerTable_Helpers.cpp | 4 ++-- test/test_table_fill.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp index 0fc054dc..3e2c6651 100644 --- a/src/PowerTable_Helpers.cpp +++ b/src/PowerTable_Helpers.cpp @@ -433,7 +433,7 @@ void PTHelpers::fillByAverage(PTData& ptData) { float min_cad = points.front().first; float max_cad = points.back().first; float cad_range = max_cad - min_cad; - float distance_from_center = std::min(std::abs(center_cad - min_cad), std::abs(center_cad - max_cad)); + float distance_from_center = (std::min)((std::abs)(center_cad - min_cad), (std::abs)(center_cad - max_cad)); // If data is too far from center or range is too small, use neighbor interpolation instead if (distance_from_center > 20.0f || cad_range < 10.0f) { @@ -470,7 +470,7 @@ void PTHelpers::fillByAverage(PTData& ptData) { float neighborCenterValue = slope * center_cad + intercept; // Weight by proximity and data quality - float weight = 1.0f / (1.0f + std::abs(neighbor_j - j)); + float weight = 1.0f / (1.0f + (std::abs)(neighbor_j - j)); neighborAvg += neighborCenterValue * weight; neighborCount += weight; } diff --git a/test/test_table_fill.cpp b/test/test_table_fill.cpp index ab9c21ad..78734cd2 100644 --- a/test/test_table_fill.cpp +++ b/test/test_table_fill.cpp @@ -31,7 +31,7 @@ void TestTableFill::test_fill_incomplete_table(void) { PTHelpers helpers; // Count initial data points - int initialPoints = helpers.dataPoints(ptData); + int initialPoints = helpers.getNumEntries(ptData); logFile << "Initial data points: " << initialPoints << "\n"; int previousFilledPoints = 0; int filledPoints = 1; @@ -42,13 +42,13 @@ void TestTableFill::test_fill_incomplete_table(void) { logFile << "Applied splineFill to the table\n"; // Count filled data points - filledPoints = helpers.dataPoints(ptData); + filledPoints = helpers.getNumEntries(ptData); logFile << "Filled data points: " << filledPoints << "\n"; logFile << "Added " << (filledPoints - initialPoints) << " points\n"; } // loop through the table and check for INT16_MIN values - helpers.linearFill(ptData); + helpers.fillByAverage(ptData); // Save the filled power table const std::string outputFilePath = "test/output/power_table_filled.ptab"; savePTDataToCSV(ptData, outputFilePath); From 9e222c0ed373ec918fcb4037e926c98dd5f3c54e Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Fri, 4 Jul 2025 15:25:57 -0500 Subject: [PATCH 267/451] new completePowerTable() method --- dependencies.lock | 13 +- include/PowerTable_Helpers.h | 1 + sdkconfig.release | 429 ++++++++++++++++++++++++++ src/PowerTable_Helpers.cpp | 562 +++++++++++++++++++++++++++++++++-- src/Power_Table.cpp | 48 +-- test/data/10x5-26-25.ptab | 2 +- test/data/averageMethod.ptab | 12 + test/test_table_fill.cpp | 23 +- 8 files changed, 1026 insertions(+), 64 deletions(-) create mode 100644 test/data/averageMethod.ptab diff --git a/dependencies.lock b/dependencies.lock index 3aef0ca5..17170be1 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -41,6 +41,16 @@ dependencies: registry_url: https://components.espressif.com/ type: service version: 1.6.3 + espressif/esp_modem: + component_hash: b541c3f5765d3ba062c0d004b9ca6da6d0af908293421c2dbe046c537fb2a011 + dependencies: + - name: idf + require: private + version: '>=4.1' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.4.0 espressif/mdns: component_hash: 3ec0af5f6bce310512e90f482388d21cc7c0e99668172d2f895356165fc6f7c5 dependencies: @@ -81,10 +91,11 @@ direct_dependencies: - espressif/cbor - espressif/esp-zboss-lib - espressif/esp-zigbee-lib +- espressif/esp_modem - espressif/mdns - espressif/network_provisioning - idf - joltwallet/littlefs -manifest_hash: cdea08c215af25ecb07f34a572afe529ccee1d11a022752ebfb3b54cbc0cb5f8 +manifest_hash: e871ea1e1aff9421b8e57e1c5a4db8daeef71b071a2a17f239e5feebc4acdfc3 target: esp32 version: 2.0.0 diff --git a/include/PowerTable_Helpers.h b/include/PowerTable_Helpers.h index 9743e4ec..45cb0104 100644 --- a/include/PowerTable_Helpers.h +++ b/include/PowerTable_Helpers.h @@ -132,6 +132,7 @@ class PTHelpers { int getNumEntries(PTData& ptData, int minReadings = 0); int getTotalReadings(PTData& ptData); void fillByAverage(PTData& ptData); + void completePowerTable(PTData& data); ptIndex calculateIndex(int watts, int cad); std::pair, std::vector> getRow(int row, PTData& ptData); std::pair, std::vector> getColumn(int column, PTData& ptData); diff --git a/sdkconfig.release b/sdkconfig.release index 7b3b88bf..a9f2dc38 100644 --- a/sdkconfig.release +++ b/sdkconfig.release @@ -259,9 +259,13 @@ CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y CONFIG_APP_BUILD_GENERATE_BINARIES=y CONFIG_APP_BUILD_BOOTLOADER=y CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# default: # CONFIG_APP_REPRODUCIBLE_BUILD is not set +# default: # CONFIG_APP_NO_BLOBS is not set +# default: # CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# default: # CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set # end of Build type @@ -296,6 +300,7 @@ CONFIG_BOOTLOADER_LOG_LEVEL=3 # # Format # +# default: # CONFIG_BOOTLOADER_LOG_COLORS is not set CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y # end of Format @@ -304,23 +309,32 @@ CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y # # Serial Flash Configurations # +# default: # CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y # end of Serial Flash Configurations # CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# default: # CONFIG_BOOTLOADER_FACTORY_RESET is not set +# default: # CONFIG_BOOTLOADER_APP_TEST is not set CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y CONFIG_BOOTLOADER_WDT_ENABLE=y +# default: # CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# default: # CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# default: # CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set # end of Bootloader config @@ -328,8 +342,11 @@ CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 # Security features # CONFIG_SECURE_BOOT_V1_SUPPORTED=y +# default: # CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# default: # CONFIG_SECURE_BOOT is not set +# default: # CONFIG_SECURE_FLASH_ENC_ENABLED is not set # end of Security features @@ -337,8 +354,11 @@ CONFIG_SECURE_BOOT_V1_SUPPORTED=y # Application manager # CONFIG_APP_COMPILE_TIME_DATE=y +# default: # CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# default: # CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# default: # CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 # end of Application manager @@ -361,6 +381,7 @@ CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y # # Serial flasher config # +# default: # CONFIG_ESPTOOLPY_NO_STUB is not set # CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set @@ -382,6 +403,7 @@ CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set CONFIG_ESPTOOLPY_FLASHSIZE="2MB" +# default: # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set @@ -411,6 +433,7 @@ CONFIG_PARTITION_TABLE_MD5=y # CONFIG_ARDUINO_VARIANT="esp32" CONFIG_ENABLE_ARDUINO_DEPENDS=y +# default: # CONFIG_AUTOSTART_ARDUINO is not set # CONFIG_ARDUINO_RUN_CORE0 is not set CONFIG_ARDUINO_RUN_CORE1=y @@ -432,7 +455,9 @@ CONFIG_ARDUINO_UDP_RUN_CORE0=y # CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set CONFIG_ARDUINO_UDP_RUNNING_CORE=0 CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 +# default: # CONFIG_ARDUINO_ISR_IRAM is not set +# default: # CONFIG_DISABLE_HAL_LOCKS is not set # @@ -445,7 +470,9 @@ CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE=y # CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set # CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=0 +# default: # CONFIG_ARDUHAL_LOG_COLORS is not set +# default: # CONFIG_ARDUHAL_ESP_LOG is not set # end of Debug Log Configuration @@ -460,17 +487,25 @@ CONFIG_ARDUINO_SELECTIVE_SPI=y CONFIG_ARDUINO_SELECTIVE_Wire=y CONFIG_ARDUINO_SELECTIVE_ESP_SR=y CONFIG_ARDUINO_SELECTIVE_EEPROM=y +# default: # CONFIG_ARDUINO_SELECTIVE_Preferences is not set +# default: # CONFIG_ARDUINO_SELECTIVE_Ticker is not set CONFIG_ARDUINO_SELECTIVE_Update=y +# default: # CONFIG_ARDUINO_SELECTIVE_Zigbee is not set CONFIG_ARDUINO_SELECTIVE_FS=y +# default: # CONFIG_ARDUINO_SELECTIVE_SD is not set +# default: # CONFIG_ARDUINO_SELECTIVE_SD_MMC is not set +# default: # CONFIG_ARDUINO_SELECTIVE_SPIFFS is not set +# default: # CONFIG_ARDUINO_SELECTIVE_FFat is not set CONFIG_ARDUINO_SELECTIVE_LittleFS=y CONFIG_ARDUINO_SELECTIVE_Network=y +# default: # CONFIG_ARDUINO_SELECTIVE_Ethernet is not set CONFIG_ARDUINO_SELECTIVE_PPP=y CONFIG_ARDUINO_SELECTIVE_ArduinoOTA=y @@ -478,17 +513,23 @@ CONFIG_ARDUINO_SELECTIVE_AsyncUDP=y CONFIG_ARDUINO_SELECTIVE_DNSServer=y CONFIG_ARDUINO_SELECTIVE_ESPmDNS=y CONFIG_ARDUINO_SELECTIVE_HTTPClient=y +# default: # CONFIG_ARDUINO_SELECTIVE_Matter is not set +# default: # CONFIG_ARDUINO_SELECTIVE_NetBIOS is not set CONFIG_ARDUINO_SELECTIVE_WebServer=y CONFIG_ARDUINO_SELECTIVE_WiFi=y CONFIG_ARDUINO_SELECTIVE_NetworkClientSecure=y CONFIG_ARDUINO_SELECTIVE_WiFiProv=y CONFIG_ARDUINO_SELECTIVE_BLE=y +# default: # CONFIG_ARDUINO_SELECTIVE_BluetoothSerial is not set CONFIG_ARDUINO_SELECTIVE_SimpleBLE=y +# default: # CONFIG_ARDUINO_SELECTIVE_RainMaker is not set +# default: # CONFIG_ARDUINO_SELECTIVE_OpenThread is not set +# default: # CONFIG_ARDUINO_SELECTIVE_Insights is not set # end of Arduino Configuration @@ -505,25 +546,35 @@ CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# default: # CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# default: # CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# default: # CONFIG_COMPILER_CXX_RTTI is not set CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set # CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set # CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# default: # CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set +# default: # CONFIG_COMPILER_WARN_WRITE_STRINGS is not set CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y +# default: # CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# default: # CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# default: # CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set +# default: # CONFIG_COMPILER_DUMP_RTL_FILES is not set CONFIG_COMPILER_RT_LIB_GCCLIB=y CONFIG_COMPILER_RT_LIB_NAME="gcc" CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y # CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set +# default: # CONFIG_COMPILER_STATIC_ANALYZER is not set # end of Compiler options @@ -576,10 +627,15 @@ CONFIG_BT_NIMBLE_ROLE_CENTRAL=y CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y CONFIG_BT_NIMBLE_ROLE_OBSERVER=y +# default: # CONFIG_BT_NIMBLE_NVS_PERSIST is not set +# default: # CONFIG_BT_NIMBLE_SMP_ID_RESET is not set +# default: # CONFIG_BT_NIMBLE_SECURITY_ENABLE is not set +# default: # CONFIG_BT_NIMBLE_DEBUG is not set +# default: # CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 @@ -607,16 +663,22 @@ CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 +# default: # CONFIG_BT_NIMBLE_MESH is not set CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 +# default: # CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set +# default: # CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set CONFIG_BT_NIMBLE_WHITELIST_SIZE=1 +# default: # CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set +# default: # CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set CONFIG_BT_NIMBLE_USE_ESP_TIMER=y CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y +# default: # CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set # @@ -626,6 +688,7 @@ CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y # # GAP Appearance write permissions # +# default: # CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set # end of GAP Appearance write permissions @@ -641,6 +704,7 @@ CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 # # GAP device name write permissions # +# default: # CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set # end of GAP device name write permissions @@ -652,33 +716,49 @@ CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 +# default: # CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL is not set # end of GAP Service # # BLE Services # +# default: # CONFIG_BT_NIMBLE_HID_SERVICE is not set +# default: # CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY is not set # # Device Information Service # +# default: # CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED is not set # end of Device Information Service # end of BLE Services +# default: # CONFIG_BT_NIMBLE_VS_SUPPORT is not set +# default: # CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set +# default: # CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set +# default: # CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set +# default: # CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT is not set # @@ -692,6 +772,7 @@ CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 # end of Host-controller Transport CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 +# default: # CONFIG_BT_NIMBLE_SUBRATE is not set # end of NimBLE Options @@ -734,9 +815,12 @@ CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y CONFIG_BTDM_SCAN_DUPL_TYPE=0 CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 +# default: # CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y +# default: # CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set +# default: # CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 @@ -745,12 +829,15 @@ CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # # BLE disconnects when Instant Passed (0x28) occurs # +# default: # CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set +# default: # CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set # end of BLE disconnects when Instant Passed (0x28) occurs CONFIG_BTDM_BLE_CHAN_ASS_EN=y CONFIG_BTDM_BLE_PING_EN=y +# default: # CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 is not set CONFIG_BTDM_RESERVE_DRAM=0xdb5c CONFIG_BTDM_CTRL_HLI=y @@ -760,17 +847,21 @@ CONFIG_BTDM_CTRL_HLI=y # Common Options # CONFIG_BT_ALARM_MAX_NUM=50 +# default: # CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set # end of Common Options +# default: # CONFIG_BT_HCI_LOG_DEBUG_EN is not set # end of Bluetooth +# default: # CONFIG_BLE_MESH is not set # # Console Library # +# default: # CONFIG_CONSOLE_SORTED_HELP is not set # end of Console Library @@ -781,6 +872,7 @@ CONFIG_BT_ALARM_MAX_NUM=50 # # TWAI Configuration # +# default: # CONFIG_TWAI_ISR_IN_IRAM is not set CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y @@ -793,7 +885,9 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # Legacy ADC Driver Configuration # CONFIG_ADC_DISABLE_DAC=y +# default: # CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set # @@ -802,6 +896,7 @@ CONFIG_ADC_DISABLE_DAC=y CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y CONFIG_ADC_CAL_LUT_ENABLE=y +# default: # CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set # end of Legacy ADC Calibration Configuration # end of Legacy ADC Driver Configuration @@ -809,49 +904,63 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # # Legacy DAC Driver Configurations # +# default: # CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy DAC Driver Configurations # # Legacy MCPWM Driver Configurations # +# default: # CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy MCPWM Driver Configurations # # Legacy Timer Group Driver Configurations # +# default: # CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Timer Group Driver Configurations # # Legacy RMT Driver Configurations # +# default: # CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy RMT Driver Configurations # # Legacy I2S Driver Configurations # +# default: # CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy I2S Driver Configurations # # Legacy PCNT Driver Configurations # +# default: # CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy PCNT Driver Configurations # # Legacy SDM Driver Configurations # +# default: # CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy SDM Driver Configurations # end of Driver Configurations @@ -859,7 +968,9 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # # eFuse Bit Manager # +# default: # CONFIG_EFUSE_CUSTOM_TABLE is not set +# default: # CONFIG_EFUSE_VIRTUAL is not set # CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y @@ -871,19 +982,28 @@ CONFIG_EFUSE_MAX_BLK_LEN=192 # ESP-TLS # CONFIG_ESP_TLS_USING_MBEDTLS=y +# default: # CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set +# default: # CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# default: # CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set +# default: # CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set +# default: # CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set +# default: # CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# default: # CONFIG_ESP_TLS_INSECURE is not set # end of ESP-TLS # # ADC and ADC Calibration # +# default: # CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set # @@ -895,6 +1015,7 @@ CONFIG_ADC_CALI_LUT_ENABLE=y # end of ADC Calibration Configurations CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# default: # CONFIG_ADC_ENABLE_DEBUG_LOG is not set # end of ADC and ADC Calibration @@ -903,7 +1024,9 @@ CONFIG_ADC_DISABLE_DAC_OUTPUT=y # CONFIG_ESP_COEX_ENABLED=y CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y +# default: # CONFIG_ESP_COEX_POWER_MANAGEMENT is not set +# default: # CONFIG_ESP_COEX_GPIO_DEBUG is not set # end of Wireless Coexistence @@ -916,8 +1039,11 @@ CONFIG_ESP_ERR_TO_NAME_LOOKUP=y # # ESP-Driver:DAC Configurations # +# default: # CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_DAC_ISR_IRAM_SAFE is not set +# default: # CONFIG_DAC_ENABLE_DEBUG_LOG is not set CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # end of ESP-Driver:DAC Configurations @@ -925,7 +1051,9 @@ CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # # ESP-Driver:GPIO Configurations # +# default: # CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set +# default: # CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:GPIO Configurations @@ -933,68 +1061,90 @@ CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # ESP-Driver:GPTimer Configurations # CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y +# default: # CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# default: # CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:GPTimer Configurations # # ESP-Driver:I2C Configurations # +# default: # CONFIG_I2C_ISR_IRAM_SAFE is not set +# default: # CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# default: # CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set # end of ESP-Driver:I2C Configurations # # ESP-Driver:I2S Configurations # +# default: # CONFIG_I2S_ISR_IRAM_SAFE is not set +# default: # CONFIG_I2S_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:I2S Configurations # # ESP-Driver:LEDC Configurations # +# default: # CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:LEDC Configurations # # ESP-Driver:MCPWM Configurations # +# default: # CONFIG_MCPWM_ISR_IRAM_SAFE is not set +# default: # CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:MCPWM Configurations # # ESP-Driver:PCNT Configurations # +# default: # CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_PCNT_ISR_IRAM_SAFE is not set +# default: # CONFIG_PCNT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:PCNT Configurations # # ESP-Driver:RMT Configurations # +# default: # CONFIG_RMT_ISR_IRAM_SAFE is not set +# default: # CONFIG_RMT_RECV_FUNC_IN_IRAM is not set +# default: # CONFIG_RMT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:RMT Configurations # # ESP-Driver:Sigma Delta Modulator Configurations # +# default: # CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_SDM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Sigma Delta Modulator Configurations # # ESP-Driver:SPI Configurations # +# default: # CONFIG_SPI_MASTER_IN_IRAM is not set CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# default: # CONFIG_SPI_SLAVE_IN_IRAM is not set CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # end of ESP-Driver:SPI Configurations @@ -1002,28 +1152,36 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # # ESP-Driver:Touch Sensor Configurations # +# default: # CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_TOUCH_ISR_IRAM_SAFE is not set +# default: # CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Touch Sensor Configurations # # ESP-Driver:UART Configurations # +# default: # CONFIG_UART_ISR_IN_IRAM is not set # end of ESP-Driver:UART Configurations # # Ethernet # +# default: # CONFIG_ETH_USE_ESP32_EMAC is not set +# default: # CONFIG_ETH_USE_SPI_ETHERNET is not set +# default: # CONFIG_ETH_USE_OPENETH is not set # end of Ethernet # # Event Loop Library # +# default: # CONFIG_ESP_EVENT_LOOP_PROFILING is not set CONFIG_ESP_EVENT_POST_FROM_ISR=y CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y @@ -1033,6 +1191,7 @@ CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y # GDB Stub # CONFIG_ESP_GDBSTUB_ENABLED=y +# default: # CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y CONFIG_ESP_GDBSTUB_MAX_TASKS=32 @@ -1049,8 +1208,11 @@ CONFIG_ESPHID_TASK_SIZE_BLE=4096 # ESP HTTP client # CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 # end of ESP HTTP client @@ -1062,8 +1224,11 @@ CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 CONFIG_HTTPD_MAX_URI_LEN=512 CONFIG_HTTPD_ERR_RESP_NO_DELAY=y CONFIG_HTTPD_PURGE_BUF_LEN=32 +# default: # CONFIG_HTTPD_LOG_PURGE_DATA is not set +# default: # CONFIG_HTTPD_WS_SUPPORT is not set +# default: # CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # end of HTTP Server @@ -1071,7 +1236,9 @@ CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # # ESP HTTPS OTA # +# default: # CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# default: # CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS OTA @@ -1079,6 +1246,7 @@ CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # # ESP HTTPS server # +# default: # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS server @@ -1125,20 +1293,27 @@ CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 # CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 +# default: # CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set +# default: # CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set # end of MAC Config # # Sleep Config # +# default: # CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +# default: # CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# default: # CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 +# default: # CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set +# default: # CONFIG_ESP_SLEEP_DEBUG is not set CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y # end of Sleep Config @@ -1175,6 +1350,7 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # # ESP-Driver:LCD Controller Configurations # +# default: # CONFIG_LCD_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:LCD Controller Configurations @@ -1187,14 +1363,19 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # ESP NETIF Adapter # CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +# default: # CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set CONFIG_ESP_NETIF_TCPIP_LWIP=y # CONFIG_ESP_NETIF_LOOPBACK is not set CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y +# default: # CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# default: # CONFIG_ESP_NETIF_L2_TAP is not set +# default: # CONFIG_ESP_NETIF_BRIDGE_EN is not set +# default: # CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set # end of ESP NETIF Adapter @@ -1208,35 +1389,44 @@ CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y # CONFIG_ESP_PHY_ENABLED=y CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# default: # CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP_PHY_MAX_TX_POWER=20 +# default: # CONFIG_ESP_PHY_REDUCE_TX_POWER is not set +# default: # CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set CONFIG_ESP_PHY_RF_CAL_PARTIAL=y # CONFIG_ESP_PHY_RF_CAL_NONE is not set # CONFIG_ESP_PHY_RF_CAL_FULL is not set CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# default: # CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# default: # CONFIG_ESP_PHY_RECORD_USED_TIME is not set # end of PHY # # Power Management # +# default: # CONFIG_PM_ENABLE is not set +# default: # CONFIG_PM_SLP_IRAM_OPT is not set # end of Power Management # # ESP PSRAM # +# default: # CONFIG_SPIRAM is not set # end of ESP PSRAM # # ESP Ringbuf # +# default: # CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set # end of ESP Ringbuf @@ -1256,11 +1446,13 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 # # Memory # +# default: # CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set # # Non-backward compatible options # +# default: # CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set # end of Non-backward compatible options # end of Memory @@ -1268,6 +1460,7 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 # # Trace memory # +# default: # CONFIG_ESP32_TRAX is not set CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 # end of Trace memory @@ -1303,11 +1496,14 @@ CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 CONFIG_ESP_INT_WDT_CHECK_CPU1=y CONFIG_ESP_TASK_WDT_EN=y CONFIG_ESP_TASK_WDT_INIT=y +# default: # CONFIG_ESP_TASK_WDT_PANIC is not set CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# default: # CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# default: # CONFIG_ESP_DEBUG_STUBS_ENABLE is not set CONFIG_ESP_DEBUG_OCDAWARE=y CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y @@ -1327,6 +1523,7 @@ CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y CONFIG_ESP_BROWNOUT_DET_LVL=0 # end of Brownout Detector +# default: # CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y # end of ESP System Settings @@ -1342,15 +1539,18 @@ CONFIG_ESP_IPC_ISR_ENABLE=y # # ESP Timer (High Resolution Timer) # +# default: # CONFIG_ESP_TIMER_PROFILING is not set CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# default: # CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# default: # CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set CONFIG_ESP_TIMER_IMPL_TG0_LAC=y # end of ESP Timer (High Resolution Timer) @@ -1369,6 +1569,7 @@ CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y # CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 +# default: # CONFIG_ESP_WIFI_CSI_ENABLED is not set CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP_WIFI_TX_BA_WIN=6 @@ -1379,13 +1580,17 @@ CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +# default: # CONFIG_ESP_WIFI_IRAM_OPT is not set +# default: # CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set +# default: # CONFIG_ESP_WIFI_RX_IRAM_OPT is not set CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y CONFIG_ESP_WIFI_ENABLE_SAE_PK=y CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# default: # CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 @@ -1393,28 +1598,41 @@ CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y CONFIG_ESP_WIFI_GMAC_SUPPORT=y CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# default: # CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# default: # CONFIG_ESP_WIFI_NAN_ENABLE is not set CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# default: # CONFIG_ESP_WIFI_WAPI_PSK is not set +# default: # CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_11R_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set # # WPS Configuration Options # +# default: # CONFIG_ESP_WIFI_WPS_STRICT is not set +# default: # CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set # end of WPS Configuration Options +# default: # CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# default: # CONFIG_ESP_WIFI_TESTING_OPTIONS is not set CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y +# default: # CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set # end of Wi-Fi @@ -1461,12 +1679,15 @@ CONFIG_FATFS_CODEPAGE=437 CONFIG_FATFS_FS_LOCK=0 CONFIG_FATFS_TIMEOUT_MS=10000 CONFIG_FATFS_PER_FILE_CACHE=y +# default: # CONFIG_FATFS_USE_FASTSEEK is not set CONFIG_FATFS_USE_STRFUNC_NONE=y # CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set # CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# default: # CONFIG_FATFS_IMMEDIATE_FSYNC is not set +# default: # CONFIG_FATFS_USE_LABEL is not set CONFIG_FATFS_LINK_LOCK=y # end of FAT Filesystem support @@ -1478,7 +1699,9 @@ CONFIG_FATFS_LINK_LOCK=y # # Kernel # +# default: # CONFIG_FREERTOS_SMP is not set +# default: # CONFIG_FREERTOS_UNICORE is not set CONFIG_FREERTOS_HZ=1000 # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set @@ -1486,9 +1709,12 @@ CONFIG_FREERTOS_HZ=1000 CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +# default: # CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# default: # CONFIG_FREERTOS_USE_TICK_HOOK is not set CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# default: # CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set CONFIG_FREERTOS_USE_TIMERS=y CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" @@ -1501,28 +1727,38 @@ CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# default: # CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# default: # CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set +# default: # CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# default: # CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set # end of Kernel # # Port # +# default: # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# default: # CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set +# default: # CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y CONFIG_FREERTOS_ISR_STACKSIZE=1536 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# default: # CONFIG_FREERTOS_FPU_IN_ISR is not set CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y CONFIG_FREERTOS_CORETIMER_0=y # CONFIG_FREERTOS_CORETIMER_1 is not set CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# default: # CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +# default: # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set # end of Port @@ -1561,9 +1797,13 @@ CONFIG_HEAP_POISONING_DISABLED=y CONFIG_HEAP_TRACING_OFF=y # CONFIG_HEAP_TRACING_STANDALONE is not set # CONFIG_HEAP_TRACING_TOHOST is not set +# default: # CONFIG_HEAP_USE_HOOKS is not set +# default: # CONFIG_HEAP_TASK_TRACKING is not set +# default: # CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# default: # CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set # end of Heap memory debugging @@ -1592,6 +1832,7 @@ CONFIG_LOG_MAXIMUM_LEVEL=0 # # Level Settings # +# default: # CONFIG_LOG_MASTER_LEVEL is not set CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y # CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set @@ -1606,6 +1847,7 @@ CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 # # Format # +# default: # CONFIG_LOG_COLORS is not set CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set @@ -1617,31 +1859,45 @@ CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LWIP_ENABLE=y CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# default: # CONFIG_LWIP_NETIF_API is not set CONFIG_LWIP_TCPIP_TASK_PRIO=18 +# default: # CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# default: # CONFIG_LWIP_CHECK_THREAD_SAFETY is not set CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# default: # CONFIG_LWIP_L2_TO_L3_COPY is not set +# default: # CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# default: # CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set CONFIG_LWIP_TIMERS_ONDEMAND=y CONFIG_LWIP_ND6=y +# default: # CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set CONFIG_LWIP_MAX_SOCKETS=10 +# default: # CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# default: # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y CONFIG_LWIP_SO_RCVBUF=y +# default: # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP_DEFAULT_TTL=64 CONFIG_LWIP_IP4_FRAG=y CONFIG_LWIP_IP6_FRAG=y +# default: # CONFIG_LWIP_IP4_REASSEMBLY is not set +# default: # CONFIG_LWIP_IP6_REASSEMBLY is not set CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# default: # CONFIG_LWIP_IP_FORWARD is not set +# default: # CONFIG_LWIP_STATS is not set CONFIG_LWIP_ESP_GRATUITOUS_ARP=y CONFIG_LWIP_GARP_TMR_INTERVAL=60 @@ -1651,8 +1907,10 @@ CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y # CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set # CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set +# default: # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# default: # CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set CONFIG_LWIP_DHCP_OPTIONS_LEN=68 CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 @@ -1668,12 +1926,16 @@ CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y CONFIG_LWIP_DHCPS_ADD_DNS=y # end of DHCP server +# default: # CONFIG_LWIP_AUTOIP is not set CONFIG_LWIP_IPV4=y CONFIG_LWIP_IPV6=y +# default: # CONFIG_LWIP_IPV6_AUTOCONFIG is not set CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# default: # CONFIG_LWIP_IPV6_FORWARD is not set +# default: # CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set CONFIG_LWIP_NETIF_LOOPBACK=y CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 @@ -1697,6 +1959,7 @@ CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 CONFIG_LWIP_TCP_QUEUE_OOSEQ=y CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 +# default: # CONFIG_LWIP_TCP_SACK_OUT is not set CONFIG_LWIP_TCP_OVERSIZE_MSS=y # CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set @@ -1714,7 +1977,9 @@ CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 # # Checksums # +# default: # CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# default: # CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums @@ -1729,14 +1994,18 @@ CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 +# default: # CONFIG_LWIP_PPP_SUPPORT is not set +# default: # CONFIG_LWIP_SLIP_SUPPORT is not set # # ICMP # CONFIG_LWIP_ICMP=y +# default: # CONFIG_LWIP_MULTICAST_PING is not set +# default: # CONFIG_LWIP_BROADCAST_PING is not set # end of ICMP @@ -1750,6 +2019,7 @@ CONFIG_LWIP_MAX_RAW_PCBS=16 # SNTP # CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# default: # CONFIG_LWIP_DHCP_GET_NTP_SRV is not set CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 CONFIG_LWIP_SNTP_STARTUP_DELAY=y @@ -1761,7 +2031,9 @@ CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 # CONFIG_LWIP_DNS_MAX_HOST_IP=1 CONFIG_LWIP_DNS_MAX_SERVERS=3 +# default: # CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set +# default: # CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set # end of DNS @@ -1793,6 +2065,7 @@ CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y # CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set # end of Hooks +# default: # CONFIG_LWIP_DEBUG is not set # end of LWIP @@ -1805,15 +2078,21 @@ CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# default: # CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# default: # CONFIG_MBEDTLS_DEBUG is not set # # mbedTLS v3.x related # +# default: # CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set +# default: # CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# default: # CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# default: # CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y CONFIG_MBEDTLS_PKCS7_C=y @@ -1826,26 +2105,35 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# default: # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# default: # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 # end of Certificate Bundle +# default: # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set CONFIG_MBEDTLS_CMAC_C=y CONFIG_MBEDTLS_HARDWARE_AES=y CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y CONFIG_MBEDTLS_HARDWARE_MPI=y +# default: # CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set CONFIG_MBEDTLS_HARDWARE_SHA=y CONFIG_MBEDTLS_ROM_MD5=y +# default: # CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# default: # CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set CONFIG_MBEDTLS_HAVE_TIME=y +# default: # CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set +# default: # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y CONFIG_MBEDTLS_SHA512_C=y +# default: # CONFIG_MBEDTLS_SHA3_C is not set CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y # CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set @@ -1872,7 +2160,9 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y CONFIG_MBEDTLS_SSL_RENEGOTIATION=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# default: # CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# default: # CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set CONFIG_MBEDTLS_SSL_ALPN=y CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y @@ -1882,15 +2172,21 @@ CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y # Symmetric Ciphers # CONFIG_MBEDTLS_AES_C=y +# default: # CONFIG_MBEDTLS_CAMELLIA_C is not set +# default: # CONFIG_MBEDTLS_DES_C is not set +# default: # CONFIG_MBEDTLS_BLOWFISH_C is not set +# default: # CONFIG_MBEDTLS_XTEA_C is not set CONFIG_MBEDTLS_CCM_C=y CONFIG_MBEDTLS_GCM_C=y +# default: # CONFIG_MBEDTLS_NIST_KW_C is not set # end of Symmetric Ciphers +# default: # CONFIG_MBEDTLS_RIPEMD160_C is not set # @@ -1905,9 +2201,11 @@ CONFIG_MBEDTLS_X509_CSR_PARSE_C=y CONFIG_MBEDTLS_ECP_C=y CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y +# default: # CONFIG_MBEDTLS_DHM_C is not set CONFIG_MBEDTLS_ECDH_C=y CONFIG_MBEDTLS_ECDSA_C=y +# default: # CONFIG_MBEDTLS_ECJPAKE_C is not set CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y @@ -1922,10 +2220,15 @@ CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# default: # CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set +# default: # CONFIG_MBEDTLS_POLY1305_C is not set +# default: # CONFIG_MBEDTLS_CHACHA20_C is not set +# default: # CONFIG_MBEDTLS_HKDF_C is not set +# default: # CONFIG_MBEDTLS_THREADING_C is not set CONFIG_MBEDTLS_ERROR_STRINGS=y CONFIG_MBEDTLS_FS_IO=y @@ -1934,15 +2237,25 @@ CONFIG_MBEDTLS_FS_IO=y # # ESP-MQTT Configurations # +# default: # CONFIG_MQTT_PROTOCOL_311 is not set +# default: # CONFIG_MQTT_PROTOCOL_5 is not set +# default: # CONFIG_MQTT_TRANSPORT_SSL is not set +# default: # CONFIG_MQTT_TRANSPORT_WEBSOCKET is not set +# default: # CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# default: # CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# default: # CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# default: # CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# default: # CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# default: # CONFIG_MQTT_CUSTOM_OUTBOX is not set # end of ESP-MQTT Configurations @@ -1955,6 +2268,7 @@ CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y # CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set # CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# default: # CONFIG_NEWLIB_NANO_FORMAT is not set CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y # CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set @@ -1965,18 +2279,22 @@ CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y # # NVS # +# default: # CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# default: # CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set # end of NVS # # OpenThread # +# default: # CONFIG_OPENTHREAD_ENABLED is not set # # OpenThread Spinel # +# default: # CONFIG_OPENTHREAD_SPINEL_ONLY is not set # end of OpenThread Spinel # end of OpenThread @@ -2030,6 +2348,7 @@ CONFIG_SPI_FLASH_BROWNOUT_RESET=y # Features here require specific hardware (READ DOCS FIRST!) # CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 +# default: # CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set # end of Optional and Experimental Features (READ DOCS FIRST) # end of Main Flash configuration @@ -2037,20 +2356,27 @@ CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 # # SPI Flash driver # +# default: # CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# default: # CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y # CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set # CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# default: # CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set +# default: # CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# default: # CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# default: # CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# default: # CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set # @@ -2065,7 +2391,9 @@ CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +# default: # CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# default: # CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set # end of Auto-detect flash chips @@ -2082,14 +2410,17 @@ CONFIG_SPIFFS_MAX_PARTITIONS=3 # CONFIG_SPIFFS_CACHE=y CONFIG_SPIFFS_CACHE_WR=y +# default: # CONFIG_SPIFFS_CACHE_STATS is not set # end of SPIFFS Cache Configuration CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 +# default: # CONFIG_SPIFFS_GC_STATS is not set CONFIG_SPIFFS_PAGE_SIZE=256 CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# default: # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y @@ -2099,11 +2430,17 @@ CONFIG_SPIFFS_USE_MTIME=y # # Debug Configuration # +# default: # CONFIG_SPIFFS_DBG is not set +# default: # CONFIG_SPIFFS_API_DBG is not set +# default: # CONFIG_SPIFFS_GC_DBG is not set +# default: # CONFIG_SPIFFS_CACHE_DBG is not set +# default: # CONFIG_SPIFFS_CHECK_DBG is not set +# default: # CONFIG_SPIFFS_TEST_VISUALISATION is not set # end of Debug Configuration # end of SPIFFS Configuration @@ -2117,6 +2454,7 @@ CONFIG_SPIFFS_USE_MTIME=y # CONFIG_WS_TRANSPORT=y CONFIG_WS_BUFFER_SIZE=1024 +# default: # CONFIG_WS_DYNAMIC_BUFFER is not set # end of Websocket # end of TCP Transport @@ -2124,6 +2462,7 @@ CONFIG_WS_BUFFER_SIZE=1024 # # Ultra Low Power (ULP) Co-processor # +# default: # CONFIG_ULP_COPROC_ENABLED is not set # @@ -2137,10 +2476,14 @@ CONFIG_WS_BUFFER_SIZE=1024 # CONFIG_UNITY_ENABLE_FLOAT=y CONFIG_UNITY_ENABLE_DOUBLE=y +# default: # CONFIG_UNITY_ENABLE_64BIT is not set +# default: # CONFIG_UNITY_ENABLE_COLOR is not set CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# default: # CONFIG_UNITY_ENABLE_FIXTURE is not set +# default: # CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set # end of Unity unit testing library @@ -2151,6 +2494,7 @@ CONFIG_VFS_SUPPORT_IO=y CONFIG_VFS_SUPPORT_DIR=y CONFIG_VFS_SUPPORT_SELECT=y CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +# default: # CONFIG_VFS_SELECT_IN_RAM is not set CONFIG_VFS_SUPPORT_TERMIOS=y CONFIG_VFS_MAX_COUNT=8 @@ -2177,10 +2521,14 @@ CONFIG_WL_SECTOR_SIZE=4096 # CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# default: # CONFIG_WIFI_PROV_BLE_BONDING is not set CONFIG_WIFI_PROV_BLE_SEC_CONN=y +# default: # CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set +# default: # CONFIG_WIFI_PROV_BLE_NOTIFY is not set +# default: # CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set @@ -2189,9 +2537,33 @@ CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # # Zigbee # +# default: # CONFIG_ZB_ENABLED is not set # end of Zigbee +# +# esp-modem +# +# default: +CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y +# default: +# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set +# default: +CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 +# default: +# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set +# default: +# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set +# default: +CONFIG_ESP_MODEM_C_API_STR_MAX=128 +# default: +# CONFIG_ESP_MODEM_URC_HANDLER is not set +# default: +# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set +# default: +# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set +# end of esp-modem + # # mDNS # @@ -2210,15 +2582,20 @@ CONFIG_MDNS_TASK_AFFINITY=0x0 # CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y +# default: # CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set # end of MDNS Memory Configuration CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 CONFIG_MDNS_TIMER_PERIOD_MS=100 +# default: # CONFIG_MDNS_NETWORKING_SOCKET is not set +# default: # CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set +# default: # CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set CONFIG_MDNS_ENABLE_CONSOLE_CLI=y +# default: # CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set CONFIG_MDNS_MULTIPLE_INSTANCE=y @@ -2236,9 +2613,12 @@ CONFIG_MDNS_PREDEF_NETIF_AP=y CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 +# default: # CONFIG_NETWORK_PROV_BLE_BONDING is not set CONFIG_NETWORK_PROV_BLE_SEC_CONN=y +# default: # CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set +# default: # CONFIG_NETWORK_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y # CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set @@ -2247,6 +2627,7 @@ CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y # # LittleFS # +# default: # CONFIG_LITTLEFS_SDMMC_SUPPORT is not set CONFIG_LITTLEFS_MAX_PARTITIONS=3 CONFIG_LITTLEFS_PAGE_SIZE=256 @@ -2257,29 +2638,41 @@ CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 CONFIG_LITTLEFS_CACHE_SIZE=512 CONFIG_LITTLEFS_BLOCK_CYCLES=512 CONFIG_LITTLEFS_USE_MTIME=y +# default: # CONFIG_LITTLEFS_USE_ONLY_HASH is not set +# default: # CONFIG_LITTLEFS_HUMAN_READABLE is not set CONFIG_LITTLEFS_MTIME_USE_SECONDS=y # CONFIG_LITTLEFS_MTIME_USE_NONCE is not set +# default: # CONFIG_LITTLEFS_SPIFFS_COMPAT is not set +# default: # CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set +# default: # CONFIG_LITTLEFS_FCNTL_GET_PATH is not set +# default: # CONFIG_LITTLEFS_MULTIVERSION is not set # CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y # CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set CONFIG_LITTLEFS_ASSERTS=y +# default: # CONFIG_LITTLEFS_MMAP_PARTITION is not set # end of LittleFS # end of Component config +# default: # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set # Deprecated options for backward compatibility # CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# default: # CONFIG_NO_BLOBS is not set +# default: # CONFIG_ESP32_NO_BLOBS is not set +# default: # CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# default: # CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set # CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set # CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set @@ -2288,7 +2681,9 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y # CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set # CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set CONFIG_LOG_BOOTLOADER_LEVEL=3 +# default: # CONFIG_APP_ROLLBACK_ENABLE is not set +# default: # CONFIG_FLASH_ENCRYPTION_ENABLED is not set # CONFIG_FLASHMODE_QIO is not set # CONFIG_FLASHMODE_QOUT is not set @@ -2304,11 +2699,13 @@ CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y # CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set # CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# default: # CONFIG_CXX_EXCEPTIONS is not set CONFIG_STACK_CHECK_NONE=y # CONFIG_STACK_CHECK_NORM is not set # CONFIG_STACK_CHECK_STRONG is not set # CONFIG_STACK_CHECK_ALL is not set +# default: # CONFIG_WARN_WRITE_STRINGS is not set # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set CONFIG_ESP32_APPTRACE_DEST_NONE=y @@ -2330,7 +2727,9 @@ CONFIG_NIMBLE_ROLE_CENTRAL=y CONFIG_NIMBLE_ROLE_PERIPHERAL=y CONFIG_NIMBLE_ROLE_BROADCASTER=y CONFIG_NIMBLE_ROLE_OBSERVER=y +# default: # CONFIG_NIMBLE_NVS_PERSIST is not set +# default: # CONFIG_NIMBLE_DEBUG is not set CONFIG_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" CONFIG_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 @@ -2347,6 +2746,7 @@ CONFIG_NIMBLE_HS_FLOW_CTRL_ITVL=1000 CONFIG_NIMBLE_HS_FLOW_CTRL_THRESH=2 CONFIG_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y CONFIG_NIMBLE_RPA_TIMEOUT=900 +# default: # CONFIG_NIMBLE_MESH is not set CONFIG_NIMBLE_CRYPTO_STACK_MBEDTLS=y CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y @@ -2366,6 +2766,7 @@ CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y # CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR is not set CONFIG_SCAN_DUPLICATE_TYPE=0 CONFIG_DUPLICATE_SCAN_CACHE_SIZE=100 +# default: # CONFIG_BLE_MESH_SCAN_DUPLICATE_EN is not set CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED=y @@ -2375,16 +2776,20 @@ CONFIG_ADC2_DISABLE_DAC=y CONFIG_SW_COEXIST_ENABLE=y CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y +# default: # CONFIG_MCPWM_ISR_IN_IRAM is not set +# default: # CONFIG_EVENT_LOOP_PROFILING is not set CONFIG_POST_EVENTS_FROM_ISR=y CONFIG_POST_EVENTS_FROM_IRAM_ISR=y CONFIG_GDBSTUB_SUPPORT_TASKS=y CONFIG_GDBSTUB_MAX_TASKS=32 +# default: # CONFIG_OTA_ALLOW_HTTP is not set # CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 +# default: # CONFIG_ESP_SYSTEM_PD_FLASH is not set CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 @@ -2402,12 +2807,17 @@ CONFIG_ESP32_XTAL_FREQ_40=y # CONFIG_ESP32_XTAL_FREQ_AUTO is not set CONFIG_ESP32_XTAL_FREQ=40 CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# default: # CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# default: # CONFIG_REDUCE_PHY_TX_POWER is not set +# default: # CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set +# default: # CONFIG_SPIRAM_SUPPORT is not set +# default: # CONFIG_ESP32_SPIRAM_SUPPORT is not set # CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y @@ -2433,10 +2843,12 @@ CONFIG_INT_WDT_TIMEOUT_MS=300 CONFIG_INT_WDT_CHECK_CPU1=y CONFIG_TASK_WDT=y CONFIG_ESP_TASK_WDT=y +# default: # CONFIG_TASK_WDT_PANIC is not set CONFIG_TASK_WDT_TIMEOUT_S=5 CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# default: # CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set CONFIG_ESP32_DEBUG_OCDAWARE=y CONFIG_BROWNOUT_DET=y @@ -2459,6 +2871,7 @@ CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set CONFIG_BROWNOUT_DET_LVL=0 CONFIG_ESP32_BROWNOUT_DET_LVL=0 +# default: # CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set CONFIG_IPC_TASK_STACK_SIZE=1024 CONFIG_TIMER_TASK_STACK_SIZE=3584 @@ -2469,6 +2882,7 @@ CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# default: # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP32_WIFI_TX_BA_WIN=6 @@ -2479,20 +2893,31 @@ CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +# default: # CONFIG_ESP32_WIFI_IRAM_OPT is not set +# default: # CONFIG_ESP32_WIFI_RX_IRAM_OPT is not set CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y CONFIG_WPA_MBEDTLS_CRYPTO=y CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# default: # CONFIG_WPA_WAPI_PSK is not set +# default: # CONFIG_WPA_11KV_SUPPORT is not set +# default: # CONFIG_WPA_MBO_SUPPORT is not set +# default: # CONFIG_WPA_DPP_SUPPORT is not set +# default: # CONFIG_WPA_11R_SUPPORT is not set +# default: # CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set +# default: # CONFIG_WPA_WPS_STRICT is not set +# default: # CONFIG_WPA_DEBUG_PRINT is not set +# default: # CONFIG_WPA_TESTING_OPTIONS is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set @@ -2500,8 +2925,10 @@ CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y CONFIG_TIMER_TASK_PRIORITY=1 CONFIG_TIMER_TASK_STACK_DEPTH=2048 CONFIG_TIMER_QUEUE_LENGTH=10 +# default: # CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set # CONFIG_HAL_ASSERTION_SILIENT is not set +# default: # CONFIG_L2_TO_L3_COPY is not set CONFIG_ESP_GRATUITOUS_ARP=y CONFIG_GARP_TMR_INTERVAL=60 @@ -2523,6 +2950,7 @@ CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set # CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# default: # CONFIG_PPP_SUPPORT is not set CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y @@ -2541,6 +2969,7 @@ CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +# default: # CONFIG_ESP32_ULP_COPROC_ENABLED is not set CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y diff --git a/src/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp index 3e2c6651..b6bb3fdc 100644 --- a/src/PowerTable_Helpers.cpp +++ b/src/PowerTable_Helpers.cpp @@ -405,6 +405,8 @@ bool PTHelpers::extrapolateEmptyIndices(int outerIndex, const std::vector& * 2. Computes the average increase in target position per cadence increment for each wattage column. * 3. For each empty or invalid cell, estimates its value based on the center average and the average * increase per cadence step, filling in the missing data accordingly. + * 4. Validates that each filled value maintains proper ordering relative to neighbors. + * 5. Applies a second pass to correct outlier rows and fix downward trends. * * If a cell was previously filled by another method, the function averages the new estimate with the * existing value to provide a smoother result. @@ -415,7 +417,7 @@ void PTHelpers::fillByAverage(PTData& ptData) { std::vector centerAverageRow(POWERTABLE_WATT_SIZE, 0.0f); std::vector validCounts(POWERTABLE_WATT_SIZE, 0); int mid_cad_index = POWERTABLE_CAD_SIZE / 2; - float center_cad = static_cast(MINIMUM_TABLE_CAD + mid_cad_index * POWERTABLE_CAD_INCREMENT); + float center_cad = static_cast(MINIMUM_TABLE_CAD + mid_cad_index * POWERTABLE_CAD_INCREMENT); // 1. Calculate the center average row using improved regression for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { @@ -430,19 +432,22 @@ void PTHelpers::fillByAverage(PTData& ptData) { if (points.size() >= 2) { // Check if data is clustered far from center - float min_cad = points.front().first; - float max_cad = points.back().first; - float cad_range = max_cad - min_cad; + float min_cad = points.front().first; + float max_cad = points.back().first; + float cad_range = max_cad - min_cad; float distance_from_center = (std::min)((std::abs)(center_cad - min_cad), (std::abs)(center_cad - max_cad)); - + // If data is too far from center or range is too small, use neighbor interpolation instead - if (distance_from_center > 20.0f || cad_range < 10.0f) { + float centerDistanceThreshold = POWERTABLE_CAD_INCREMENT * 4.0f; // 4 cadence increments from center + float minimumCadenceRange = POWERTABLE_CAD_INCREMENT * 2.0f; // At least 2 cadence increments of data + + if (distance_from_center > centerDistanceThreshold || cad_range < minimumCadenceRange) { // Try to interpolate from neighboring power levels float neighborAvg = 0.0f; int neighborCount = 0; - + // Check left and right neighbors - for (int neighbor_j = std::max(0, j-2); neighbor_j <= std::min(POWERTABLE_WATT_SIZE-1, j+2); neighbor_j++) { + for (int neighbor_j = std::max(0, j - 2); neighbor_j <= std::min(POWERTABLE_WATT_SIZE - 1, j + 2); neighbor_j++) { if (neighbor_j != j && validCounts[neighbor_j] > 0) { // Get neighbor's data and check if it has data near center std::vector> neighborPoints; @@ -452,7 +457,7 @@ void PTHelpers::fillByAverage(PTData& ptData) { neighborPoints.push_back({cad, static_cast(ptData.tableRow[i].tableEntry[neighbor_j].targetPosition)}); } } - + if (neighborPoints.size() >= 2) { // Calculate neighbor's center value float sum_x = 0, sum_y = 0, sum_xy = 0, sum_x2 = 0; @@ -462,13 +467,13 @@ void PTHelpers::fillByAverage(PTData& ptData) { sum_xy += p.first * p.second; sum_x2 += p.first * p.first; } - float n = neighborPoints.size(); + float n = neighborPoints.size(); float denom = (n * sum_x2 - sum_x * sum_x); if (denom != 0) { - float slope = (n * sum_xy - sum_x * sum_y) / denom; - float intercept = (sum_y - slope * sum_x) / n; + float slope = (n * sum_xy - sum_x * sum_y) / denom; + float intercept = (sum_y - slope * sum_x) / n; float neighborCenterValue = slope * center_cad + intercept; - + // Weight by proximity and data quality float weight = 1.0f / (1.0f + (std::abs)(neighbor_j - j)); neighborAvg += neighborCenterValue * weight; @@ -477,7 +482,7 @@ void PTHelpers::fillByAverage(PTData& ptData) { } } } - + if (neighborCount > 0) { centerAverageRow[j] = neighborAvg / neighborCount; } else { @@ -495,17 +500,17 @@ void PTHelpers::fillByAverage(PTData& ptData) { sum_xy += p.first * p.second; sum_x2 += p.first * p.first; } - float n = points.size(); - float denom = (n * sum_x2 - sum_x * sum_x); - float slope = (denom != 0) ? (n * sum_xy - sum_x * sum_y) / denom : 0; - float intercept = (sum_y - slope * sum_x) / n; + float n = points.size(); + float denom = (n * sum_x2 - sum_x * sum_x); + float slope = (denom != 0) ? (n * sum_xy - sum_x * sum_y) / denom : 0; + float intercept = (sum_y - slope * sum_x) / n; centerAverageRow[j] = slope * center_cad + intercept; } } else if (points.size() == 1) { centerAverageRow[j] = points[0].second; } } - + // 2. Calculate the average increase in target position per cadence increment for each column std::vector averageIncreasePerCadence(POWERTABLE_WATT_SIZE, 0.0f); for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { @@ -522,26 +527,324 @@ void PTHelpers::fillByAverage(PTData& ptData) { } } - // 3. Fill empty cells based on the average row and average increase + // Helper function to get neighbor values + auto getNeighborValue = [&](int i, int j, int di, int dj) -> int16_t { + int ni = i + di; + int nj = j + dj; + if (ni >= 0 && ni < POWERTABLE_CAD_SIZE && nj >= 0 && nj < POWERTABLE_WATT_SIZE) { + return ptData.tableRow[ni].tableEntry[nj].targetPosition; + } + return INT16_MIN; + }; + + // Helper function to count valid neighbors + auto countValidNeighbors = [&](int i, int j) -> int { + int count = 0; + if (getNeighborValue(i, j, 0, -1) != INT16_MIN) count++; // left + if (getNeighborValue(i, j, 0, 1) != INT16_MIN) count++; // right + if (getNeighborValue(i, j, -1, 0) != INT16_MIN) count++; // top + if (getNeighborValue(i, j, 1, 0) != INT16_MIN) count++; // bottom + return count; + }; + + // Helper function to apply flexible constraints + auto applyFlexibleConstraints = [&](int i, int j, float baseValue) -> int16_t { + int16_t leftNeighbor = getNeighborValue(i, j, 0, -1); + int16_t rightNeighbor = getNeighborValue(i, j, 0, 1); + int16_t topNeighbor = getNeighborValue(i, j, -1, 0); + int16_t bottomNeighbor = getNeighborValue(i, j, 1, 0); + + int validNeighborCount = countValidNeighbors(i, j); + float adjustedValue = baseValue; + + // If we have very few neighbors, be more lenient with constraints + if (validNeighborCount <= 1) { + // Only apply minimal constraints - allow more deviation from trend + const float tolerance = POWERTABLE_CAD_INCREMENT * 10.0f; // Allow larger deviations when few neighbors (50 units if CAD_INCREMENT=5) + + if (leftNeighbor != INT16_MIN) { + adjustedValue = std::max(adjustedValue, static_cast(leftNeighbor - tolerance)); + } + if (rightNeighbor != INT16_MIN) { + adjustedValue = std::min(adjustedValue, static_cast(rightNeighbor + tolerance)); + } + if (topNeighbor != INT16_MIN) { + adjustedValue = std::min(adjustedValue, static_cast(topNeighbor + tolerance)); + } + if (bottomNeighbor != INT16_MIN) { + adjustedValue = std::max(adjustedValue, static_cast(bottomNeighbor - tolerance)); + } + } else { + // Apply normal constraints when we have sufficient neighbor data + const float tolerance = POWERTABLE_CAD_INCREMENT * 2.0f; // Smaller tolerance when we have more data (10 units if CAD_INCREMENT=5) + + // Ensure value follows general trend but with some tolerance + if (leftNeighbor != INT16_MIN) { + adjustedValue = std::max(adjustedValue, static_cast(leftNeighbor + 1)); + } + if (bottomNeighbor != INT16_MIN) { + adjustedValue = std::max(adjustedValue, static_cast(bottomNeighbor + 1)); + } + if (topNeighbor != INT16_MIN) { + adjustedValue = std::min(adjustedValue, static_cast(topNeighbor - 1)); + } + if (rightNeighbor != INT16_MIN) { + adjustedValue = std::min(adjustedValue, static_cast(rightNeighbor - 1)); + } + + // Check for impossible constraints and relax if needed + float minRequired = -std::numeric_limits::infinity(); + float maxAllowed = std::numeric_limits::infinity(); + + if (leftNeighbor != INT16_MIN) minRequired = std::max(minRequired, static_cast(leftNeighbor + 1)); + if (bottomNeighbor != INT16_MIN) minRequired = std::max(minRequired, static_cast(bottomNeighbor + 1)); + if (topNeighbor != INT16_MIN) maxAllowed = std::min(maxAllowed, static_cast(topNeighbor - 1)); + if (rightNeighbor != INT16_MIN) maxAllowed = std::min(maxAllowed, static_cast(rightNeighbor - 1)); + + if (minRequired > maxAllowed) { + // Constraints conflict - use weighted average favoring the trend + float trendWeight = 0.7f; + adjustedValue = trendWeight * baseValue + (1.0f - trendWeight) * ((minRequired + maxAllowed) / 2.0f); + } + } + + return static_cast(round(adjustedValue)); + }; + + // 3. Fill empty cells based on the average row and average increase, with flexible neighbor validation for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { // Only fill cells that have not been populated with real data if (ptData.tableRow[i].tableEntry[j].readings < 1) { - if (validCounts[j] > 0) { // Only fill if there was data in this column to create an average - int distance = i - mid_cad_index; - float newValue = centerAverageRow[j] + (averageIncreasePerCadence[j] * distance); - int16_t intNewValue = static_cast(round(newValue)); + float newValue = 0.0f; + bool hasValue = false; + + if (validCounts[j] > 0) { + // Use column-based average if we have data for this column + int distance = i - mid_cad_index; + newValue = centerAverageRow[j] + (averageIncreasePerCadence[j] * distance); + hasValue = true; + } else { + // Column is completely empty - interpolate from neighboring columns + float leftValue = 0.0f, rightValue = 0.0f; + bool hasLeft = false, hasRight = false; + + // Find nearest left column with data + for (int left_j = j - 1; left_j >= 0; --left_j) { + if (validCounts[left_j] > 0) { + int distance = i - mid_cad_index; + leftValue = centerAverageRow[left_j] + (averageIncreasePerCadence[left_j] * distance); + hasLeft = true; + break; + } + } + + // Find nearest right column with data + for (int right_j = j + 1; right_j < POWERTABLE_WATT_SIZE; ++right_j) { + if (validCounts[right_j] > 0) { + int distance = i - mid_cad_index; + rightValue = centerAverageRow[right_j] + (averageIncreasePerCadence[right_j] * distance); + hasRight = true; + break; + } + } + + // Interpolate between left and right neighbors + if (hasLeft && hasRight) { + // Linear interpolation between left and right columns + float ratio = 0.5f; // Simple midpoint for now, could be more sophisticated + newValue = leftValue + (rightValue - leftValue) * ratio; + hasValue = true; + } else if (hasLeft) { + // Extrapolate from left neighbor + newValue = leftValue + (leftValue * 0.1f); // Add 10% increase as reasonable extrapolation + hasValue = true; + } else if (hasRight) { + // Extrapolate from right neighbor + newValue = rightValue - (rightValue * 0.1f); // Subtract 10% as reasonable extrapolation + hasValue = true; + } + } + + if (hasValue) { + // Apply flexible constraints based on neighbor availability + int16_t constrainedValue = applyFlexibleConstraints(i, j, newValue); // If the cell was already filled by another method, average with the new value if (ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - ptData.tableRow[i].tableEntry[j].targetPosition = round((ptData.tableRow[i].tableEntry[j].targetPosition + intNewValue) / 2.0f); + float existingValue = static_cast(ptData.tableRow[i].tableEntry[j].targetPosition); + float blendedValue = (existingValue + constrainedValue) / 2.0f; + int16_t finalValue = applyFlexibleConstraints(i, j, blendedValue); + ptData.tableRow[i].tableEntry[j].targetPosition = finalValue; } else { - ptData.tableRow[i].tableEntry[j].targetPosition = intNewValue; + ptData.tableRow[i].tableEntry[j].targetPosition = constrainedValue; + } + } + } + } + } + + // 4. SECOND PASS: Detect and correct outlier rows and downward trends + + // Calculate overall table statistics for outlier detection + std::vector rowAverages(POWERTABLE_CAD_SIZE, 0.0f); + std::vector rowValidCounts(POWERTABLE_CAD_SIZE, 0); + + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + float sum = 0.0f; + int count = 0; + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + sum += ptData.tableRow[i].tableEntry[j].targetPosition; + count++; + } + } + if (count > 0) { + rowAverages[i] = sum / count; + rowValidCounts[i] = count; + } + } + + // Calculate expected row average based on neighboring rows + auto calculateExpectedRowAverage = [&](int rowIndex) -> float { + float weightedSum = 0.0f; + float totalWeight = 0.0f; + + // Use 3 rows above and below with distance-based weighting + for (int offset = -3; offset <= 3; ++offset) { + if (offset == 0) continue; // Skip self + int neighborRow = rowIndex + offset; + if (neighborRow >= 0 && neighborRow < POWERTABLE_CAD_SIZE && rowValidCounts[neighborRow] > 0) { + float weight = 1.0f / (1.0f + (std::abs)(offset)); + weightedSum += rowAverages[neighborRow] * weight; + totalWeight += weight; + } + } + + return (totalWeight > 0) ? weightedSum / totalWeight : rowAverages[rowIndex]; + }; + + // Check for downward trends in rows (resistance should generally increase with lower cadence) + auto hasDownwardTrend = [&](int rowIndex) -> bool { + if (rowValidCounts[rowIndex] < 3) return false; // Need enough data points + + float trend = 0.0f; + int trendCount = 0; + + for (int j = 0; j < POWERTABLE_WATT_SIZE - 1; ++j) { + if (ptData.tableRow[rowIndex].tableEntry[j].targetPosition != INT16_MIN && ptData.tableRow[rowIndex].tableEntry[j + 1].targetPosition != INT16_MIN) { + trend += (ptData.tableRow[rowIndex].tableEntry[j + 1].targetPosition - ptData.tableRow[rowIndex].tableEntry[j].targetPosition); + trendCount++; + } + } + + // If average trend is significantly negative, it's a downward trend + float downwardTrendThreshold = -POWERTABLE_CAD_INCREMENT * 2.0f; // -10 units if CAD_INCREMENT=5 + return (trendCount > 0 && (trend / trendCount) < downwardTrendThreshold); + }; + + // Detect and correct outlier rows + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + if (rowValidCounts[i] < 3) continue; // Skip rows with insufficient data + + float expectedAverage = calculateExpectedRowAverage(i); + float deviation = (std::abs)(rowAverages[i] - expectedAverage); + float minimumDeviationThreshold = POWERTABLE_CAD_INCREMENT * 10.0f; // 50 units if CAD_INCREMENT=5 + float threshold = std::max(minimumDeviationThreshold, expectedAverage * 0.15f); // 15% or minimum threshold + + bool isOutlier = deviation > threshold; + bool hasDownTrend = hasDownwardTrend(i); + + if (isOutlier || hasDownTrend) { + // Correct this row by interpolating from neighbors and enforcing upward trend + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + if (ptData.tableRow[i].tableEntry[j].readings < 1) { // Only correct filled values, not original data + + // Calculate expected value based on neighboring rows + float verticalInterpolation = 0.0f; + float verticalWeight = 0.0f; + + for (int offset = -2; offset <= 2; ++offset) { + if (offset == 0) continue; + int neighborRow = i + offset; + if (neighborRow >= 0 && neighborRow < POWERTABLE_CAD_SIZE && ptData.tableRow[neighborRow].tableEntry[j].targetPosition != INT16_MIN) { + float weight = 1.0f / (1.0f + (std::abs)(offset)); + verticalInterpolation += ptData.tableRow[neighborRow].tableEntry[j].targetPosition * weight; + verticalWeight += weight; + } + } + + if (verticalWeight > 0) { + float correctedValue = verticalInterpolation / verticalWeight; + + // Ensure the corrected value maintains proper ordering + int16_t finalCorrectedValue = applyFlexibleConstraints(i, j, correctedValue); + + // Apply correction with some smoothing to avoid abrupt changes + if (ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + float currentValue = static_cast(ptData.tableRow[i].tableEntry[j].targetPosition); + float blendFactor = (isOutlier && hasDownTrend) ? 0.8f : 0.5f; // Stronger correction for severe cases + float blendedValue = (1.0f - blendFactor) * currentValue + blendFactor * finalCorrectedValue; + ptData.tableRow[i].tableEntry[j].targetPosition = static_cast(round(blendedValue)); + } else { + ptData.tableRow[i].tableEntry[j].targetPosition = finalCorrectedValue; + } } } } } } + + // 5. Final pass to ensure no downward trends remain + for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { + for (int j = 0; j < POWERTABLE_WATT_SIZE - 1; ++j) { + if (ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN && ptData.tableRow[i].tableEntry[j + 1].targetPosition != INT16_MIN && + ptData.tableRow[i].tableEntry[j].readings < 1 && // Only adjust filled values + ptData.tableRow[i].tableEntry[j + 1].readings < 1) { + // If we have a downward trend, adjust the right value upward + if (ptData.tableRow[i].tableEntry[j + 1].targetPosition <= ptData.tableRow[i].tableEntry[j].targetPosition) { + int16_t minValue = ptData.tableRow[i].tableEntry[j].targetPosition + 1; + ptData.tableRow[i].tableEntry[j + 1].targetPosition = std::max(minValue, ptData.tableRow[i].tableEntry[j + 1].targetPosition); + } + } + } + } + + // 6. FINAL LAYER CAKE PASS: Build table from lowest cadence (highest row index) upward, enforcing all constraints + for (int i = POWERTABLE_CAD_SIZE - 1; i >= 0; --i) { // Start from lowest cadence (highest RPM) + for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { + // Only update filled/interpolated cells, not real data + if (ptData.tableRow[i].tableEntry[j].readings < 1 && ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { + int16_t base = ptData.tableRow[i].tableEntry[j].targetPosition; + // 1. Enforce left neighbor (must be lower) + if (j > 0 && ptData.tableRow[i].tableEntry[j - 1].targetPosition != INT16_MIN) { + int16_t left = ptData.tableRow[i].tableEntry[j - 1].targetPosition; + if (base <= left) base = left + 1; + } + // 2. Enforce down neighbor (must be lower) + if (i < POWERTABLE_CAD_SIZE - 1 && ptData.tableRow[i + 1].tableEntry[j].targetPosition != INT16_MIN) { + int16_t down = ptData.tableRow[i + 1].tableEntry[j].targetPosition; + float avgInc = (j < averageIncreasePerCadence.size()) ? averageIncreasePerCadence[j] : 1.0f; + int16_t minVal = static_cast(std::ceil(down + std::max(1.0f, avgInc))); + if (base < minVal) base = minVal; + } + // 3. Enforce right neighbor (must be higher) + if (j < POWERTABLE_WATT_SIZE - 1 && ptData.tableRow[i].tableEntry[j + 1].targetPosition != INT16_MIN) { + int16_t right = ptData.tableRow[i].tableEntry[j + 1].targetPosition; + if (base >= right) base = right - 1; + } + // 4. Enforce up neighbor (must be higher) + if (i > 0 && ptData.tableRow[i - 1].tableEntry[j].targetPosition != INT16_MIN) { + int16_t up = ptData.tableRow[i - 1].tableEntry[j].targetPosition; + if (base >= up) base = up - 1; + } + // 5. Clamp to reasonable range if needed (optional) + if (base < -2000) base = -2000; + if (base > 20000) base = 20000; + ptData.tableRow[i].tableEntry[j].targetPosition = base; + } + } + } } /** @@ -1002,4 +1305,209 @@ bool CubicSpline::shouldUseNaturalSpline(std::pair, std::vect float curvatureThreshold = 1.0f; return !(abs(secondDerivativeStart) > curvatureThreshold || abs(secondDerivativeEnd) > curvatureThreshold); -} \ No newline at end of file +} + +// --- Helper Functions --- + +// Check if a cell is considered "filled" with valid data +bool isFilled(const TableEntry& entry) { return entry.targetPosition != INT16_MIN; } + +// Linearly interpolate or extrapolate a value. +// Interpolates if x is between x0 and x1. +// Extrapolates if x is outside x0 and x1. +double linear_interpolate(double x, double x0, double y0, double x1, double y1) { + if (x0 == x1) { + return y0; // Avoid division by zero, return one of the points + } + // Formula: y = y0 + (x - x0) * (y1 - y0) / (x1 - x0) + return y0 + (x - x0) * (y1 - y0) / (x1 - x0); +} + +// --- Core Logic --- + +/** + * @brief Completes the power table using an iterative interpolation and enforcement strategy. + * + * This function fills in a partially completed PTData table. It operates in a loop until + * the table is stable (no more changes are made). Each loop consists of two main passes: + * + * 1. Interpolation/Extrapolation Pass: + * - Iterates through each cell that is modifiable (empty or readings == 0). + * - For each cell, it finds the nearest filled neighbors in its row and column. + * - It uses this information to perform bilinear interpolation (if possible), + * linear interpolation, or linear extrapolation to estimate a value. + * - This ensures the filled data follows the trend of the existing measurements. + * + * 2. Monotonicity Enforcement Pass: + * - After interpolation, this pass guarantees all rules are met. + * - It sweeps the grid from bottom-left (0,0) to top-right. + * - It enforces rule 1: cell[r][c] > cell[r][c-1] + * - It enforces rule 2: cell[r][c] > cell[r-1][c] + * - If a rule is violated, the cell's value is minimally adjusted (e.g., incremented by 1) + * to satisfy the rule. This also handles "outliers" with actual readings that + * violate the monotonic structure, correcting them as a last resort. + * + * The loop continues until a full iteration makes no changes, resulting in a complete and + * rule-compliant table. + * + * @param data A reference to the PTData object to be completed in-place. + */ +void PTHelpers::completePowerTable(PTData& data) { + bool changedInIteration = true; + int max_iterations = 100; // Safety break to prevent infinite loops + int iteration_count = 0; + + while (changedInIteration && iteration_count < max_iterations) { + changedInIteration = false; + iteration_count++; + + // --- PASS 1: Interpolation and Extrapolation --- + for (int r = 0; r < POWERTABLE_CAD_SIZE; ++r) { + for (int c = 0; c < POWERTABLE_WATT_SIZE; ++c) { + if (isFilled(data.tableRow[r].tableEntry[c]) && data.tableRow[r].tableEntry[c].readings > 0) { + continue; + } + + // Find horizontal anchors (left and right) for interpolation + int left_c = -1, right_c = -1; + for (int i = c - 1; i >= 0; --i) { + if (isFilled(data.tableRow[r].tableEntry[i])) { + left_c = i; + break; + } + } + for (int i = c + 1; i < POWERTABLE_WATT_SIZE; ++i) { + if (isFilled(data.tableRow[r].tableEntry[i])) { + right_c = i; + break; + } + } + + // Find vertical anchors (bottom and top) for interpolation + int bottom_r = -1, top_r = -1; + for (int i = r - 1; i >= 0; --i) { + if (isFilled(data.tableRow[i].tableEntry[c])) { + bottom_r = i; + break; + } + } + for (int i = r + 1; i < POWERTABLE_CAD_SIZE; ++i) { + if (isFilled(data.tableRow[i].tableEntry[c])) { + top_r = i; + break; + } + } + + double h_val = 0, v_val = 0; + bool h_ok = false, v_ok = false; + + // Horizontal Estimation + if (left_c != -1 && right_c != -1) { + h_val = linear_interpolate(c, left_c, data.tableRow[r].tableEntry[left_c].targetPosition, right_c, data.tableRow[r].tableEntry[right_c].targetPosition); + h_ok = true; + } else if (left_c != -1) { + int l2 = -1; + for (int i = left_c - 1; i >= 0; --i) + if (isFilled(data.tableRow[r].tableEntry[i])) { + l2 = i; + break; + } + if (l2 != -1) + h_val = linear_interpolate(c, l2, data.tableRow[r].tableEntry[l2].targetPosition, left_c, data.tableRow[r].tableEntry[left_c].targetPosition); + else + h_val = data.tableRow[r].tableEntry[left_c].targetPosition; + h_ok = true; + } else if (right_c != -1) { + int r2 = -1; + for (int i = right_c + 1; i < POWERTABLE_WATT_SIZE; ++i) + if (isFilled(data.tableRow[r].tableEntry[i])) { + r2 = i; + break; + } + if (r2 != -1) + h_val = linear_interpolate(c, right_c, data.tableRow[r].tableEntry[right_c].targetPosition, r2, data.tableRow[r].tableEntry[r2].targetPosition); + else + h_val = data.tableRow[r].tableEntry[right_c].targetPosition; + h_ok = true; + } + + // Vertical Estimation + if (bottom_r != -1 && top_r != -1) { + v_val = linear_interpolate(r, bottom_r, data.tableRow[bottom_r].tableEntry[c].targetPosition, top_r, data.tableRow[top_r].tableEntry[c].targetPosition); + v_ok = true; + } else if (bottom_r != -1) { + int b2 = -1; + for (int i = bottom_r - 1; i >= 0; --i) + if (isFilled(data.tableRow[i].tableEntry[c])) { + b2 = i; + break; + } + if (b2 != -1) + v_val = linear_interpolate(r, b2, data.tableRow[b2].tableEntry[c].targetPosition, bottom_r, data.tableRow[bottom_r].tableEntry[c].targetPosition); + else + v_val = data.tableRow[bottom_r].tableEntry[c].targetPosition; + v_ok = true; + } else if (top_r != -1) { + int t2 = -1; + for (int i = top_r + 1; i < POWERTABLE_CAD_SIZE; ++i) + if (isFilled(data.tableRow[i].tableEntry[c])) { + t2 = i; + break; + } + if (t2 != -1) + v_val = linear_interpolate(r, top_r, data.tableRow[top_r].tableEntry[c].targetPosition, t2, data.tableRow[t2].tableEntry[c].targetPosition); + else + v_val = data.tableRow[top_r].tableEntry[c].targetPosition; + v_ok = true; + } + + double final_val = 0; + if (h_ok && v_ok) { + final_val = (h_val + v_val) / 2.0; + } else if (h_ok) { + final_val = h_val; + } else if (v_ok) { + final_val = v_val; + } else { + continue; + } + + int16_t new_pos = static_cast(round(final_val)); + if (data.tableRow[r].tableEntry[c].targetPosition != new_pos) { + data.tableRow[r].tableEntry[c].targetPosition = new_pos; + data.tableRow[r].tableEntry[c].readings = 0; + changedInIteration = true; + } + } + } + + // --- PASS 2: Monotonicity Enforcement --- + for (int r = 0; r < POWERTABLE_CAD_SIZE; ++r) { + for (int c = 0; c < POWERTABLE_WATT_SIZE; ++c) { + if (!isFilled(data.tableRow[r].tableEntry[c])) continue; + + // --- MODIFIED RULE --- + // Enforce Rule 2: Neighbor above (row r-1) must be higher. + // This means the value at [r] must be LESS than the value at [r-1]. + if (r > 0 && isFilled(data.tableRow[r - 1].tableEntry[c])) { + if (data.tableRow[r].tableEntry[c].targetPosition >= data.tableRow[r - 1].tableEntry[c].targetPosition) { + data.tableRow[r].tableEntry[c].targetPosition = data.tableRow[r - 1].tableEntry[c].targetPosition - 1; + changedInIteration = true; + } + } + + // Enforce Rule 1: Neighbor left (column c-1) must be lower. + // This means the value at [c] must be GREATER than the value at [c-1]. + if (c > 0 && isFilled(data.tableRow[r].tableEntry[c - 1])) { + if (data.tableRow[r].tableEntry[c].targetPosition <= data.tableRow[r].tableEntry[c - 1].targetPosition) { + data.tableRow[r].tableEntry[c].targetPosition = data.tableRow[r].tableEntry[c - 1].targetPosition + 1; + changedInIteration = true; + } + } + } + } + } + if (iteration_count >= max_iterations) { + SS2K_LOG(PTDATA_LOG_TAG, "Warning: Table completion reached max iterations. Result may be unstable."); + } +} diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index d4fc6970..b3fcec17 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -196,27 +196,27 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { return; } - targetPosition = this->calculatePosition(watts, cad, targetPosition, index); + // targetPosition = this->calculatePosition(watts, cad, targetPosition, index); - // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table - TestResults testResults = ptHelpers.testNeighbors(index, targetPosition, ptData); + // // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table + // TestResults testResults = ptHelpers.testNeighbors(index, targetPosition, ptData); - auto handleNeighborFailure = [&](const char* direction, const TestResults::Neighbor& neighbor, const TestResults::Neighbor& oppositeNeighbor, float rangeFactor) { - if (!neighbor.passedTest) { - SS2K_LOG(POWERTABLE_LOG_TAG, "%s neighbor position (%d) failed with watts=%f, cad=%f, targetPosition=%f, (%d)(%d)", direction, neighbor.targetPosition, watts, cad, - targetPosition, index.cadIndex, index.wattIndex); - this->processNeighbor(index, targetPosition, neighbor.index, neighbor.targetPosition, oppositeNeighbor.index, oppositeNeighbor.targetPosition, rangeFactor); - } - }; + // auto handleNeighborFailure = [&](const char* direction, const TestResults::Neighbor& neighbor, const TestResults::Neighbor& oppositeNeighbor, float rangeFactor) { + // if (!neighbor.passedTest) { + // SS2K_LOG(POWERTABLE_LOG_TAG, "%s neighbor position (%d) failed with watts=%f, cad=%f, targetPosition=%f, (%d)(%d)", direction, neighbor.targetPosition, watts, cad, + // targetPosition, index.cadIndex, index.wattIndex); + // this->processNeighbor(index, targetPosition, neighbor.index, neighbor.targetPosition, oppositeNeighbor.index, oppositeNeighbor.targetPosition, rangeFactor); + // } + // }; - handleNeighborFailure("Left", testResults.leftNeighbor, testResults.rightNeighbor, HORIZONTAL_NEIGHBOR_RANGE); - handleNeighborFailure("Right", testResults.rightNeighbor, testResults.leftNeighbor, HORIZONTAL_NEIGHBOR_RANGE); - handleNeighborFailure("Top", testResults.topNeighbor, testResults.bottomNeighbor, VERTICAL_NEIGHBOR_RANGE); - handleNeighborFailure("Bottom", testResults.bottomNeighbor, testResults.topNeighbor, VERTICAL_NEIGHBOR_RANGE); + // handleNeighborFailure("Left", testResults.leftNeighbor, testResults.rightNeighbor, HORIZONTAL_NEIGHBOR_RANGE); + // handleNeighborFailure("Right", testResults.rightNeighbor, testResults.leftNeighbor, HORIZONTAL_NEIGHBOR_RANGE); + // handleNeighborFailure("Top", testResults.topNeighbor, testResults.bottomNeighbor, VERTICAL_NEIGHBOR_RANGE); + // handleNeighborFailure("Bottom", testResults.bottomNeighbor, testResults.topNeighbor, VERTICAL_NEIGHBOR_RANGE); - if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { - return; - } + // if (!(testResults.bottomNeighbor.passedTest && testResults.topNeighbor.passedTest && testResults.rightNeighbor.passedTest && testResults.leftNeighbor.passedTest)) { + // return; + // } this->enterData(index, (int)targetPosition); fillTableFlag = true; // set flag to fill table @@ -242,7 +242,7 @@ void PowerTable::enterData(ptIndex index, int pos) { } else { // Average and update the readings. this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition = (pos + (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition * this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings)) / - (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings + 1.0); + (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings + 1.0f); SS2K_LOG(POWERTABLE_LOG_TAG, "Existing entry averaged (%d)(%d)(%d), readings(%d)", index.cadIndex, index.wattIndex, this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition, this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings); if (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings > POWER_SAMPLES * 2) { @@ -278,13 +278,13 @@ void PowerTable::fillTable() { if (step == 0) { SS2K_LOG(POWERTABLE_LOG_TAG, "Fill start with %d entries", entries); prevEntries = entries; - completed = ptHelpers.splineFill(ptData, true); + // completed = ptHelpers.splineFill(ptData, true); } else if (step == 1) { - completed = ptHelpers.splineFill(ptData, false); + // completed = ptHelpers.splineFill(ptData, false); } else if (step == 2) { - completed = ptHelpers.linearFill(ptData); - }else if (step == 3) { - //ptHelpers.fillByAverage(ptData); + // completed = ptHelpers.linearFill(ptData); + } else if (step == 3) { + ptHelpers.completePowerTable(ptData); completed = true; // this step is always completed. } newEntries = ptHelpers.getNumEntries(ptData); @@ -418,7 +418,7 @@ void PowerTable::downVoteData(ptIndex index, float target, int neighbor) { int penalty = 1; if (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings < penalty) { - this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings = 0; + this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings = 0; this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition = INT16_MIN; // remove target position if readings are zero. } else { this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings -= penalty; diff --git a/test/data/10x5-26-25.ptab b/test/data/10x5-26-25.ptab index 40648005..71806456 100644 --- a/test/data/10x5-26-25.ptab +++ b/test/data/10x5-26-25.ptab @@ -1,7 +1,7 @@ Cadence/Power,0W,30W,60W,90W,120W,150W,180W,210W,240W,270W,300W,330W,360W,390W,420W,450W,480W,510W,540W,570W,600W,630W,660W,690W,720W,750W,780W,810W,840W,870W,900W,930W,960W,990W,1020W,1050W,1080W,1110W 60RPM,,,,,,,,,,,1755,1938,,,,,,,,,,,,,,,,,, 65RPM,,,,,,,,,,,1665,1716,,1845,1903,1926,1950,1973,2069,2097,2102,2106,,,,,,, -70RPM,1198,,,,1241,1334,1361,1388,1518,1665,1670,1673,1678,1702,1707,1711,,,,, +70RPM,370,,,,1241,1334,1361,1388,1518,1665,1670,1673,1678,1702,1707,1711,,,,, 75RPM,268,,,,,,1350,,1448,,1625,,,,,,,,,1641,,,,,,2075,2147,2219,, 80RPM,135,,854,,1120,1184,1316,1373,1421,1443,1538,1604,1642,,,,,,,,1994,2018,,,,, 85RPM,,794,841,888,,,1250,1327,1382,,1497,1512,1521,1535,1564,1571,1576,1577,,1638,,,,,, diff --git a/test/data/averageMethod.ptab b/test/data/averageMethod.ptab new file mode 100644 index 00000000..48870a24 --- /dev/null +++ b/test/data/averageMethod.ptab @@ -0,0 +1,12 @@ +# METADATA:HMax=30165 +Cadence/Power,0W,30W,60W,90W,120W,150W,180W,210W,240W,270W,300W,330W,360W,390W,420W,450W,480W,510W,540W,570W,600W,630W,660W,690W,720W,750W,780W,810W,840W,870W,900W,930W,960W,990W,1020W,1050W,1080W,1110W +60RPM,1771,,,,,,,,1794,1964,,2029,2046,2049,2051,2052,2053,,,,,,,,,,,,, +65RPM,,850,,,1479,,,1563,,1778,1858,1862,1870,1874,1881,1901,1945,2105,2381,3866,4835,5045,5255,5465,5674,5884,6094,6304,6513,6723 +70RPM,1418,,1421,1425,1433,,1450,1487,1570,1637,1721,1797,1808,1816,1822,1827,1829,1830,,,,,,,,,,,, +75RPM,,-23,989,,,1297,1440,,,1627,1716,1768,1782,1789,1791,1793,1794,1801,,,,,,,,,,,, +80RPM,139,,,,,,1343,1438,1519,1557,1572,1591,1613,1657,1704,1720,1749,1800,2002,2283,4237,4442,4647,4852,5057,5261,5466,5671,5876,6081 +85RPM,,,,1360,1384,,,1398,1449,1509,1523,1573,1581,1601,1619,1651,1676,1699,1723,1747,1771,1795,1819,1843,1867,1892,1916,1940,1964,1987 +90RPM,,,,1291,1292,1293,1299,1312,1365,1378,1402,1459,1510,1534,1569,1582,1607,1631,1655,1679,1703,1727,1752,1776,1800,1824,1848,1873,1897,1920 +95RPM,,,952,977,1028,1142,1207,1229,1254,1292,1360,1411,1461,1512,1562,,,,,,,,,,,,,,, +100RPM,130,,388,631,657,706,877,943,1071,1188,1330,1367,1384,1390,1392,1395,1399,1407,1436,1489,1589,1662,1735,,,,,,, +105RPM,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/test/test_table_fill.cpp b/test/test_table_fill.cpp index 78734cd2..ef5dfeff 100644 --- a/test/test_table_fill.cpp +++ b/test/test_table_fill.cpp @@ -35,20 +35,21 @@ void TestTableFill::test_fill_incomplete_table(void) { logFile << "Initial data points: " << initialPoints << "\n"; int previousFilledPoints = 0; int filledPoints = 1; - // Fill the incomplete table - while (previousFilledPoints < filledPoints) { - previousFilledPoints = filledPoints; - helpers.splineFill(ptData); - logFile << "Applied splineFill to the table\n"; + //Fill the incomplete table + // while (previousFilledPoints < filledPoints) { + // previousFilledPoints = filledPoints; + // helpers.linearFill(ptData); + // logFile << "Applied splineFill to the table\n"; - // Count filled data points - filledPoints = helpers.getNumEntries(ptData); - logFile << "Filled data points: " << filledPoints << "\n"; - logFile << "Added " << (filledPoints - initialPoints) << " points\n"; - } + // // Count filled data points + // filledPoints = helpers.getNumEntries(ptData); + // logFile << "Filled data points: " << filledPoints << "\n"; + // logFile << "Added " << (filledPoints - initialPoints) << " points\n"; + // } // loop through the table and check for INT16_MIN values - helpers.fillByAverage(ptData); + //for(int i=1; i<2; i++){ + helpers.completePowerTable(ptData);//} // Save the filled power table const std::string outputFilePath = "test/output/power_table_filled.ptab"; savePTDataToCSV(ptData, outputFilePath); From 27bf41d8ac25aad6388693f4345bb0f57fd3818a Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Fri, 4 Jul 2025 16:39:42 -0500 Subject: [PATCH 268/451] run fill until done. Don't enfore monotonicity on entries with readings unless things get dire :) --- include/PowerTable_Helpers.h | 3 +- src/PowerTable_Helpers.cpp | 495 +++-------------------------------- src/Power_Table.cpp | 9 +- 3 files changed, 38 insertions(+), 469 deletions(-) diff --git a/include/PowerTable_Helpers.h b/include/PowerTable_Helpers.h index 45cb0104..12d38942 100644 --- a/include/PowerTable_Helpers.h +++ b/include/PowerTable_Helpers.h @@ -131,8 +131,7 @@ class PTHelpers { // return number of readings in the table. If minReadings is set, it will only count entries with at least that many readings. int getNumEntries(PTData& ptData, int minReadings = 0); int getTotalReadings(PTData& ptData); - void fillByAverage(PTData& ptData); - void completePowerTable(PTData& data); + bool completePowerTable(PTData& data); ptIndex calculateIndex(int watts, int cad); std::pair, std::vector> getRow(int row, PTData& ptData); std::pair, std::vector> getColumn(int column, PTData& ptData); diff --git a/src/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp index b6bb3fdc..1764e6c8 100644 --- a/src/PowerTable_Helpers.cpp +++ b/src/PowerTable_Helpers.cpp @@ -396,457 +396,6 @@ bool PTHelpers::extrapolateEmptyIndices(int outerIndex, const std::vector& return true; } -/** - * @brief Fills missing or invalid entries in the power table by estimating values using averages. - * - * This function processes the provided PTData structure, which represents a power table with - * cadence and wattage dimensions. It performs the following steps: - * 1. Calculates the average target position for each wattage column across all valid cadence rows. - * 2. Computes the average increase in target position per cadence increment for each wattage column. - * 3. For each empty or invalid cell, estimates its value based on the center average and the average - * increase per cadence step, filling in the missing data accordingly. - * 4. Validates that each filled value maintains proper ordering relative to neighbors. - * 5. Applies a second pass to correct outlier rows and fix downward trends. - * - * If a cell was previously filled by another method, the function averages the new estimate with the - * existing value to provide a smoother result. - * - * @param ptData Reference to the PTData structure containing the power table to be filled. - */ -void PTHelpers::fillByAverage(PTData& ptData) { - std::vector centerAverageRow(POWERTABLE_WATT_SIZE, 0.0f); - std::vector validCounts(POWERTABLE_WATT_SIZE, 0); - int mid_cad_index = POWERTABLE_CAD_SIZE / 2; - float center_cad = static_cast(MINIMUM_TABLE_CAD + mid_cad_index * POWERTABLE_CAD_INCREMENT); - - // 1. Calculate the center average row using improved regression - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - std::vector> points; - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - float cad = static_cast(MINIMUM_TABLE_CAD + i * POWERTABLE_CAD_INCREMENT); - points.push_back({cad, static_cast(ptData.tableRow[i].tableEntry[j].targetPosition)}); - } - } - validCounts[j] = points.size(); - - if (points.size() >= 2) { - // Check if data is clustered far from center - float min_cad = points.front().first; - float max_cad = points.back().first; - float cad_range = max_cad - min_cad; - float distance_from_center = (std::min)((std::abs)(center_cad - min_cad), (std::abs)(center_cad - max_cad)); - - // If data is too far from center or range is too small, use neighbor interpolation instead - float centerDistanceThreshold = POWERTABLE_CAD_INCREMENT * 4.0f; // 4 cadence increments from center - float minimumCadenceRange = POWERTABLE_CAD_INCREMENT * 2.0f; // At least 2 cadence increments of data - - if (distance_from_center > centerDistanceThreshold || cad_range < minimumCadenceRange) { - // Try to interpolate from neighboring power levels - float neighborAvg = 0.0f; - int neighborCount = 0; - - // Check left and right neighbors - for (int neighbor_j = std::max(0, j - 2); neighbor_j <= std::min(POWERTABLE_WATT_SIZE - 1, j + 2); neighbor_j++) { - if (neighbor_j != j && validCounts[neighbor_j] > 0) { - // Get neighbor's data and check if it has data near center - std::vector> neighborPoints; - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (ptData.tableRow[i].tableEntry[neighbor_j].targetPosition != INT16_MIN) { - float cad = static_cast(MINIMUM_TABLE_CAD + i * POWERTABLE_CAD_INCREMENT); - neighborPoints.push_back({cad, static_cast(ptData.tableRow[i].tableEntry[neighbor_j].targetPosition)}); - } - } - - if (neighborPoints.size() >= 2) { - // Calculate neighbor's center value - float sum_x = 0, sum_y = 0, sum_xy = 0, sum_x2 = 0; - for (const auto& p : neighborPoints) { - sum_x += p.first; - sum_y += p.second; - sum_xy += p.first * p.second; - sum_x2 += p.first * p.first; - } - float n = neighborPoints.size(); - float denom = (n * sum_x2 - sum_x * sum_x); - if (denom != 0) { - float slope = (n * sum_xy - sum_x * sum_y) / denom; - float intercept = (sum_y - slope * sum_x) / n; - float neighborCenterValue = slope * center_cad + intercept; - - // Weight by proximity and data quality - float weight = 1.0f / (1.0f + (std::abs)(neighbor_j - j)); - neighborAvg += neighborCenterValue * weight; - neighborCount += weight; - } - } - } - } - - if (neighborCount > 0) { - centerAverageRow[j] = neighborAvg / neighborCount; - } else { - // Fallback to simple average of available points - float sum = 0; - for (const auto& p : points) sum += p.second; - centerAverageRow[j] = sum / points.size(); - } - } else { - // Use normal linear regression for well-distributed data - float sum_x = 0, sum_y = 0, sum_xy = 0, sum_x2 = 0; - for (const auto& p : points) { - sum_x += p.first; - sum_y += p.second; - sum_xy += p.first * p.second; - sum_x2 += p.first * p.first; - } - float n = points.size(); - float denom = (n * sum_x2 - sum_x * sum_x); - float slope = (denom != 0) ? (n * sum_xy - sum_x * sum_y) / denom : 0; - float intercept = (sum_y - slope * sum_x) / n; - centerAverageRow[j] = slope * center_cad + intercept; - } - } else if (points.size() == 1) { - centerAverageRow[j] = points[0].second; - } - } - - // 2. Calculate the average increase in target position per cadence increment for each column - std::vector averageIncreasePerCadence(POWERTABLE_WATT_SIZE, 0.0f); - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - float totalIncrease = 0.0f; - int increaseCount = 0; - for (int i = 0; i < POWERTABLE_CAD_SIZE - 1; ++i) { - if (ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN && ptData.tableRow[i + 1].tableEntry[j].targetPosition != INT16_MIN) { - totalIncrease += (ptData.tableRow[i + 1].tableEntry[j].targetPosition - ptData.tableRow[i].tableEntry[j].targetPosition); - increaseCount++; - } - } - if (increaseCount > 0) { - averageIncreasePerCadence[j] = totalIncrease / increaseCount; - } - } - - // Helper function to get neighbor values - auto getNeighborValue = [&](int i, int j, int di, int dj) -> int16_t { - int ni = i + di; - int nj = j + dj; - if (ni >= 0 && ni < POWERTABLE_CAD_SIZE && nj >= 0 && nj < POWERTABLE_WATT_SIZE) { - return ptData.tableRow[ni].tableEntry[nj].targetPosition; - } - return INT16_MIN; - }; - - // Helper function to count valid neighbors - auto countValidNeighbors = [&](int i, int j) -> int { - int count = 0; - if (getNeighborValue(i, j, 0, -1) != INT16_MIN) count++; // left - if (getNeighborValue(i, j, 0, 1) != INT16_MIN) count++; // right - if (getNeighborValue(i, j, -1, 0) != INT16_MIN) count++; // top - if (getNeighborValue(i, j, 1, 0) != INT16_MIN) count++; // bottom - return count; - }; - - // Helper function to apply flexible constraints - auto applyFlexibleConstraints = [&](int i, int j, float baseValue) -> int16_t { - int16_t leftNeighbor = getNeighborValue(i, j, 0, -1); - int16_t rightNeighbor = getNeighborValue(i, j, 0, 1); - int16_t topNeighbor = getNeighborValue(i, j, -1, 0); - int16_t bottomNeighbor = getNeighborValue(i, j, 1, 0); - - int validNeighborCount = countValidNeighbors(i, j); - float adjustedValue = baseValue; - - // If we have very few neighbors, be more lenient with constraints - if (validNeighborCount <= 1) { - // Only apply minimal constraints - allow more deviation from trend - const float tolerance = POWERTABLE_CAD_INCREMENT * 10.0f; // Allow larger deviations when few neighbors (50 units if CAD_INCREMENT=5) - - if (leftNeighbor != INT16_MIN) { - adjustedValue = std::max(adjustedValue, static_cast(leftNeighbor - tolerance)); - } - if (rightNeighbor != INT16_MIN) { - adjustedValue = std::min(adjustedValue, static_cast(rightNeighbor + tolerance)); - } - if (topNeighbor != INT16_MIN) { - adjustedValue = std::min(adjustedValue, static_cast(topNeighbor + tolerance)); - } - if (bottomNeighbor != INT16_MIN) { - adjustedValue = std::max(adjustedValue, static_cast(bottomNeighbor - tolerance)); - } - } else { - // Apply normal constraints when we have sufficient neighbor data - const float tolerance = POWERTABLE_CAD_INCREMENT * 2.0f; // Smaller tolerance when we have more data (10 units if CAD_INCREMENT=5) - - // Ensure value follows general trend but with some tolerance - if (leftNeighbor != INT16_MIN) { - adjustedValue = std::max(adjustedValue, static_cast(leftNeighbor + 1)); - } - if (bottomNeighbor != INT16_MIN) { - adjustedValue = std::max(adjustedValue, static_cast(bottomNeighbor + 1)); - } - if (topNeighbor != INT16_MIN) { - adjustedValue = std::min(adjustedValue, static_cast(topNeighbor - 1)); - } - if (rightNeighbor != INT16_MIN) { - adjustedValue = std::min(adjustedValue, static_cast(rightNeighbor - 1)); - } - - // Check for impossible constraints and relax if needed - float minRequired = -std::numeric_limits::infinity(); - float maxAllowed = std::numeric_limits::infinity(); - - if (leftNeighbor != INT16_MIN) minRequired = std::max(minRequired, static_cast(leftNeighbor + 1)); - if (bottomNeighbor != INT16_MIN) minRequired = std::max(minRequired, static_cast(bottomNeighbor + 1)); - if (topNeighbor != INT16_MIN) maxAllowed = std::min(maxAllowed, static_cast(topNeighbor - 1)); - if (rightNeighbor != INT16_MIN) maxAllowed = std::min(maxAllowed, static_cast(rightNeighbor - 1)); - - if (minRequired > maxAllowed) { - // Constraints conflict - use weighted average favoring the trend - float trendWeight = 0.7f; - adjustedValue = trendWeight * baseValue + (1.0f - trendWeight) * ((minRequired + maxAllowed) / 2.0f); - } - } - - return static_cast(round(adjustedValue)); - }; - - // 3. Fill empty cells based on the average row and average increase, with flexible neighbor validation - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - // Only fill cells that have not been populated with real data - if (ptData.tableRow[i].tableEntry[j].readings < 1) { - float newValue = 0.0f; - bool hasValue = false; - - if (validCounts[j] > 0) { - // Use column-based average if we have data for this column - int distance = i - mid_cad_index; - newValue = centerAverageRow[j] + (averageIncreasePerCadence[j] * distance); - hasValue = true; - } else { - // Column is completely empty - interpolate from neighboring columns - float leftValue = 0.0f, rightValue = 0.0f; - bool hasLeft = false, hasRight = false; - - // Find nearest left column with data - for (int left_j = j - 1; left_j >= 0; --left_j) { - if (validCounts[left_j] > 0) { - int distance = i - mid_cad_index; - leftValue = centerAverageRow[left_j] + (averageIncreasePerCadence[left_j] * distance); - hasLeft = true; - break; - } - } - - // Find nearest right column with data - for (int right_j = j + 1; right_j < POWERTABLE_WATT_SIZE; ++right_j) { - if (validCounts[right_j] > 0) { - int distance = i - mid_cad_index; - rightValue = centerAverageRow[right_j] + (averageIncreasePerCadence[right_j] * distance); - hasRight = true; - break; - } - } - - // Interpolate between left and right neighbors - if (hasLeft && hasRight) { - // Linear interpolation between left and right columns - float ratio = 0.5f; // Simple midpoint for now, could be more sophisticated - newValue = leftValue + (rightValue - leftValue) * ratio; - hasValue = true; - } else if (hasLeft) { - // Extrapolate from left neighbor - newValue = leftValue + (leftValue * 0.1f); // Add 10% increase as reasonable extrapolation - hasValue = true; - } else if (hasRight) { - // Extrapolate from right neighbor - newValue = rightValue - (rightValue * 0.1f); // Subtract 10% as reasonable extrapolation - hasValue = true; - } - } - - if (hasValue) { - // Apply flexible constraints based on neighbor availability - int16_t constrainedValue = applyFlexibleConstraints(i, j, newValue); - - // If the cell was already filled by another method, average with the new value - if (ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - float existingValue = static_cast(ptData.tableRow[i].tableEntry[j].targetPosition); - float blendedValue = (existingValue + constrainedValue) / 2.0f; - int16_t finalValue = applyFlexibleConstraints(i, j, blendedValue); - ptData.tableRow[i].tableEntry[j].targetPosition = finalValue; - } else { - ptData.tableRow[i].tableEntry[j].targetPosition = constrainedValue; - } - } - } - } - } - - // 4. SECOND PASS: Detect and correct outlier rows and downward trends - - // Calculate overall table statistics for outlier detection - std::vector rowAverages(POWERTABLE_CAD_SIZE, 0.0f); - std::vector rowValidCounts(POWERTABLE_CAD_SIZE, 0); - - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - float sum = 0.0f; - int count = 0; - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - sum += ptData.tableRow[i].tableEntry[j].targetPosition; - count++; - } - } - if (count > 0) { - rowAverages[i] = sum / count; - rowValidCounts[i] = count; - } - } - - // Calculate expected row average based on neighboring rows - auto calculateExpectedRowAverage = [&](int rowIndex) -> float { - float weightedSum = 0.0f; - float totalWeight = 0.0f; - - // Use 3 rows above and below with distance-based weighting - for (int offset = -3; offset <= 3; ++offset) { - if (offset == 0) continue; // Skip self - int neighborRow = rowIndex + offset; - if (neighborRow >= 0 && neighborRow < POWERTABLE_CAD_SIZE && rowValidCounts[neighborRow] > 0) { - float weight = 1.0f / (1.0f + (std::abs)(offset)); - weightedSum += rowAverages[neighborRow] * weight; - totalWeight += weight; - } - } - - return (totalWeight > 0) ? weightedSum / totalWeight : rowAverages[rowIndex]; - }; - - // Check for downward trends in rows (resistance should generally increase with lower cadence) - auto hasDownwardTrend = [&](int rowIndex) -> bool { - if (rowValidCounts[rowIndex] < 3) return false; // Need enough data points - - float trend = 0.0f; - int trendCount = 0; - - for (int j = 0; j < POWERTABLE_WATT_SIZE - 1; ++j) { - if (ptData.tableRow[rowIndex].tableEntry[j].targetPosition != INT16_MIN && ptData.tableRow[rowIndex].tableEntry[j + 1].targetPosition != INT16_MIN) { - trend += (ptData.tableRow[rowIndex].tableEntry[j + 1].targetPosition - ptData.tableRow[rowIndex].tableEntry[j].targetPosition); - trendCount++; - } - } - - // If average trend is significantly negative, it's a downward trend - float downwardTrendThreshold = -POWERTABLE_CAD_INCREMENT * 2.0f; // -10 units if CAD_INCREMENT=5 - return (trendCount > 0 && (trend / trendCount) < downwardTrendThreshold); - }; - - // Detect and correct outlier rows - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (rowValidCounts[i] < 3) continue; // Skip rows with insufficient data - - float expectedAverage = calculateExpectedRowAverage(i); - float deviation = (std::abs)(rowAverages[i] - expectedAverage); - float minimumDeviationThreshold = POWERTABLE_CAD_INCREMENT * 10.0f; // 50 units if CAD_INCREMENT=5 - float threshold = std::max(minimumDeviationThreshold, expectedAverage * 0.15f); // 15% or minimum threshold - - bool isOutlier = deviation > threshold; - bool hasDownTrend = hasDownwardTrend(i); - - if (isOutlier || hasDownTrend) { - // Correct this row by interpolating from neighbors and enforcing upward trend - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (ptData.tableRow[i].tableEntry[j].readings < 1) { // Only correct filled values, not original data - - // Calculate expected value based on neighboring rows - float verticalInterpolation = 0.0f; - float verticalWeight = 0.0f; - - for (int offset = -2; offset <= 2; ++offset) { - if (offset == 0) continue; - int neighborRow = i + offset; - if (neighborRow >= 0 && neighborRow < POWERTABLE_CAD_SIZE && ptData.tableRow[neighborRow].tableEntry[j].targetPosition != INT16_MIN) { - float weight = 1.0f / (1.0f + (std::abs)(offset)); - verticalInterpolation += ptData.tableRow[neighborRow].tableEntry[j].targetPosition * weight; - verticalWeight += weight; - } - } - - if (verticalWeight > 0) { - float correctedValue = verticalInterpolation / verticalWeight; - - // Ensure the corrected value maintains proper ordering - int16_t finalCorrectedValue = applyFlexibleConstraints(i, j, correctedValue); - - // Apply correction with some smoothing to avoid abrupt changes - if (ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - float currentValue = static_cast(ptData.tableRow[i].tableEntry[j].targetPosition); - float blendFactor = (isOutlier && hasDownTrend) ? 0.8f : 0.5f; // Stronger correction for severe cases - float blendedValue = (1.0f - blendFactor) * currentValue + blendFactor * finalCorrectedValue; - ptData.tableRow[i].tableEntry[j].targetPosition = static_cast(round(blendedValue)); - } else { - ptData.tableRow[i].tableEntry[j].targetPosition = finalCorrectedValue; - } - } - } - } - } - } - - // 5. Final pass to ensure no downward trends remain - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - for (int j = 0; j < POWERTABLE_WATT_SIZE - 1; ++j) { - if (ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN && ptData.tableRow[i].tableEntry[j + 1].targetPosition != INT16_MIN && - ptData.tableRow[i].tableEntry[j].readings < 1 && // Only adjust filled values - ptData.tableRow[i].tableEntry[j + 1].readings < 1) { - // If we have a downward trend, adjust the right value upward - if (ptData.tableRow[i].tableEntry[j + 1].targetPosition <= ptData.tableRow[i].tableEntry[j].targetPosition) { - int16_t minValue = ptData.tableRow[i].tableEntry[j].targetPosition + 1; - ptData.tableRow[i].tableEntry[j + 1].targetPosition = std::max(minValue, ptData.tableRow[i].tableEntry[j + 1].targetPosition); - } - } - } - } - - // 6. FINAL LAYER CAKE PASS: Build table from lowest cadence (highest row index) upward, enforcing all constraints - for (int i = POWERTABLE_CAD_SIZE - 1; i >= 0; --i) { // Start from lowest cadence (highest RPM) - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - // Only update filled/interpolated cells, not real data - if (ptData.tableRow[i].tableEntry[j].readings < 1 && ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { - int16_t base = ptData.tableRow[i].tableEntry[j].targetPosition; - // 1. Enforce left neighbor (must be lower) - if (j > 0 && ptData.tableRow[i].tableEntry[j - 1].targetPosition != INT16_MIN) { - int16_t left = ptData.tableRow[i].tableEntry[j - 1].targetPosition; - if (base <= left) base = left + 1; - } - // 2. Enforce down neighbor (must be lower) - if (i < POWERTABLE_CAD_SIZE - 1 && ptData.tableRow[i + 1].tableEntry[j].targetPosition != INT16_MIN) { - int16_t down = ptData.tableRow[i + 1].tableEntry[j].targetPosition; - float avgInc = (j < averageIncreasePerCadence.size()) ? averageIncreasePerCadence[j] : 1.0f; - int16_t minVal = static_cast(std::ceil(down + std::max(1.0f, avgInc))); - if (base < minVal) base = minVal; - } - // 3. Enforce right neighbor (must be higher) - if (j < POWERTABLE_WATT_SIZE - 1 && ptData.tableRow[i].tableEntry[j + 1].targetPosition != INT16_MIN) { - int16_t right = ptData.tableRow[i].tableEntry[j + 1].targetPosition; - if (base >= right) base = right - 1; - } - // 4. Enforce up neighbor (must be higher) - if (i > 0 && ptData.tableRow[i - 1].tableEntry[j].targetPosition != INT16_MIN) { - int16_t up = ptData.tableRow[i - 1].tableEntry[j].targetPosition; - if (base >= up) base = up - 1; - } - // 5. Clamp to reasonable range if needed (optional) - if (base < -2000) base = -2000; - if (base > 20000) base = 20000; - ptData.tableRow[i].tableEntry[j].targetPosition = base; - } - } - } -} - /** * @brief Fills missing entries in the power table using cubic spline interpolation. * @@ -1352,7 +901,7 @@ double linear_interpolate(double x, double x0, double y0, double x1, double y1) * * @param data A reference to the PTData object to be completed in-place. */ -void PTHelpers::completePowerTable(PTData& data) { +bool PTHelpers::completePowerTable(PTData& data) { bool changedInIteration = true; int max_iterations = 100; // Safety break to prevent infinite loops int iteration_count = 0; @@ -1482,26 +1031,46 @@ void PTHelpers::completePowerTable(PTData& data) { } // --- PASS 2: Monotonicity Enforcement --- - for (int r = 0; r < POWERTABLE_CAD_SIZE; ++r) { - for (int c = 0; c < POWERTABLE_WATT_SIZE; ++c) { + for (int r = 1; r < POWERTABLE_CAD_SIZE; ++r) { + for (int c = 1; c < POWERTABLE_WATT_SIZE; ++c) { if (!isFilled(data.tableRow[r].tableEntry[c])) continue; // --- MODIFIED RULE --- - // Enforce Rule 2: Neighbor above (row r-1) must be higher. + // Enforce Rule: Neighbor above (row r-1) must be higher. // This means the value at [r] must be LESS than the value at [r-1]. - if (r > 0 && isFilled(data.tableRow[r - 1].tableEntry[c])) { + if (r > 0 && isFilled(data.tableRow[r - 1].tableEntry[c]) && + data.tableRow[r - 1].tableEntry[c].readings < round(((iteration_count / 2.0f) / (float)max_iterations) * MAX_NEIGHBOR_WEIGHT)) { if (data.tableRow[r].tableEntry[c].targetPosition >= data.tableRow[r - 1].tableEntry[c].targetPosition) { - data.tableRow[r].tableEntry[c].targetPosition = data.tableRow[r - 1].tableEntry[c].targetPosition - 1; - changedInIteration = true; + data.tableRow[r - 1].tableEntry[c].targetPosition++; + changedInIteration = true; } } - // Enforce Rule 1: Neighbor left (column c-1) must be lower. + // Enforce Rule: Neighbor left (column c-1) must be lower. // This means the value at [c] must be GREATER than the value at [c-1]. - if (c > 0 && isFilled(data.tableRow[r].tableEntry[c - 1])) { + if (c > 0 && isFilled(data.tableRow[r].tableEntry[c - 1]) && + data.tableRow[r].tableEntry[c - 1].readings < round(((iteration_count / 2.0f) / (float)max_iterations) * MAX_NEIGHBOR_WEIGHT)) { if (data.tableRow[r].tableEntry[c].targetPosition <= data.tableRow[r].tableEntry[c - 1].targetPosition) { - data.tableRow[r].tableEntry[c].targetPosition = data.tableRow[r].tableEntry[c - 1].targetPosition + 1; - changedInIteration = true; + data.tableRow[r].tableEntry[c - 1].targetPosition--; + changedInIteration = true; + } + } + // Enforce Rule: Neighbor below (row r+1) must be lower. + // This means the value at [c] must be LESS than the value at [r+1]. + if (r < POWERTABLE_CAD_SIZE - 2 && isFilled(data.tableRow[r + 1].tableEntry[c]) && + data.tableRow[r + 1].tableEntry[c].readings < round(((iteration_count / 2.0f) / (float)max_iterations) * MAX_NEIGHBOR_WEIGHT)) { + if (data.tableRow[r].tableEntry[c].targetPosition <= data.tableRow[r + 1].tableEntry[c].targetPosition) { + data.tableRow[r + 1].tableEntry[c].targetPosition--; + changedInIteration = true; + } + } + // Enforce Rule: Neighbor right (column c+1) must be higher. + // This means the value at [c] must be GREATER than the value at [c+1]. + if (c < POWERTABLE_WATT_SIZE - 2 && isFilled(data.tableRow[r].tableEntry[c + 1]) && + data.tableRow[r].tableEntry[c + 1].readings < round(((iteration_count / 2.0f) / (float)max_iterations) * MAX_NEIGHBOR_WEIGHT)) { + if (data.tableRow[r].tableEntry[c].targetPosition <= data.tableRow[r].tableEntry[c + 1].targetPosition) { + data.tableRow[r].tableEntry[c + 1].targetPosition++; + changedInIteration = true; } } } @@ -1509,5 +1078,7 @@ void PTHelpers::completePowerTable(PTData& data) { } if (iteration_count >= max_iterations) { SS2K_LOG(PTDATA_LOG_TAG, "Warning: Table completion reached max iterations. Result may be unstable."); + return false; // Indicate that the table may not be fully completed } + return true; // Indicate that the table was successfully completed } diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index b3fcec17..120308bc 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -245,8 +245,8 @@ void PowerTable::enterData(ptIndex index, int pos) { (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings + 1.0f); SS2K_LOG(POWERTABLE_LOG_TAG, "Existing entry averaged (%d)(%d)(%d), readings(%d)", index.cadIndex, index.wattIndex, this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition, this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings); - if (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings > POWER_SAMPLES * 2) { - this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings = POWER_SAMPLES * 2; // keep from diluting recent readings too far. + if (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings > MAX_NEIGHBOR_WEIGHT) { + this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings = MAX_NEIGHBOR_WEIGHT; } } this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings++; @@ -278,14 +278,13 @@ void PowerTable::fillTable() { if (step == 0) { SS2K_LOG(POWERTABLE_LOG_TAG, "Fill start with %d entries", entries); prevEntries = entries; - // completed = ptHelpers.splineFill(ptData, true); + completed = ptHelpers.completePowerTable(ptData); } else if (step == 1) { // completed = ptHelpers.splineFill(ptData, false); } else if (step == 2) { // completed = ptHelpers.linearFill(ptData); } else if (step == 3) { - ptHelpers.completePowerTable(ptData); - completed = true; // this step is always completed. + } newEntries = ptHelpers.getNumEntries(ptData); SS2K_LOG(POWERTABLE_LOG_TAG, "Fill step %d added %d new entries", step, newEntries - prevEntries); From 16d7d582a241d65bb5f5278f9c99efa29cbf91a8 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Fri, 4 Jul 2025 17:09:49 -0500 Subject: [PATCH 269/451] higher reading wins --- src/PowerTable_Helpers.cpp | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp index 1764e6c8..2b866d09 100644 --- a/src/PowerTable_Helpers.cpp +++ b/src/PowerTable_Helpers.cpp @@ -1041,7 +1041,11 @@ bool PTHelpers::completePowerTable(PTData& data) { if (r > 0 && isFilled(data.tableRow[r - 1].tableEntry[c]) && data.tableRow[r - 1].tableEntry[c].readings < round(((iteration_count / 2.0f) / (float)max_iterations) * MAX_NEIGHBOR_WEIGHT)) { if (data.tableRow[r].tableEntry[c].targetPosition >= data.tableRow[r - 1].tableEntry[c].targetPosition) { - data.tableRow[r - 1].tableEntry[c].targetPosition++; + if(data.tableRow[r].tableEntry[c].readings >= data.tableRow[r - 1].tableEntry[c].readings) { + data.tableRow[r - 1].tableEntry[c].targetPosition = data.tableRow[r].tableEntry[c].targetPosition + 1; + } else { + data.tableRow[r].tableEntry[c].targetPosition = data.tableRow[r - 1].tableEntry[c].targetPosition - 1; + } changedInIteration = true; } } @@ -1051,25 +1055,11 @@ bool PTHelpers::completePowerTable(PTData& data) { if (c > 0 && isFilled(data.tableRow[r].tableEntry[c - 1]) && data.tableRow[r].tableEntry[c - 1].readings < round(((iteration_count / 2.0f) / (float)max_iterations) * MAX_NEIGHBOR_WEIGHT)) { if (data.tableRow[r].tableEntry[c].targetPosition <= data.tableRow[r].tableEntry[c - 1].targetPosition) { - data.tableRow[r].tableEntry[c - 1].targetPosition--; - changedInIteration = true; - } - } - // Enforce Rule: Neighbor below (row r+1) must be lower. - // This means the value at [c] must be LESS than the value at [r+1]. - if (r < POWERTABLE_CAD_SIZE - 2 && isFilled(data.tableRow[r + 1].tableEntry[c]) && - data.tableRow[r + 1].tableEntry[c].readings < round(((iteration_count / 2.0f) / (float)max_iterations) * MAX_NEIGHBOR_WEIGHT)) { - if (data.tableRow[r].tableEntry[c].targetPosition <= data.tableRow[r + 1].tableEntry[c].targetPosition) { - data.tableRow[r + 1].tableEntry[c].targetPosition--; - changedInIteration = true; - } - } - // Enforce Rule: Neighbor right (column c+1) must be higher. - // This means the value at [c] must be GREATER than the value at [c+1]. - if (c < POWERTABLE_WATT_SIZE - 2 && isFilled(data.tableRow[r].tableEntry[c + 1]) && - data.tableRow[r].tableEntry[c + 1].readings < round(((iteration_count / 2.0f) / (float)max_iterations) * MAX_NEIGHBOR_WEIGHT)) { - if (data.tableRow[r].tableEntry[c].targetPosition <= data.tableRow[r].tableEntry[c + 1].targetPosition) { - data.tableRow[r].tableEntry[c + 1].targetPosition++; + if(data.tableRow[r].tableEntry[c].readings >= data.tableRow[r].tableEntry[c - 1].readings) { + data.tableRow[r].tableEntry[c - 1].targetPosition = data.tableRow[r].tableEntry[c].targetPosition - 1; + } else { + data.tableRow[r].tableEntry[c].targetPosition = data.tableRow[r].tableEntry[c - 1].targetPosition + 1; + } changedInIteration = true; } } From 82245e4cc95ae8098f5ffacaa27ea8651c1177fd Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Fri, 4 Jul 2025 17:20:30 -0500 Subject: [PATCH 270/451] 0 is back --- src/PowerTable_Helpers.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp index 2b866d09..4c90714f 100644 --- a/src/PowerTable_Helpers.cpp +++ b/src/PowerTable_Helpers.cpp @@ -1031,8 +1031,8 @@ bool PTHelpers::completePowerTable(PTData& data) { } // --- PASS 2: Monotonicity Enforcement --- - for (int r = 1; r < POWERTABLE_CAD_SIZE; ++r) { - for (int c = 1; c < POWERTABLE_WATT_SIZE; ++c) { + for (int r = 0; r < POWERTABLE_CAD_SIZE; ++r) { + for (int c = 0; c < POWERTABLE_WATT_SIZE; ++c) { if (!isFilled(data.tableRow[r].tableEntry[c])) continue; // --- MODIFIED RULE --- From a4088c955dbabce039c5ed962fcf306339b73a09 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Fri, 4 Jul 2025 17:41:21 -0500 Subject: [PATCH 271/451] Allow more change --- src/PowerTable_Helpers.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp index 4c90714f..f451fae4 100644 --- a/src/PowerTable_Helpers.cpp +++ b/src/PowerTable_Helpers.cpp @@ -1038,29 +1038,29 @@ bool PTHelpers::completePowerTable(PTData& data) { // --- MODIFIED RULE --- // Enforce Rule: Neighbor above (row r-1) must be higher. // This means the value at [r] must be LESS than the value at [r-1]. - if (r > 0 && isFilled(data.tableRow[r - 1].tableEntry[c]) && - data.tableRow[r - 1].tableEntry[c].readings < round(((iteration_count / 2.0f) / (float)max_iterations) * MAX_NEIGHBOR_WEIGHT)) { + if (r > 0 && isFilled(data.tableRow[r - 1].tableEntry[c])) { if (data.tableRow[r].tableEntry[c].targetPosition >= data.tableRow[r - 1].tableEntry[c].targetPosition) { if(data.tableRow[r].tableEntry[c].readings >= data.tableRow[r - 1].tableEntry[c].readings) { - data.tableRow[r - 1].tableEntry[c].targetPosition = data.tableRow[r].tableEntry[c].targetPosition + 1; + data.tableRow[r].tableEntry[c].targetPosition += 1; } else { data.tableRow[r].tableEntry[c].targetPosition = data.tableRow[r - 1].tableEntry[c].targetPosition - 1; + changedInIteration = true; } - changedInIteration = true; + } } // Enforce Rule: Neighbor left (column c-1) must be lower. // This means the value at [c] must be GREATER than the value at [c-1]. - if (c > 0 && isFilled(data.tableRow[r].tableEntry[c - 1]) && - data.tableRow[r].tableEntry[c - 1].readings < round(((iteration_count / 2.0f) / (float)max_iterations) * MAX_NEIGHBOR_WEIGHT)) { + if (c > 0 && isFilled(data.tableRow[r].tableEntry[c - 1])) { if (data.tableRow[r].tableEntry[c].targetPosition <= data.tableRow[r].tableEntry[c - 1].targetPosition) { if(data.tableRow[r].tableEntry[c].readings >= data.tableRow[r].tableEntry[c - 1].readings) { - data.tableRow[r].tableEntry[c - 1].targetPosition = data.tableRow[r].tableEntry[c].targetPosition - 1; + data.tableRow[r].tableEntry[c].targetPosition += 1; } else { data.tableRow[r].tableEntry[c].targetPosition = data.tableRow[r].tableEntry[c - 1].targetPosition + 1; + changedInIteration = true; } - changedInIteration = true; + } } } From 92c046fb6f775aac08814e2e9d3a25ad198fc0bb Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Fri, 4 Jul 2025 17:44:10 -0500 Subject: [PATCH 272/451] operator change --- src/PowerTable_Helpers.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp index f451fae4..a2928695 100644 --- a/src/PowerTable_Helpers.cpp +++ b/src/PowerTable_Helpers.cpp @@ -1040,7 +1040,7 @@ bool PTHelpers::completePowerTable(PTData& data) { // This means the value at [r] must be LESS than the value at [r-1]. if (r > 0 && isFilled(data.tableRow[r - 1].tableEntry[c])) { if (data.tableRow[r].tableEntry[c].targetPosition >= data.tableRow[r - 1].tableEntry[c].targetPosition) { - if(data.tableRow[r].tableEntry[c].readings >= data.tableRow[r - 1].tableEntry[c].readings) { + if(data.tableRow[r].tableEntry[c].readings > data.tableRow[r - 1].tableEntry[c].readings) { data.tableRow[r].tableEntry[c].targetPosition += 1; } else { data.tableRow[r].tableEntry[c].targetPosition = data.tableRow[r - 1].tableEntry[c].targetPosition - 1; @@ -1054,7 +1054,7 @@ bool PTHelpers::completePowerTable(PTData& data) { // This means the value at [c] must be GREATER than the value at [c-1]. if (c > 0 && isFilled(data.tableRow[r].tableEntry[c - 1])) { if (data.tableRow[r].tableEntry[c].targetPosition <= data.tableRow[r].tableEntry[c - 1].targetPosition) { - if(data.tableRow[r].tableEntry[c].readings >= data.tableRow[r].tableEntry[c - 1].readings) { + if(data.tableRow[r].tableEntry[c].readings > data.tableRow[r].tableEntry[c - 1].readings) { data.tableRow[r].tableEntry[c].targetPosition += 1; } else { data.tableRow[r].tableEntry[c].targetPosition = data.tableRow[r].tableEntry[c - 1].targetPosition + 1; From 2fd52e4c655ec73275fb74da6a6b13f9cd62e469 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Fri, 4 Jul 2025 18:20:57 -0500 Subject: [PATCH 273/451] Give fill some cadence to always work with --- src/Power_Table.cpp | 8 ++++++++ test/test_table_fill.cpp | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 120308bc..2d441992 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -223,6 +223,13 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { BLE_ss2kCustomCharacteristic::notify(0x27, index.cadIndex); } +void fillAllCadenceLines(ptIndex index, PTData& ptData) { + for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { + if (ptData.tableRow[i].tableEntry[index.wattIndex].readings == 0) { + ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition + (i - index.cadIndex) * (index.wattIndex + 10); + } + } +} /** * @brief Updates or enters data into the power table for a specific row and entry. * @@ -250,6 +257,7 @@ void PowerTable::enterData(ptIndex index, int pos) { } } this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings++; + fillAllCadenceLines(index, this->ptData); } void PowerTable::fillTable() { diff --git a/test/test_table_fill.cpp b/test/test_table_fill.cpp index ef5dfeff..d5a3d8e2 100644 --- a/test/test_table_fill.cpp +++ b/test/test_table_fill.cpp @@ -48,8 +48,8 @@ void TestTableFill::test_fill_incomplete_table(void) { // } // loop through the table and check for INT16_MIN values - //for(int i=1; i<2; i++){ - helpers.completePowerTable(ptData);//} + for(int i=1; i<100; i++){ + helpers.completePowerTable(ptData);} // Save the filled power table const std::string outputFilePath = "test/output/power_table_filled.ptab"; savePTDataToCSV(ptData, outputFilePath); From 9fbb22a2a109e4f1180b5ea7e37c9435ebb2f421 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Fri, 4 Jul 2025 21:42:39 -0500 Subject: [PATCH 274/451] give cadence a chance --- dependencies.lock | 13 +- sdkconfig.release | 429 ------------------------------------- src/PowerTable_Helpers.cpp | 23 +- src/Power_Table.cpp | 26 ++- 4 files changed, 34 insertions(+), 457 deletions(-) diff --git a/dependencies.lock b/dependencies.lock index 17170be1..3aef0ca5 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -41,16 +41,6 @@ dependencies: registry_url: https://components.espressif.com/ type: service version: 1.6.3 - espressif/esp_modem: - component_hash: b541c3f5765d3ba062c0d004b9ca6da6d0af908293421c2dbe046c537fb2a011 - dependencies: - - name: idf - require: private - version: '>=4.1' - source: - registry_url: https://components.espressif.com/ - type: service - version: 1.4.0 espressif/mdns: component_hash: 3ec0af5f6bce310512e90f482388d21cc7c0e99668172d2f895356165fc6f7c5 dependencies: @@ -91,11 +81,10 @@ direct_dependencies: - espressif/cbor - espressif/esp-zboss-lib - espressif/esp-zigbee-lib -- espressif/esp_modem - espressif/mdns - espressif/network_provisioning - idf - joltwallet/littlefs -manifest_hash: e871ea1e1aff9421b8e57e1c5a4db8daeef71b071a2a17f239e5feebc4acdfc3 +manifest_hash: cdea08c215af25ecb07f34a572afe529ccee1d11a022752ebfb3b54cbc0cb5f8 target: esp32 version: 2.0.0 diff --git a/sdkconfig.release b/sdkconfig.release index a9f2dc38..7b3b88bf 100644 --- a/sdkconfig.release +++ b/sdkconfig.release @@ -259,13 +259,9 @@ CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y CONFIG_APP_BUILD_GENERATE_BINARIES=y CONFIG_APP_BUILD_BOOTLOADER=y CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y -# default: # CONFIG_APP_REPRODUCIBLE_BUILD is not set -# default: # CONFIG_APP_NO_BLOBS is not set -# default: # CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set -# default: # CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set # end of Build type @@ -300,7 +296,6 @@ CONFIG_BOOTLOADER_LOG_LEVEL=3 # # Format # -# default: # CONFIG_BOOTLOADER_LOG_COLORS is not set CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y # end of Format @@ -309,32 +304,23 @@ CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y # # Serial Flash Configurations # -# default: # CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y # end of Serial Flash Configurations # CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y -# default: # CONFIG_BOOTLOADER_FACTORY_RESET is not set -# default: # CONFIG_BOOTLOADER_APP_TEST is not set CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y CONFIG_BOOTLOADER_WDT_ENABLE=y -# default: # CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set CONFIG_BOOTLOADER_WDT_TIME_MS=9000 -# default: # CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set -# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set -# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set -# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 -# default: # CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set # end of Bootloader config @@ -342,11 +328,8 @@ CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 # Security features # CONFIG_SECURE_BOOT_V1_SUPPORTED=y -# default: # CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set -# default: # CONFIG_SECURE_BOOT is not set -# default: # CONFIG_SECURE_FLASH_ENC_ENABLED is not set # end of Security features @@ -354,11 +337,8 @@ CONFIG_SECURE_BOOT_V1_SUPPORTED=y # Application manager # CONFIG_APP_COMPILE_TIME_DATE=y -# default: # CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set -# default: # CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set -# default: # CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 # end of Application manager @@ -381,7 +361,6 @@ CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y # # Serial flasher config # -# default: # CONFIG_ESPTOOLPY_NO_STUB is not set # CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set @@ -403,7 +382,6 @@ CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set CONFIG_ESPTOOLPY_FLASHSIZE="2MB" -# default: # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set @@ -433,7 +411,6 @@ CONFIG_PARTITION_TABLE_MD5=y # CONFIG_ARDUINO_VARIANT="esp32" CONFIG_ENABLE_ARDUINO_DEPENDS=y -# default: # CONFIG_AUTOSTART_ARDUINO is not set # CONFIG_ARDUINO_RUN_CORE0 is not set CONFIG_ARDUINO_RUN_CORE1=y @@ -455,9 +432,7 @@ CONFIG_ARDUINO_UDP_RUN_CORE0=y # CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set CONFIG_ARDUINO_UDP_RUNNING_CORE=0 CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 -# default: # CONFIG_ARDUINO_ISR_IRAM is not set -# default: # CONFIG_DISABLE_HAL_LOCKS is not set # @@ -470,9 +445,7 @@ CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE=y # CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set # CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=0 -# default: # CONFIG_ARDUHAL_LOG_COLORS is not set -# default: # CONFIG_ARDUHAL_ESP_LOG is not set # end of Debug Log Configuration @@ -487,25 +460,17 @@ CONFIG_ARDUINO_SELECTIVE_SPI=y CONFIG_ARDUINO_SELECTIVE_Wire=y CONFIG_ARDUINO_SELECTIVE_ESP_SR=y CONFIG_ARDUINO_SELECTIVE_EEPROM=y -# default: # CONFIG_ARDUINO_SELECTIVE_Preferences is not set -# default: # CONFIG_ARDUINO_SELECTIVE_Ticker is not set CONFIG_ARDUINO_SELECTIVE_Update=y -# default: # CONFIG_ARDUINO_SELECTIVE_Zigbee is not set CONFIG_ARDUINO_SELECTIVE_FS=y -# default: # CONFIG_ARDUINO_SELECTIVE_SD is not set -# default: # CONFIG_ARDUINO_SELECTIVE_SD_MMC is not set -# default: # CONFIG_ARDUINO_SELECTIVE_SPIFFS is not set -# default: # CONFIG_ARDUINO_SELECTIVE_FFat is not set CONFIG_ARDUINO_SELECTIVE_LittleFS=y CONFIG_ARDUINO_SELECTIVE_Network=y -# default: # CONFIG_ARDUINO_SELECTIVE_Ethernet is not set CONFIG_ARDUINO_SELECTIVE_PPP=y CONFIG_ARDUINO_SELECTIVE_ArduinoOTA=y @@ -513,23 +478,17 @@ CONFIG_ARDUINO_SELECTIVE_AsyncUDP=y CONFIG_ARDUINO_SELECTIVE_DNSServer=y CONFIG_ARDUINO_SELECTIVE_ESPmDNS=y CONFIG_ARDUINO_SELECTIVE_HTTPClient=y -# default: # CONFIG_ARDUINO_SELECTIVE_Matter is not set -# default: # CONFIG_ARDUINO_SELECTIVE_NetBIOS is not set CONFIG_ARDUINO_SELECTIVE_WebServer=y CONFIG_ARDUINO_SELECTIVE_WiFi=y CONFIG_ARDUINO_SELECTIVE_NetworkClientSecure=y CONFIG_ARDUINO_SELECTIVE_WiFiProv=y CONFIG_ARDUINO_SELECTIVE_BLE=y -# default: # CONFIG_ARDUINO_SELECTIVE_BluetoothSerial is not set CONFIG_ARDUINO_SELECTIVE_SimpleBLE=y -# default: # CONFIG_ARDUINO_SELECTIVE_RainMaker is not set -# default: # CONFIG_ARDUINO_SELECTIVE_OpenThread is not set -# default: # CONFIG_ARDUINO_SELECTIVE_Insights is not set # end of Arduino Configuration @@ -546,35 +505,25 @@ CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 -# default: # CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set CONFIG_COMPILER_HIDE_PATHS_MACROS=y -# default: # CONFIG_COMPILER_CXX_EXCEPTIONS is not set -# default: # CONFIG_COMPILER_CXX_RTTI is not set CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set # CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set # CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set -# default: # CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set -# default: # CONFIG_COMPILER_WARN_WRITE_STRINGS is not set CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y -# default: # CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set -# default: # CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set -# default: # CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set -# default: # CONFIG_COMPILER_DUMP_RTL_FILES is not set CONFIG_COMPILER_RT_LIB_GCCLIB=y CONFIG_COMPILER_RT_LIB_NAME="gcc" CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y # CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set -# default: # CONFIG_COMPILER_STATIC_ANALYZER is not set # end of Compiler options @@ -627,15 +576,10 @@ CONFIG_BT_NIMBLE_ROLE_CENTRAL=y CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y CONFIG_BT_NIMBLE_ROLE_OBSERVER=y -# default: # CONFIG_BT_NIMBLE_NVS_PERSIST is not set -# default: # CONFIG_BT_NIMBLE_SMP_ID_RESET is not set -# default: # CONFIG_BT_NIMBLE_SECURITY_ENABLE is not set -# default: # CONFIG_BT_NIMBLE_DEBUG is not set -# default: # CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 @@ -663,22 +607,16 @@ CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 -# default: # CONFIG_BT_NIMBLE_MESH is not set CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 -# default: # CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set -# default: # CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set CONFIG_BT_NIMBLE_WHITELIST_SIZE=1 -# default: # CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set -# default: # CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set CONFIG_BT_NIMBLE_USE_ESP_TIMER=y CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y -# default: # CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set # @@ -688,7 +626,6 @@ CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y # # GAP Appearance write permissions # -# default: # CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set # end of GAP Appearance write permissions @@ -704,7 +641,6 @@ CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 # # GAP device name write permissions # -# default: # CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set # end of GAP device name write permissions @@ -716,49 +652,33 @@ CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 -# default: # CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL is not set # end of GAP Service # # BLE Services # -# default: # CONFIG_BT_NIMBLE_HID_SERVICE is not set -# default: # CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY is not set # # Device Information Service # -# default: # CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID is not set -# default: # CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED is not set # end of Device Information Service # end of BLE Services -# default: # CONFIG_BT_NIMBLE_VS_SUPPORT is not set -# default: # CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set -# default: # CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set -# default: # CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set -# default: # CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT is not set # @@ -772,7 +692,6 @@ CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 # end of Host-controller Transport CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 -# default: # CONFIG_BT_NIMBLE_SUBRATE is not set # end of NimBLE Options @@ -815,12 +734,9 @@ CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y CONFIG_BTDM_SCAN_DUPL_TYPE=0 CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 -# default: # CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y -# default: # CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set -# default: # CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 @@ -829,15 +745,12 @@ CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # # BLE disconnects when Instant Passed (0x28) occurs # -# default: # CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set -# default: # CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set # end of BLE disconnects when Instant Passed (0x28) occurs CONFIG_BTDM_BLE_CHAN_ASS_EN=y CONFIG_BTDM_BLE_PING_EN=y -# default: # CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 is not set CONFIG_BTDM_RESERVE_DRAM=0xdb5c CONFIG_BTDM_CTRL_HLI=y @@ -847,21 +760,17 @@ CONFIG_BTDM_CTRL_HLI=y # Common Options # CONFIG_BT_ALARM_MAX_NUM=50 -# default: # CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set # end of Common Options -# default: # CONFIG_BT_HCI_LOG_DEBUG_EN is not set # end of Bluetooth -# default: # CONFIG_BLE_MESH is not set # # Console Library # -# default: # CONFIG_CONSOLE_SORTED_HELP is not set # end of Console Library @@ -872,7 +781,6 @@ CONFIG_BT_ALARM_MAX_NUM=50 # # TWAI Configuration # -# default: # CONFIG_TWAI_ISR_IN_IRAM is not set CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y @@ -885,9 +793,7 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # Legacy ADC Driver Configuration # CONFIG_ADC_DISABLE_DAC=y -# default: # CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set # @@ -896,7 +802,6 @@ CONFIG_ADC_DISABLE_DAC=y CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y CONFIG_ADC_CAL_LUT_ENABLE=y -# default: # CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set # end of Legacy ADC Calibration Configuration # end of Legacy ADC Driver Configuration @@ -904,63 +809,49 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # # Legacy DAC Driver Configurations # -# default: # CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy DAC Driver Configurations # # Legacy MCPWM Driver Configurations # -# default: # CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy MCPWM Driver Configurations # # Legacy Timer Group Driver Configurations # -# default: # CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Timer Group Driver Configurations # # Legacy RMT Driver Configurations # -# default: # CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy RMT Driver Configurations # # Legacy I2S Driver Configurations # -# default: # CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy I2S Driver Configurations # # Legacy PCNT Driver Configurations # -# default: # CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy PCNT Driver Configurations # # Legacy SDM Driver Configurations # -# default: # CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set -# default: # CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy SDM Driver Configurations # end of Driver Configurations @@ -968,9 +859,7 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # # eFuse Bit Manager # -# default: # CONFIG_EFUSE_CUSTOM_TABLE is not set -# default: # CONFIG_EFUSE_VIRTUAL is not set # CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y @@ -982,28 +871,19 @@ CONFIG_EFUSE_MAX_BLK_LEN=192 # ESP-TLS # CONFIG_ESP_TLS_USING_MBEDTLS=y -# default: # CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set -# default: # CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set -# default: # CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set -# default: # CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set -# default: # CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set -# default: # CONFIG_ESP_TLS_PSK_VERIFICATION is not set -# default: # CONFIG_ESP_TLS_INSECURE is not set # end of ESP-TLS # # ADC and ADC Calibration # -# default: # CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set # @@ -1015,7 +895,6 @@ CONFIG_ADC_CALI_LUT_ENABLE=y # end of ADC Calibration Configurations CONFIG_ADC_DISABLE_DAC_OUTPUT=y -# default: # CONFIG_ADC_ENABLE_DEBUG_LOG is not set # end of ADC and ADC Calibration @@ -1024,9 +903,7 @@ CONFIG_ADC_DISABLE_DAC_OUTPUT=y # CONFIG_ESP_COEX_ENABLED=y CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y -# default: # CONFIG_ESP_COEX_POWER_MANAGEMENT is not set -# default: # CONFIG_ESP_COEX_GPIO_DEBUG is not set # end of Wireless Coexistence @@ -1039,11 +916,8 @@ CONFIG_ESP_ERR_TO_NAME_LOOKUP=y # # ESP-Driver:DAC Configurations # -# default: # CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_DAC_ISR_IRAM_SAFE is not set -# default: # CONFIG_DAC_ENABLE_DEBUG_LOG is not set CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # end of ESP-Driver:DAC Configurations @@ -1051,9 +925,7 @@ CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # # ESP-Driver:GPIO Configurations # -# default: # CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set -# default: # CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:GPIO Configurations @@ -1061,90 +933,68 @@ CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # ESP-Driver:GPTimer Configurations # CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y -# default: # CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_GPTIMER_ISR_IRAM_SAFE is not set -# default: # CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:GPTimer Configurations # # ESP-Driver:I2C Configurations # -# default: # CONFIG_I2C_ISR_IRAM_SAFE is not set -# default: # CONFIG_I2C_ENABLE_DEBUG_LOG is not set -# default: # CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set # end of ESP-Driver:I2C Configurations # # ESP-Driver:I2S Configurations # -# default: # CONFIG_I2S_ISR_IRAM_SAFE is not set -# default: # CONFIG_I2S_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:I2S Configurations # # ESP-Driver:LEDC Configurations # -# default: # CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:LEDC Configurations # # ESP-Driver:MCPWM Configurations # -# default: # CONFIG_MCPWM_ISR_IRAM_SAFE is not set -# default: # CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:MCPWM Configurations # # ESP-Driver:PCNT Configurations # -# default: # CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_PCNT_ISR_IRAM_SAFE is not set -# default: # CONFIG_PCNT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:PCNT Configurations # # ESP-Driver:RMT Configurations # -# default: # CONFIG_RMT_ISR_IRAM_SAFE is not set -# default: # CONFIG_RMT_RECV_FUNC_IN_IRAM is not set -# default: # CONFIG_RMT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:RMT Configurations # # ESP-Driver:Sigma Delta Modulator Configurations # -# default: # CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_SDM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Sigma Delta Modulator Configurations # # ESP-Driver:SPI Configurations # -# default: # CONFIG_SPI_MASTER_IN_IRAM is not set CONFIG_SPI_MASTER_ISR_IN_IRAM=y -# default: # CONFIG_SPI_SLAVE_IN_IRAM is not set CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # end of ESP-Driver:SPI Configurations @@ -1152,36 +1002,28 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # # ESP-Driver:Touch Sensor Configurations # -# default: # CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set -# default: # CONFIG_TOUCH_ISR_IRAM_SAFE is not set -# default: # CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Touch Sensor Configurations # # ESP-Driver:UART Configurations # -# default: # CONFIG_UART_ISR_IN_IRAM is not set # end of ESP-Driver:UART Configurations # # Ethernet # -# default: # CONFIG_ETH_USE_ESP32_EMAC is not set -# default: # CONFIG_ETH_USE_SPI_ETHERNET is not set -# default: # CONFIG_ETH_USE_OPENETH is not set # end of Ethernet # # Event Loop Library # -# default: # CONFIG_ESP_EVENT_LOOP_PROFILING is not set CONFIG_ESP_EVENT_POST_FROM_ISR=y CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y @@ -1191,7 +1033,6 @@ CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y # GDB Stub # CONFIG_ESP_GDBSTUB_ENABLED=y -# default: # CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y CONFIG_ESP_GDBSTUB_MAX_TASKS=32 @@ -1208,11 +1049,8 @@ CONFIG_ESPHID_TASK_SIZE_BLE=4096 # ESP HTTP client # CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y -# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set -# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set -# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 # end of ESP HTTP client @@ -1224,11 +1062,8 @@ CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 CONFIG_HTTPD_MAX_URI_LEN=512 CONFIG_HTTPD_ERR_RESP_NO_DELAY=y CONFIG_HTTPD_PURGE_BUF_LEN=32 -# default: # CONFIG_HTTPD_LOG_PURGE_DATA is not set -# default: # CONFIG_HTTPD_WS_SUPPORT is not set -# default: # CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # end of HTTP Server @@ -1236,9 +1071,7 @@ CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # # ESP HTTPS OTA # -# default: # CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set -# default: # CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS OTA @@ -1246,7 +1079,6 @@ CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # # ESP HTTPS server # -# default: # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS server @@ -1293,27 +1125,20 @@ CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 # CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 -# default: # CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set -# default: # CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set # end of MAC Config # # Sleep Config # -# default: # CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y -# default: # CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y -# default: # CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 -# default: # CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set -# default: # CONFIG_ESP_SLEEP_DEBUG is not set CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y # end of Sleep Config @@ -1350,7 +1175,6 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # # ESP-Driver:LCD Controller Configurations # -# default: # CONFIG_LCD_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:LCD Controller Configurations @@ -1363,19 +1187,14 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # ESP NETIF Adapter # CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 -# default: # CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set CONFIG_ESP_NETIF_TCPIP_LWIP=y # CONFIG_ESP_NETIF_LOOPBACK is not set CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y -# default: # CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set -# default: # CONFIG_ESP_NETIF_L2_TAP is not set -# default: # CONFIG_ESP_NETIF_BRIDGE_EN is not set -# default: # CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set # end of ESP NETIF Adapter @@ -1389,44 +1208,35 @@ CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y # CONFIG_ESP_PHY_ENABLED=y CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y -# default: # CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP_PHY_MAX_TX_POWER=20 -# default: # CONFIG_ESP_PHY_REDUCE_TX_POWER is not set -# default: # CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set CONFIG_ESP_PHY_RF_CAL_PARTIAL=y # CONFIG_ESP_PHY_RF_CAL_NONE is not set # CONFIG_ESP_PHY_RF_CAL_FULL is not set CONFIG_ESP_PHY_CALIBRATION_MODE=0 -# default: # CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set -# default: # CONFIG_ESP_PHY_RECORD_USED_TIME is not set # end of PHY # # Power Management # -# default: # CONFIG_PM_ENABLE is not set -# default: # CONFIG_PM_SLP_IRAM_OPT is not set # end of Power Management # # ESP PSRAM # -# default: # CONFIG_SPIRAM is not set # end of ESP PSRAM # # ESP Ringbuf # -# default: # CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set # end of ESP Ringbuf @@ -1446,13 +1256,11 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 # # Memory # -# default: # CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set # # Non-backward compatible options # -# default: # CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set # end of Non-backward compatible options # end of Memory @@ -1460,7 +1268,6 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 # # Trace memory # -# default: # CONFIG_ESP32_TRAX is not set CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 # end of Trace memory @@ -1496,14 +1303,11 @@ CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 CONFIG_ESP_INT_WDT_CHECK_CPU1=y CONFIG_ESP_TASK_WDT_EN=y CONFIG_ESP_TASK_WDT_INIT=y -# default: # CONFIG_ESP_TASK_WDT_PANIC is not set CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# default: # CONFIG_ESP_PANIC_HANDLER_IRAM is not set -# default: # CONFIG_ESP_DEBUG_STUBS_ENABLE is not set CONFIG_ESP_DEBUG_OCDAWARE=y CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y @@ -1523,7 +1327,6 @@ CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y CONFIG_ESP_BROWNOUT_DET_LVL=0 # end of Brownout Detector -# default: # CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y # end of ESP System Settings @@ -1539,18 +1342,15 @@ CONFIG_ESP_IPC_ISR_ENABLE=y # # ESP Timer (High Resolution Timer) # -# default: # CONFIG_ESP_TIMER_PROFILING is not set CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 -# default: # CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y -# default: # CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set CONFIG_ESP_TIMER_IMPL_TG0_LAC=y # end of ESP Timer (High Resolution Timer) @@ -1569,7 +1369,6 @@ CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y # CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 -# default: # CONFIG_ESP_WIFI_CSI_ENABLED is not set CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP_WIFI_TX_BA_WIN=6 @@ -1580,17 +1379,13 @@ CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 -# default: # CONFIG_ESP_WIFI_IRAM_OPT is not set -# default: # CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set -# default: # CONFIG_ESP_WIFI_RX_IRAM_OPT is not set CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y CONFIG_ESP_WIFI_ENABLE_SAE_PK=y CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y -# default: # CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 @@ -1598,41 +1393,28 @@ CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y CONFIG_ESP_WIFI_GMAC_SUPPORT=y CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y -# default: # CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 -# default: # CONFIG_ESP_WIFI_NAN_ENABLE is not set CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y -# default: # CONFIG_ESP_WIFI_WAPI_PSK is not set -# default: # CONFIG_ESP_WIFI_11KV_SUPPORT is not set -# default: # CONFIG_ESP_WIFI_MBO_SUPPORT is not set -# default: # CONFIG_ESP_WIFI_DPP_SUPPORT is not set -# default: # CONFIG_ESP_WIFI_11R_SUPPORT is not set -# default: # CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set # # WPS Configuration Options # -# default: # CONFIG_ESP_WIFI_WPS_STRICT is not set -# default: # CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set # end of WPS Configuration Options -# default: # CONFIG_ESP_WIFI_DEBUG_PRINT is not set -# default: # CONFIG_ESP_WIFI_TESTING_OPTIONS is not set CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y -# default: # CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set # end of Wi-Fi @@ -1679,15 +1461,12 @@ CONFIG_FATFS_CODEPAGE=437 CONFIG_FATFS_FS_LOCK=0 CONFIG_FATFS_TIMEOUT_MS=10000 CONFIG_FATFS_PER_FILE_CACHE=y -# default: # CONFIG_FATFS_USE_FASTSEEK is not set CONFIG_FATFS_USE_STRFUNC_NONE=y # CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set # CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 -# default: # CONFIG_FATFS_IMMEDIATE_FSYNC is not set -# default: # CONFIG_FATFS_USE_LABEL is not set CONFIG_FATFS_LINK_LOCK=y # end of FAT Filesystem support @@ -1699,9 +1478,7 @@ CONFIG_FATFS_LINK_LOCK=y # # Kernel # -# default: # CONFIG_FREERTOS_SMP is not set -# default: # CONFIG_FREERTOS_UNICORE is not set CONFIG_FREERTOS_HZ=1000 # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set @@ -1709,12 +1486,9 @@ CONFIG_FREERTOS_HZ=1000 CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 -# default: # CONFIG_FREERTOS_USE_IDLE_HOOK is not set -# default: # CONFIG_FREERTOS_USE_TICK_HOOK is not set CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 -# default: # CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set CONFIG_FREERTOS_USE_TIMERS=y CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" @@ -1727,38 +1501,28 @@ CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 -# default: # CONFIG_FREERTOS_USE_TRACE_FACILITY is not set -# default: # CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set -# default: # CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set -# default: # CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set # end of Kernel # # Port # -# default: # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y -# default: # CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set -# default: # CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y CONFIG_FREERTOS_ISR_STACKSIZE=1536 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y -# default: # CONFIG_FREERTOS_FPU_IN_ISR is not set CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y CONFIG_FREERTOS_CORETIMER_0=y # CONFIG_FREERTOS_CORETIMER_1 is not set CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y -# default: # CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set -# default: # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set # end of Port @@ -1797,13 +1561,9 @@ CONFIG_HEAP_POISONING_DISABLED=y CONFIG_HEAP_TRACING_OFF=y # CONFIG_HEAP_TRACING_STANDALONE is not set # CONFIG_HEAP_TRACING_TOHOST is not set -# default: # CONFIG_HEAP_USE_HOOKS is not set -# default: # CONFIG_HEAP_TASK_TRACKING is not set -# default: # CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set -# default: # CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set # end of Heap memory debugging @@ -1832,7 +1592,6 @@ CONFIG_LOG_MAXIMUM_LEVEL=0 # # Level Settings # -# default: # CONFIG_LOG_MASTER_LEVEL is not set CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y # CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set @@ -1847,7 +1606,6 @@ CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 # # Format # -# default: # CONFIG_LOG_COLORS is not set CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set @@ -1859,45 +1617,31 @@ CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LWIP_ENABLE=y CONFIG_LWIP_LOCAL_HOSTNAME="espressif" -# default: # CONFIG_LWIP_NETIF_API is not set CONFIG_LWIP_TCPIP_TASK_PRIO=18 -# default: # CONFIG_LWIP_TCPIP_CORE_LOCKING is not set -# default: # CONFIG_LWIP_CHECK_THREAD_SAFETY is not set CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -# default: # CONFIG_LWIP_L2_TO_L3_COPY is not set -# default: # CONFIG_LWIP_IRAM_OPTIMIZATION is not set -# default: # CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set CONFIG_LWIP_TIMERS_ONDEMAND=y CONFIG_LWIP_ND6=y -# default: # CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set CONFIG_LWIP_MAX_SOCKETS=10 -# default: # CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set -# default: # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y CONFIG_LWIP_SO_RCVBUF=y -# default: # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP_DEFAULT_TTL=64 CONFIG_LWIP_IP4_FRAG=y CONFIG_LWIP_IP6_FRAG=y -# default: # CONFIG_LWIP_IP4_REASSEMBLY is not set -# default: # CONFIG_LWIP_IP6_REASSEMBLY is not set CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 -# default: # CONFIG_LWIP_IP_FORWARD is not set -# default: # CONFIG_LWIP_STATS is not set CONFIG_LWIP_ESP_GRATUITOUS_ARP=y CONFIG_LWIP_GARP_TMR_INTERVAL=60 @@ -1907,10 +1651,8 @@ CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y # CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set # CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set -# default: # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y -# default: # CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set CONFIG_LWIP_DHCP_OPTIONS_LEN=68 CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 @@ -1926,16 +1668,12 @@ CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y CONFIG_LWIP_DHCPS_ADD_DNS=y # end of DHCP server -# default: # CONFIG_LWIP_AUTOIP is not set CONFIG_LWIP_IPV4=y CONFIG_LWIP_IPV6=y -# default: # CONFIG_LWIP_IPV6_AUTOCONFIG is not set CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 -# default: # CONFIG_LWIP_IPV6_FORWARD is not set -# default: # CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set CONFIG_LWIP_NETIF_LOOPBACK=y CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 @@ -1959,7 +1697,6 @@ CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 CONFIG_LWIP_TCP_QUEUE_OOSEQ=y CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 -# default: # CONFIG_LWIP_TCP_SACK_OUT is not set CONFIG_LWIP_TCP_OVERSIZE_MSS=y # CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set @@ -1977,9 +1714,7 @@ CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 # # Checksums # -# default: # CONFIG_LWIP_CHECKSUM_CHECK_IP is not set -# default: # CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums @@ -1994,18 +1729,14 @@ CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 -# default: # CONFIG_LWIP_PPP_SUPPORT is not set -# default: # CONFIG_LWIP_SLIP_SUPPORT is not set # # ICMP # CONFIG_LWIP_ICMP=y -# default: # CONFIG_LWIP_MULTICAST_PING is not set -# default: # CONFIG_LWIP_BROADCAST_PING is not set # end of ICMP @@ -2019,7 +1750,6 @@ CONFIG_LWIP_MAX_RAW_PCBS=16 # SNTP # CONFIG_LWIP_SNTP_MAX_SERVERS=1 -# default: # CONFIG_LWIP_DHCP_GET_NTP_SRV is not set CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 CONFIG_LWIP_SNTP_STARTUP_DELAY=y @@ -2031,9 +1761,7 @@ CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 # CONFIG_LWIP_DNS_MAX_HOST_IP=1 CONFIG_LWIP_DNS_MAX_SERVERS=3 -# default: # CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set -# default: # CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set # end of DNS @@ -2065,7 +1793,6 @@ CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y # CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set # end of Hooks -# default: # CONFIG_LWIP_DEBUG is not set # end of LWIP @@ -2078,21 +1805,15 @@ CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 -# default: # CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set -# default: # CONFIG_MBEDTLS_DEBUG is not set # # mbedTLS v3.x related # -# default: # CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set -# default: # CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set -# default: # CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set -# default: # CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y CONFIG_MBEDTLS_PKCS7_C=y @@ -2105,35 +1826,26 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set -# default: # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set -# default: # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 # end of Certificate Bundle -# default: # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set CONFIG_MBEDTLS_CMAC_C=y CONFIG_MBEDTLS_HARDWARE_AES=y CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y CONFIG_MBEDTLS_HARDWARE_MPI=y -# default: # CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set CONFIG_MBEDTLS_HARDWARE_SHA=y CONFIG_MBEDTLS_ROM_MD5=y -# default: # CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set -# default: # CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set CONFIG_MBEDTLS_HAVE_TIME=y -# default: # CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set -# default: # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y CONFIG_MBEDTLS_SHA512_C=y -# default: # CONFIG_MBEDTLS_SHA3_C is not set CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y # CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set @@ -2160,9 +1872,7 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y CONFIG_MBEDTLS_SSL_RENEGOTIATION=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y -# default: # CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set -# default: # CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set CONFIG_MBEDTLS_SSL_ALPN=y CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y @@ -2172,21 +1882,15 @@ CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y # Symmetric Ciphers # CONFIG_MBEDTLS_AES_C=y -# default: # CONFIG_MBEDTLS_CAMELLIA_C is not set -# default: # CONFIG_MBEDTLS_DES_C is not set -# default: # CONFIG_MBEDTLS_BLOWFISH_C is not set -# default: # CONFIG_MBEDTLS_XTEA_C is not set CONFIG_MBEDTLS_CCM_C=y CONFIG_MBEDTLS_GCM_C=y -# default: # CONFIG_MBEDTLS_NIST_KW_C is not set # end of Symmetric Ciphers -# default: # CONFIG_MBEDTLS_RIPEMD160_C is not set # @@ -2201,11 +1905,9 @@ CONFIG_MBEDTLS_X509_CSR_PARSE_C=y CONFIG_MBEDTLS_ECP_C=y CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y -# default: # CONFIG_MBEDTLS_DHM_C is not set CONFIG_MBEDTLS_ECDH_C=y CONFIG_MBEDTLS_ECDSA_C=y -# default: # CONFIG_MBEDTLS_ECJPAKE_C is not set CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y @@ -2220,15 +1922,10 @@ CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y CONFIG_MBEDTLS_ECP_NIST_OPTIM=y -# default: # CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set -# default: # CONFIG_MBEDTLS_POLY1305_C is not set -# default: # CONFIG_MBEDTLS_CHACHA20_C is not set -# default: # CONFIG_MBEDTLS_HKDF_C is not set -# default: # CONFIG_MBEDTLS_THREADING_C is not set CONFIG_MBEDTLS_ERROR_STRINGS=y CONFIG_MBEDTLS_FS_IO=y @@ -2237,25 +1934,15 @@ CONFIG_MBEDTLS_FS_IO=y # # ESP-MQTT Configurations # -# default: # CONFIG_MQTT_PROTOCOL_311 is not set -# default: # CONFIG_MQTT_PROTOCOL_5 is not set -# default: # CONFIG_MQTT_TRANSPORT_SSL is not set -# default: # CONFIG_MQTT_TRANSPORT_WEBSOCKET is not set -# default: # CONFIG_MQTT_MSG_ID_INCREMENTAL is not set -# default: # CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set -# default: # CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set -# default: # CONFIG_MQTT_USE_CUSTOM_CONFIG is not set -# default: # CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set -# default: # CONFIG_MQTT_CUSTOM_OUTBOX is not set # end of ESP-MQTT Configurations @@ -2268,7 +1955,6 @@ CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y # CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set # CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y -# default: # CONFIG_NEWLIB_NANO_FORMAT is not set CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y # CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set @@ -2279,22 +1965,18 @@ CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y # # NVS # -# default: # CONFIG_NVS_ASSERT_ERROR_CHECK is not set -# default: # CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set # end of NVS # # OpenThread # -# default: # CONFIG_OPENTHREAD_ENABLED is not set # # OpenThread Spinel # -# default: # CONFIG_OPENTHREAD_SPINEL_ONLY is not set # end of OpenThread Spinel # end of OpenThread @@ -2348,7 +2030,6 @@ CONFIG_SPI_FLASH_BROWNOUT_RESET=y # Features here require specific hardware (READ DOCS FIRST!) # CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 -# default: # CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set # end of Optional and Experimental Features (READ DOCS FIRST) # end of Main Flash configuration @@ -2356,27 +2037,20 @@ CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 # # SPI Flash driver # -# default: # CONFIG_SPI_FLASH_VERIFY_WRITE is not set -# default: # CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y # CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set # CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set -# default: # CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set -# default: # CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 -# default: # CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set -# default: # CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set -# default: # CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set # @@ -2391,9 +2065,7 @@ CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y -# default: # CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set -# default: # CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set # end of Auto-detect flash chips @@ -2410,17 +2082,14 @@ CONFIG_SPIFFS_MAX_PARTITIONS=3 # CONFIG_SPIFFS_CACHE=y CONFIG_SPIFFS_CACHE_WR=y -# default: # CONFIG_SPIFFS_CACHE_STATS is not set # end of SPIFFS Cache Configuration CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 -# default: # CONFIG_SPIFFS_GC_STATS is not set CONFIG_SPIFFS_PAGE_SIZE=256 CONFIG_SPIFFS_OBJ_NAME_LEN=32 -# default: # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y @@ -2430,17 +2099,11 @@ CONFIG_SPIFFS_USE_MTIME=y # # Debug Configuration # -# default: # CONFIG_SPIFFS_DBG is not set -# default: # CONFIG_SPIFFS_API_DBG is not set -# default: # CONFIG_SPIFFS_GC_DBG is not set -# default: # CONFIG_SPIFFS_CACHE_DBG is not set -# default: # CONFIG_SPIFFS_CHECK_DBG is not set -# default: # CONFIG_SPIFFS_TEST_VISUALISATION is not set # end of Debug Configuration # end of SPIFFS Configuration @@ -2454,7 +2117,6 @@ CONFIG_SPIFFS_USE_MTIME=y # CONFIG_WS_TRANSPORT=y CONFIG_WS_BUFFER_SIZE=1024 -# default: # CONFIG_WS_DYNAMIC_BUFFER is not set # end of Websocket # end of TCP Transport @@ -2462,7 +2124,6 @@ CONFIG_WS_BUFFER_SIZE=1024 # # Ultra Low Power (ULP) Co-processor # -# default: # CONFIG_ULP_COPROC_ENABLED is not set # @@ -2476,14 +2137,10 @@ CONFIG_WS_BUFFER_SIZE=1024 # CONFIG_UNITY_ENABLE_FLOAT=y CONFIG_UNITY_ENABLE_DOUBLE=y -# default: # CONFIG_UNITY_ENABLE_64BIT is not set -# default: # CONFIG_UNITY_ENABLE_COLOR is not set CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y -# default: # CONFIG_UNITY_ENABLE_FIXTURE is not set -# default: # CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set # end of Unity unit testing library @@ -2494,7 +2151,6 @@ CONFIG_VFS_SUPPORT_IO=y CONFIG_VFS_SUPPORT_DIR=y CONFIG_VFS_SUPPORT_SELECT=y CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y -# default: # CONFIG_VFS_SELECT_IN_RAM is not set CONFIG_VFS_SUPPORT_TERMIOS=y CONFIG_VFS_MAX_COUNT=8 @@ -2521,14 +2177,10 @@ CONFIG_WL_SECTOR_SIZE=4096 # CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 -# default: # CONFIG_WIFI_PROV_BLE_BONDING is not set CONFIG_WIFI_PROV_BLE_SEC_CONN=y -# default: # CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set -# default: # CONFIG_WIFI_PROV_BLE_NOTIFY is not set -# default: # CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set @@ -2537,33 +2189,9 @@ CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # # Zigbee # -# default: # CONFIG_ZB_ENABLED is not set # end of Zigbee -# -# esp-modem -# -# default: -CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y -# default: -# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set -# default: -CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 -# default: -# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set -# default: -# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set -# default: -CONFIG_ESP_MODEM_C_API_STR_MAX=128 -# default: -# CONFIG_ESP_MODEM_URC_HANDLER is not set -# default: -# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set -# default: -# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set -# end of esp-modem - # # mDNS # @@ -2582,20 +2210,15 @@ CONFIG_MDNS_TASK_AFFINITY=0x0 # CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y -# default: # CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set # end of MDNS Memory Configuration CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 CONFIG_MDNS_TIMER_PERIOD_MS=100 -# default: # CONFIG_MDNS_NETWORKING_SOCKET is not set -# default: # CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set -# default: # CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set CONFIG_MDNS_ENABLE_CONSOLE_CLI=y -# default: # CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set CONFIG_MDNS_MULTIPLE_INSTANCE=y @@ -2613,12 +2236,9 @@ CONFIG_MDNS_PREDEF_NETIF_AP=y CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 -# default: # CONFIG_NETWORK_PROV_BLE_BONDING is not set CONFIG_NETWORK_PROV_BLE_SEC_CONN=y -# default: # CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set -# default: # CONFIG_NETWORK_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y # CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set @@ -2627,7 +2247,6 @@ CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y # # LittleFS # -# default: # CONFIG_LITTLEFS_SDMMC_SUPPORT is not set CONFIG_LITTLEFS_MAX_PARTITIONS=3 CONFIG_LITTLEFS_PAGE_SIZE=256 @@ -2638,41 +2257,29 @@ CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 CONFIG_LITTLEFS_CACHE_SIZE=512 CONFIG_LITTLEFS_BLOCK_CYCLES=512 CONFIG_LITTLEFS_USE_MTIME=y -# default: # CONFIG_LITTLEFS_USE_ONLY_HASH is not set -# default: # CONFIG_LITTLEFS_HUMAN_READABLE is not set CONFIG_LITTLEFS_MTIME_USE_SECONDS=y # CONFIG_LITTLEFS_MTIME_USE_NONCE is not set -# default: # CONFIG_LITTLEFS_SPIFFS_COMPAT is not set -# default: # CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set -# default: # CONFIG_LITTLEFS_FCNTL_GET_PATH is not set -# default: # CONFIG_LITTLEFS_MULTIVERSION is not set # CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y # CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set CONFIG_LITTLEFS_ASSERTS=y -# default: # CONFIG_LITTLEFS_MMAP_PARTITION is not set # end of LittleFS # end of Component config -# default: # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set # Deprecated options for backward compatibility # CONFIG_APP_BUILD_TYPE_ELF_RAM is not set -# default: # CONFIG_NO_BLOBS is not set -# default: # CONFIG_ESP32_NO_BLOBS is not set -# default: # CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set -# default: # CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set # CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set # CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set @@ -2681,9 +2288,7 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y # CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set # CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set CONFIG_LOG_BOOTLOADER_LEVEL=3 -# default: # CONFIG_APP_ROLLBACK_ENABLE is not set -# default: # CONFIG_FLASH_ENCRYPTION_ENABLED is not set # CONFIG_FLASHMODE_QIO is not set # CONFIG_FLASHMODE_QOUT is not set @@ -2699,13 +2304,11 @@ CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y # CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set # CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 -# default: # CONFIG_CXX_EXCEPTIONS is not set CONFIG_STACK_CHECK_NONE=y # CONFIG_STACK_CHECK_NORM is not set # CONFIG_STACK_CHECK_STRONG is not set # CONFIG_STACK_CHECK_ALL is not set -# default: # CONFIG_WARN_WRITE_STRINGS is not set # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set CONFIG_ESP32_APPTRACE_DEST_NONE=y @@ -2727,9 +2330,7 @@ CONFIG_NIMBLE_ROLE_CENTRAL=y CONFIG_NIMBLE_ROLE_PERIPHERAL=y CONFIG_NIMBLE_ROLE_BROADCASTER=y CONFIG_NIMBLE_ROLE_OBSERVER=y -# default: # CONFIG_NIMBLE_NVS_PERSIST is not set -# default: # CONFIG_NIMBLE_DEBUG is not set CONFIG_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" CONFIG_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 @@ -2746,7 +2347,6 @@ CONFIG_NIMBLE_HS_FLOW_CTRL_ITVL=1000 CONFIG_NIMBLE_HS_FLOW_CTRL_THRESH=2 CONFIG_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y CONFIG_NIMBLE_RPA_TIMEOUT=900 -# default: # CONFIG_NIMBLE_MESH is not set CONFIG_NIMBLE_CRYPTO_STACK_MBEDTLS=y CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y @@ -2766,7 +2366,6 @@ CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y # CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR is not set CONFIG_SCAN_DUPLICATE_TYPE=0 CONFIG_DUPLICATE_SCAN_CACHE_SIZE=100 -# default: # CONFIG_BLE_MESH_SCAN_DUPLICATE_EN is not set CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED=y @@ -2776,20 +2375,16 @@ CONFIG_ADC2_DISABLE_DAC=y CONFIG_SW_COEXIST_ENABLE=y CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y -# default: # CONFIG_MCPWM_ISR_IN_IRAM is not set -# default: # CONFIG_EVENT_LOOP_PROFILING is not set CONFIG_POST_EVENTS_FROM_ISR=y CONFIG_POST_EVENTS_FROM_IRAM_ISR=y CONFIG_GDBSTUB_SUPPORT_TASKS=y CONFIG_GDBSTUB_MAX_TASKS=32 -# default: # CONFIG_OTA_ALLOW_HTTP is not set # CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 -# default: # CONFIG_ESP_SYSTEM_PD_FLASH is not set CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 @@ -2807,17 +2402,12 @@ CONFIG_ESP32_XTAL_FREQ_40=y # CONFIG_ESP32_XTAL_FREQ_AUTO is not set CONFIG_ESP32_XTAL_FREQ=40 CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y -# default: # CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP32_PHY_MAX_TX_POWER=20 -# default: # CONFIG_REDUCE_PHY_TX_POWER is not set -# default: # CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set -# default: # CONFIG_SPIRAM_SUPPORT is not set -# default: # CONFIG_ESP32_SPIRAM_SUPPORT is not set # CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y @@ -2843,12 +2433,10 @@ CONFIG_INT_WDT_TIMEOUT_MS=300 CONFIG_INT_WDT_CHECK_CPU1=y CONFIG_TASK_WDT=y CONFIG_ESP_TASK_WDT=y -# default: # CONFIG_TASK_WDT_PANIC is not set CONFIG_TASK_WDT_TIMEOUT_S=5 CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# default: # CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set CONFIG_ESP32_DEBUG_OCDAWARE=y CONFIG_BROWNOUT_DET=y @@ -2871,7 +2459,6 @@ CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set CONFIG_BROWNOUT_DET_LVL=0 CONFIG_ESP32_BROWNOUT_DET_LVL=0 -# default: # CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set CONFIG_IPC_TASK_STACK_SIZE=1024 CONFIG_TIMER_TASK_STACK_SIZE=3584 @@ -2882,7 +2469,6 @@ CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 -# default: # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP32_WIFI_TX_BA_WIN=6 @@ -2893,31 +2479,20 @@ CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 -# default: # CONFIG_ESP32_WIFI_IRAM_OPT is not set -# default: # CONFIG_ESP32_WIFI_RX_IRAM_OPT is not set CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y CONFIG_WPA_MBEDTLS_CRYPTO=y CONFIG_WPA_MBEDTLS_TLS_CLIENT=y -# default: # CONFIG_WPA_WAPI_PSK is not set -# default: # CONFIG_WPA_11KV_SUPPORT is not set -# default: # CONFIG_WPA_MBO_SUPPORT is not set -# default: # CONFIG_WPA_DPP_SUPPORT is not set -# default: # CONFIG_WPA_11R_SUPPORT is not set -# default: # CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set -# default: # CONFIG_WPA_WPS_STRICT is not set -# default: # CONFIG_WPA_DEBUG_PRINT is not set -# default: # CONFIG_WPA_TESTING_OPTIONS is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set @@ -2925,10 +2500,8 @@ CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y CONFIG_TIMER_TASK_PRIORITY=1 CONFIG_TIMER_TASK_STACK_DEPTH=2048 CONFIG_TIMER_QUEUE_LENGTH=10 -# default: # CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set # CONFIG_HAL_ASSERTION_SILIENT is not set -# default: # CONFIG_L2_TO_L3_COPY is not set CONFIG_ESP_GRATUITOUS_ARP=y CONFIG_GARP_TMR_INTERVAL=60 @@ -2950,7 +2523,6 @@ CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set # CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF -# default: # CONFIG_PPP_SUPPORT is not set CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y @@ -2969,7 +2541,6 @@ CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set -# default: # CONFIG_ESP32_ULP_COPROC_ENABLED is not set CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y diff --git a/src/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp index a2928695..10f9c9aa 100644 --- a/src/PowerTable_Helpers.cpp +++ b/src/PowerTable_Helpers.cpp @@ -859,7 +859,9 @@ bool CubicSpline::shouldUseNaturalSpline(std::pair, std::vect // --- Helper Functions --- // Check if a cell is considered "filled" with valid data -bool isFilled(const TableEntry& entry) { return entry.targetPosition != INT16_MIN; } +bool isFilled(const TableEntry& entry, int readings = 0) { + return entry.targetPosition != INT16_MIN && entry.readings >= readings; +} // Linearly interpolate or extrapolate a value. // Interpolates if x is between x0 and x1. @@ -913,20 +915,20 @@ bool PTHelpers::completePowerTable(PTData& data) { // --- PASS 1: Interpolation and Extrapolation --- for (int r = 0; r < POWERTABLE_CAD_SIZE; ++r) { for (int c = 0; c < POWERTABLE_WATT_SIZE; ++c) { - if (isFilled(data.tableRow[r].tableEntry[c]) && data.tableRow[r].tableEntry[c].readings > 0) { + if (isFilled(data.tableRow[r].tableEntry[c], 1)) { continue; } // Find horizontal anchors (left and right) for interpolation int left_c = -1, right_c = -1; for (int i = c - 1; i >= 0; --i) { - if (isFilled(data.tableRow[r].tableEntry[i])) { + if (isFilled(data.tableRow[r].tableEntry[i], 1)) { left_c = i; break; } } for (int i = c + 1; i < POWERTABLE_WATT_SIZE; ++i) { - if (isFilled(data.tableRow[r].tableEntry[i])) { + if (isFilled(data.tableRow[r].tableEntry[i], 1)) { right_c = i; break; } @@ -935,13 +937,13 @@ bool PTHelpers::completePowerTable(PTData& data) { // Find vertical anchors (bottom and top) for interpolation int bottom_r = -1, top_r = -1; for (int i = r - 1; i >= 0; --i) { - if (isFilled(data.tableRow[i].tableEntry[c])) { + if (isFilled(data.tableRow[i].tableEntry[c], 1)) { bottom_r = i; break; } } for (int i = r + 1; i < POWERTABLE_CAD_SIZE; ++i) { - if (isFilled(data.tableRow[i].tableEntry[c])) { + if (isFilled(data.tableRow[i].tableEntry[c], 1)) { top_r = i; break; } @@ -957,7 +959,7 @@ bool PTHelpers::completePowerTable(PTData& data) { } else if (left_c != -1) { int l2 = -1; for (int i = left_c - 1; i >= 0; --i) - if (isFilled(data.tableRow[r].tableEntry[i])) { + if (isFilled(data.tableRow[r].tableEntry[i], 1)) { l2 = i; break; } @@ -969,7 +971,7 @@ bool PTHelpers::completePowerTable(PTData& data) { } else if (right_c != -1) { int r2 = -1; for (int i = right_c + 1; i < POWERTABLE_WATT_SIZE; ++i) - if (isFilled(data.tableRow[r].tableEntry[i])) { + if (isFilled(data.tableRow[r].tableEntry[i], 1)) { r2 = i; break; } @@ -987,7 +989,7 @@ bool PTHelpers::completePowerTable(PTData& data) { } else if (bottom_r != -1) { int b2 = -1; for (int i = bottom_r - 1; i >= 0; --i) - if (isFilled(data.tableRow[i].tableEntry[c])) { + if (isFilled(data.tableRow[i].tableEntry[c], 1)) { b2 = i; break; } @@ -999,7 +1001,7 @@ bool PTHelpers::completePowerTable(PTData& data) { } else if (top_r != -1) { int t2 = -1; for (int i = top_r + 1; i < POWERTABLE_CAD_SIZE; ++i) - if (isFilled(data.tableRow[i].tableEntry[c])) { + if (isFilled(data.tableRow[i].tableEntry[c], 1)) { t2 = i; break; } @@ -1034,7 +1036,6 @@ bool PTHelpers::completePowerTable(PTData& data) { for (int r = 0; r < POWERTABLE_CAD_SIZE; ++r) { for (int c = 0; c < POWERTABLE_WATT_SIZE; ++c) { if (!isFilled(data.tableRow[r].tableEntry[c])) continue; - // --- MODIFIED RULE --- // Enforce Rule: Neighbor above (row r-1) must be higher. // This means the value at [r] must be LESS than the value at [r-1]. diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 2d441992..05070bde 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -196,7 +196,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { return; } - // targetPosition = this->calculatePosition(watts, cad, targetPosition, index); + // targetPosition = this->calculatePosition(watts, cad, targetPosition, index); // // Downvote out of position neighbors and discard entry if it doesn't match the logic of the table // TestResults testResults = ptHelpers.testNeighbors(index, targetPosition, ptData); @@ -226,7 +226,20 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { void fillAllCadenceLines(ptIndex index, PTData& ptData) { for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { if (ptData.tableRow[i].tableEntry[index.wattIndex].readings == 0) { - ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition + (i - index.cadIndex) * (index.wattIndex + 10); + ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = + ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (i - index.cadIndex) * (index.wattIndex + 10); + // add a reading + ptData.tableRow[i].tableEntry[index.wattIndex].readings ++;; // add a reading + } + // Positions with a higher row should have lower targetPosition, so enforce monotonicity + if (i < index.cadIndex) { + ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = + std::max(ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition, + (int16_t)(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (index.cadIndex - i) * (index.wattIndex + 10))); + } else if (i > index.cadIndex) { + ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = + std::min(ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition, + (int16_t)(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (i - index.cadIndex) * (index.wattIndex + 10))); } } } @@ -246,6 +259,7 @@ void PowerTable::enterData(ptIndex index, int pos) { this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition = pos; SS2K_LOG(POWERTABLE_LOG_TAG, "New entry recorded (%d)(%d)(%d)", index.cadIndex, index.wattIndex, this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition); + this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings++; // for initial spot on readings, give 2 (one below as well) } else { // Average and update the readings. this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition = (pos + (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition * this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings)) / @@ -261,6 +275,7 @@ void PowerTable::enterData(ptIndex index, int pos) { } void PowerTable::fillTable() { + return ; // testing static int entries = 0; static int newEntries = 0; static int8_t step = 0; @@ -276,23 +291,24 @@ void PowerTable::fillTable() { return; } - if (ptHelpers.getNumEntries(ptData) > 4) { + if (ptHelpers.getNumEntries(ptData, 1) > 4) { // set flag to stop execution after we can't add any more entries. if (esp_get_free_heap_size() < FREE_HEAP_FOR_COMPLEX_MATH) { // SS2K_LOG(POWERTABLE_LOG_TAG, "%d Heap too low for step %d.", esp_get_free_heap_size(), step); return; } + // clean(); // clean the table before filling it. entries = ptHelpers.getNumEntries(ptData); if (step == 0) { SS2K_LOG(POWERTABLE_LOG_TAG, "Fill start with %d entries", entries); prevEntries = entries; - completed = ptHelpers.completePowerTable(ptData); + ptHelpers.completePowerTable(ptData); + completed = true; } else if (step == 1) { // completed = ptHelpers.splineFill(ptData, false); } else if (step == 2) { // completed = ptHelpers.linearFill(ptData); } else if (step == 3) { - } newEntries = ptHelpers.getNumEntries(ptData); SS2K_LOG(POWERTABLE_LOG_TAG, "Fill step %d added %d new entries", step, newEntries - prevEntries); From b85ad4b5035561769989fb4ad772560f30f9ff8c Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sat, 5 Jul 2025 09:26:51 -0500 Subject: [PATCH 275/451] attempting to fill all columns and rows. --- src/Power_Table.cpp | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 05070bde..be736eec 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -225,11 +225,13 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { void fillAllCadenceLines(ptIndex index, PTData& ptData) { for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { + // Create positions for all cadence lines if they are not set. + // This gives us a monotonic table with a linear progression of target positions. if (ptData.tableRow[i].tableEntry[index.wattIndex].readings == 0) { ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (i - index.cadIndex) * (index.wattIndex + 10); // add a reading - ptData.tableRow[i].tableEntry[index.wattIndex].readings ++;; // add a reading + ptData.tableRow[i].tableEntry[index.wattIndex].readings ++; // add a reading } // Positions with a higher row should have lower targetPosition, so enforce monotonicity if (i < index.cadIndex) { @@ -239,10 +241,33 @@ void fillAllCadenceLines(ptIndex index, PTData& ptData) { } else if (i > index.cadIndex) { ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = std::min(ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition, - (int16_t)(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (i - index.cadIndex) * (index.wattIndex + 10))); + (int16_t)(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (index.cadIndex - i) * (index.wattIndex + 10))); } } } + +void fillAllWattColumns(ptIndex index, PTData& ptData) { + for (int i = 0; i < POWERTABLE_WATT_SIZE; i++) { + // Create positions for all watt columns if they are not set. + // This gives us a monotonic table with a linear progression of target positions. + if (ptData.tableRow[index.cadIndex].tableEntry[i].readings == 0) { + ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition = + ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (index.wattIndex - i) * (index.cadIndex + 10); + ptData.tableRow[index.cadIndex].tableEntry[i].readings ++; // add a reading + } + // Each column to the right should have a higher targetPosition, so enforce monotonicity + if (i > index.wattIndex) { + ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition = + std::max(ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition, + (int16_t)(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (index.wattIndex - i) * (index.cadIndex + 10))); + } else if (i < index.wattIndex) { + ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition = + std::min(ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition, + (int16_t)(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (index.wattIndex - i) * (index.cadIndex + 10))); + } + } +} + /** * @brief Updates or enters data into the power table for a specific row and entry. * @@ -271,7 +296,9 @@ void PowerTable::enterData(ptIndex index, int pos) { } } this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings++; + // because of monotonicity, we can make some assumptions in order to fill the table. fillAllCadenceLines(index, this->ptData); + fillAllWattColumns(index, this->ptData); } void PowerTable::fillTable() { From 258017fedb6f8adff492154bd6a3b7bcb6f6aa27 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sat, 5 Jul 2025 09:31:36 -0500 Subject: [PATCH 276/451] Added second cadence pass --- src/Power_Table.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index be736eec..bc545750 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -265,6 +265,8 @@ void fillAllWattColumns(ptIndex index, PTData& ptData) { std::min(ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition, (int16_t)(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (index.wattIndex - i) * (index.cadIndex + 10))); } + ptIndex newIndex = {index.cadIndex, i}; + fillAllCadenceLines(newIndex, ptData); } } From f136b0e5b0e8628282f127a25e66491ec2b0ccee Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sat, 5 Jul 2025 10:24:59 -0500 Subject: [PATCH 277/451] only add readings on first order guesses --- src/Power_Table.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index bc545750..d3e6d324 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -223,7 +223,7 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { BLE_ss2kCustomCharacteristic::notify(0x27, index.cadIndex); } -void fillAllCadenceLines(ptIndex index, PTData& ptData) { +void fillAllCadenceLines(ptIndex index, PTData& ptData, bool addReading = false) { for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { // Create positions for all cadence lines if they are not set. // This gives us a monotonic table with a linear progression of target positions. @@ -231,17 +231,19 @@ void fillAllCadenceLines(ptIndex index, PTData& ptData) { ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (i - index.cadIndex) * (index.wattIndex + 10); // add a reading - ptData.tableRow[i].tableEntry[index.wattIndex].readings ++; // add a reading + if (addReading) { + ptData.tableRow[i].tableEntry[index.wattIndex].readings++; + } } // Positions with a higher row should have lower targetPosition, so enforce monotonicity if (i < index.cadIndex) { ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = std::max(ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition, - (int16_t)(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (index.cadIndex - i) * (index.wattIndex + 10))); + (int16_t)(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (i - index.cadIndex) * (index.wattIndex + 10))); } else if (i > index.cadIndex) { ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = std::min(ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition, - (int16_t)(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (index.cadIndex - i) * (index.wattIndex + 10))); + (int16_t)(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (i - index.cadIndex) * (index.wattIndex + 10))); } } } @@ -265,8 +267,10 @@ void fillAllWattColumns(ptIndex index, PTData& ptData) { std::min(ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition, (int16_t)(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (index.wattIndex - i) * (index.cadIndex + 10))); } - ptIndex newIndex = {index.cadIndex, i}; - fillAllCadenceLines(newIndex, ptData); + ptIndex newIndex; + newIndex.cadIndex = index.cadIndex; + newIndex.wattIndex = i; + fillAllCadenceLines(newIndex, ptData, false); } } @@ -299,7 +303,7 @@ void PowerTable::enterData(ptIndex index, int pos) { } this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings++; // because of monotonicity, we can make some assumptions in order to fill the table. - fillAllCadenceLines(index, this->ptData); + fillAllCadenceLines(index, this->ptData, true); fillAllWattColumns(index, this->ptData); } From 3c76d85c231366d2c78f3eb3853052fc0357e78c Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 9 Jul 2025 23:36:14 -0500 Subject: [PATCH 278/451] bugfix --- dependencies.lock | 13 +- sdkconfig.release | 438 +++++++++++++++++++++++++++++++++++++++++- sdkconfig.release.old | 399 +++++++++++++++++++++++++++++++++++++- src/Power_Table.cpp | 45 ++--- 4 files changed, 861 insertions(+), 34 deletions(-) diff --git a/dependencies.lock b/dependencies.lock index 3aef0ca5..17170be1 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -41,6 +41,16 @@ dependencies: registry_url: https://components.espressif.com/ type: service version: 1.6.3 + espressif/esp_modem: + component_hash: b541c3f5765d3ba062c0d004b9ca6da6d0af908293421c2dbe046c537fb2a011 + dependencies: + - name: idf + require: private + version: '>=4.1' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.4.0 espressif/mdns: component_hash: 3ec0af5f6bce310512e90f482388d21cc7c0e99668172d2f895356165fc6f7c5 dependencies: @@ -81,10 +91,11 @@ direct_dependencies: - espressif/cbor - espressif/esp-zboss-lib - espressif/esp-zigbee-lib +- espressif/esp_modem - espressif/mdns - espressif/network_provisioning - idf - joltwallet/littlefs -manifest_hash: cdea08c215af25ecb07f34a572afe529ccee1d11a022752ebfb3b54cbc0cb5f8 +manifest_hash: e871ea1e1aff9421b8e57e1c5a4db8daeef71b071a2a17f239e5feebc4acdfc3 target: esp32 version: 2.0.0 diff --git a/sdkconfig.release b/sdkconfig.release index 7b3b88bf..8059f8a4 100644 --- a/sdkconfig.release +++ b/sdkconfig.release @@ -259,9 +259,13 @@ CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y CONFIG_APP_BUILD_GENERATE_BINARIES=y CONFIG_APP_BUILD_BOOTLOADER=y CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# default: # CONFIG_APP_REPRODUCIBLE_BUILD is not set +# default: # CONFIG_APP_NO_BLOBS is not set +# default: # CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# default: # CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set # end of Build type @@ -296,6 +300,7 @@ CONFIG_BOOTLOADER_LOG_LEVEL=3 # # Format # +# default: # CONFIG_BOOTLOADER_LOG_COLORS is not set CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y # end of Format @@ -304,23 +309,32 @@ CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y # # Serial Flash Configurations # +# default: # CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y # end of Serial Flash Configurations # CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# default: # CONFIG_BOOTLOADER_FACTORY_RESET is not set +# default: # CONFIG_BOOTLOADER_APP_TEST is not set CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y CONFIG_BOOTLOADER_WDT_ENABLE=y +# default: # CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# default: # CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# default: # CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set # end of Bootloader config @@ -328,8 +342,11 @@ CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 # Security features # CONFIG_SECURE_BOOT_V1_SUPPORTED=y +# default: # CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# default: # CONFIG_SECURE_BOOT is not set +# default: # CONFIG_SECURE_FLASH_ENC_ENABLED is not set # end of Security features @@ -337,8 +354,11 @@ CONFIG_SECURE_BOOT_V1_SUPPORTED=y # Application manager # CONFIG_APP_COMPILE_TIME_DATE=y +# default: # CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# default: # CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# default: # CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 # end of Application manager @@ -361,6 +381,7 @@ CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y # # Serial flasher config # +# default: # CONFIG_ESPTOOLPY_NO_STUB is not set # CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set @@ -382,6 +403,7 @@ CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set CONFIG_ESPTOOLPY_FLASHSIZE="2MB" +# default: # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set @@ -411,6 +433,7 @@ CONFIG_PARTITION_TABLE_MD5=y # CONFIG_ARDUINO_VARIANT="esp32" CONFIG_ENABLE_ARDUINO_DEPENDS=y +# default: # CONFIG_AUTOSTART_ARDUINO is not set # CONFIG_ARDUINO_RUN_CORE0 is not set CONFIG_ARDUINO_RUN_CORE1=y @@ -432,7 +455,9 @@ CONFIG_ARDUINO_UDP_RUN_CORE0=y # CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set CONFIG_ARDUINO_UDP_RUNNING_CORE=0 CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 +# default: # CONFIG_ARDUINO_ISR_IRAM is not set +# default: # CONFIG_DISABLE_HAL_LOCKS is not set # @@ -445,7 +470,9 @@ CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE=y # CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set # CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=0 +# default: # CONFIG_ARDUHAL_LOG_COLORS is not set +# default: # CONFIG_ARDUHAL_ESP_LOG is not set # end of Debug Log Configuration @@ -458,19 +485,28 @@ CONFIG_ARDUHAL_PARTITION_SCHEME="min_spiffs" CONFIG_ARDUINO_SELECTIVE_COMPILATION=y CONFIG_ARDUINO_SELECTIVE_SPI=y CONFIG_ARDUINO_SELECTIVE_Wire=y -CONFIG_ARDUINO_SELECTIVE_ESP_SR=y +# default: +# CONFIG_ARDUINO_SELECTIVE_ESP_SR is not set CONFIG_ARDUINO_SELECTIVE_EEPROM=y +# default: # CONFIG_ARDUINO_SELECTIVE_Preferences is not set +# default: # CONFIG_ARDUINO_SELECTIVE_Ticker is not set CONFIG_ARDUINO_SELECTIVE_Update=y +# default: # CONFIG_ARDUINO_SELECTIVE_Zigbee is not set CONFIG_ARDUINO_SELECTIVE_FS=y +# default: # CONFIG_ARDUINO_SELECTIVE_SD is not set +# default: # CONFIG_ARDUINO_SELECTIVE_SD_MMC is not set +# default: # CONFIG_ARDUINO_SELECTIVE_SPIFFS is not set +# default: # CONFIG_ARDUINO_SELECTIVE_FFat is not set CONFIG_ARDUINO_SELECTIVE_LittleFS=y CONFIG_ARDUINO_SELECTIVE_Network=y +# default: # CONFIG_ARDUINO_SELECTIVE_Ethernet is not set CONFIG_ARDUINO_SELECTIVE_PPP=y CONFIG_ARDUINO_SELECTIVE_ArduinoOTA=y @@ -478,17 +514,25 @@ CONFIG_ARDUINO_SELECTIVE_AsyncUDP=y CONFIG_ARDUINO_SELECTIVE_DNSServer=y CONFIG_ARDUINO_SELECTIVE_ESPmDNS=y CONFIG_ARDUINO_SELECTIVE_HTTPClient=y +# default: # CONFIG_ARDUINO_SELECTIVE_Matter is not set +# default: # CONFIG_ARDUINO_SELECTIVE_NetBIOS is not set CONFIG_ARDUINO_SELECTIVE_WebServer=y CONFIG_ARDUINO_SELECTIVE_WiFi=y CONFIG_ARDUINO_SELECTIVE_NetworkClientSecure=y -CONFIG_ARDUINO_SELECTIVE_WiFiProv=y +# default: +# CONFIG_ARDUINO_SELECTIVE_WiFiProv is not set CONFIG_ARDUINO_SELECTIVE_BLE=y +# default: # CONFIG_ARDUINO_SELECTIVE_BluetoothSerial is not set -CONFIG_ARDUINO_SELECTIVE_SimpleBLE=y +# default: +# CONFIG_ARDUINO_SELECTIVE_SimpleBLE is not set +# default: # CONFIG_ARDUINO_SELECTIVE_RainMaker is not set +# default: # CONFIG_ARDUINO_SELECTIVE_OpenThread is not set +# default: # CONFIG_ARDUINO_SELECTIVE_Insights is not set # end of Arduino Configuration @@ -505,25 +549,35 @@ CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# default: # CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# default: # CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# default: # CONFIG_COMPILER_CXX_RTTI is not set CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set # CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set # CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# default: # CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set +# default: # CONFIG_COMPILER_WARN_WRITE_STRINGS is not set CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y +# default: # CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# default: # CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# default: # CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set +# default: # CONFIG_COMPILER_DUMP_RTL_FILES is not set CONFIG_COMPILER_RT_LIB_GCCLIB=y CONFIG_COMPILER_RT_LIB_NAME="gcc" CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y # CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set +# default: # CONFIG_COMPILER_STATIC_ANALYZER is not set # end of Compiler options @@ -576,10 +630,15 @@ CONFIG_BT_NIMBLE_ROLE_CENTRAL=y CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y CONFIG_BT_NIMBLE_ROLE_OBSERVER=y +# default: # CONFIG_BT_NIMBLE_NVS_PERSIST is not set +# default: # CONFIG_BT_NIMBLE_SMP_ID_RESET is not set +# default: # CONFIG_BT_NIMBLE_SECURITY_ENABLE is not set +# default: # CONFIG_BT_NIMBLE_DEBUG is not set +# default: # CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 @@ -607,16 +666,22 @@ CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 +# default: # CONFIG_BT_NIMBLE_MESH is not set CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 +# default: # CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set +# default: # CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set CONFIG_BT_NIMBLE_WHITELIST_SIZE=1 +# default: # CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set +# default: # CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set CONFIG_BT_NIMBLE_USE_ESP_TIMER=y CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y +# default: # CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set # @@ -626,6 +691,7 @@ CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y # # GAP Appearance write permissions # +# default: # CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set # end of GAP Appearance write permissions @@ -641,6 +707,7 @@ CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 # # GAP device name write permissions # +# default: # CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set # end of GAP device name write permissions @@ -652,33 +719,49 @@ CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 +# default: # CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL is not set # end of GAP Service # # BLE Services # +# default: # CONFIG_BT_NIMBLE_HID_SERVICE is not set +# default: # CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY is not set # # Device Information Service # +# default: # CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED is not set # end of Device Information Service # end of BLE Services +# default: # CONFIG_BT_NIMBLE_VS_SUPPORT is not set +# default: # CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set +# default: # CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set +# default: # CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set +# default: # CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT is not set # @@ -692,6 +775,7 @@ CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 # end of Host-controller Transport CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 +# default: # CONFIG_BT_NIMBLE_SUBRATE is not set # end of NimBLE Options @@ -734,9 +818,12 @@ CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y CONFIG_BTDM_SCAN_DUPL_TYPE=0 CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 +# default: # CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y +# default: # CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set +# default: # CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 @@ -745,12 +832,15 @@ CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # # BLE disconnects when Instant Passed (0x28) occurs # +# default: # CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set +# default: # CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set # end of BLE disconnects when Instant Passed (0x28) occurs CONFIG_BTDM_BLE_CHAN_ASS_EN=y CONFIG_BTDM_BLE_PING_EN=y +# default: # CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 is not set CONFIG_BTDM_RESERVE_DRAM=0xdb5c CONFIG_BTDM_CTRL_HLI=y @@ -760,17 +850,21 @@ CONFIG_BTDM_CTRL_HLI=y # Common Options # CONFIG_BT_ALARM_MAX_NUM=50 +# default: # CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set # end of Common Options +# default: # CONFIG_BT_HCI_LOG_DEBUG_EN is not set # end of Bluetooth +# default: # CONFIG_BLE_MESH is not set # # Console Library # +# default: # CONFIG_CONSOLE_SORTED_HELP is not set # end of Console Library @@ -781,6 +875,7 @@ CONFIG_BT_ALARM_MAX_NUM=50 # # TWAI Configuration # +# default: # CONFIG_TWAI_ISR_IN_IRAM is not set CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y @@ -793,7 +888,9 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # Legacy ADC Driver Configuration # CONFIG_ADC_DISABLE_DAC=y +# default: # CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set # @@ -802,6 +899,7 @@ CONFIG_ADC_DISABLE_DAC=y CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y CONFIG_ADC_CAL_LUT_ENABLE=y +# default: # CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set # end of Legacy ADC Calibration Configuration # end of Legacy ADC Driver Configuration @@ -809,49 +907,63 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # # Legacy DAC Driver Configurations # +# default: # CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy DAC Driver Configurations # # Legacy MCPWM Driver Configurations # +# default: # CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy MCPWM Driver Configurations # # Legacy Timer Group Driver Configurations # +# default: # CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Timer Group Driver Configurations # # Legacy RMT Driver Configurations # +# default: # CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy RMT Driver Configurations # # Legacy I2S Driver Configurations # +# default: # CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy I2S Driver Configurations # # Legacy PCNT Driver Configurations # +# default: # CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy PCNT Driver Configurations # # Legacy SDM Driver Configurations # +# default: # CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy SDM Driver Configurations # end of Driver Configurations @@ -859,7 +971,9 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # # eFuse Bit Manager # +# default: # CONFIG_EFUSE_CUSTOM_TABLE is not set +# default: # CONFIG_EFUSE_VIRTUAL is not set # CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y @@ -871,19 +985,28 @@ CONFIG_EFUSE_MAX_BLK_LEN=192 # ESP-TLS # CONFIG_ESP_TLS_USING_MBEDTLS=y +# default: # CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set +# default: # CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# default: # CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set +# default: # CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set +# default: # CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set +# default: # CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# default: # CONFIG_ESP_TLS_INSECURE is not set # end of ESP-TLS # # ADC and ADC Calibration # +# default: # CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set # @@ -895,6 +1018,7 @@ CONFIG_ADC_CALI_LUT_ENABLE=y # end of ADC Calibration Configurations CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# default: # CONFIG_ADC_ENABLE_DEBUG_LOG is not set # end of ADC and ADC Calibration @@ -903,7 +1027,9 @@ CONFIG_ADC_DISABLE_DAC_OUTPUT=y # CONFIG_ESP_COEX_ENABLED=y CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y +# default: # CONFIG_ESP_COEX_POWER_MANAGEMENT is not set +# default: # CONFIG_ESP_COEX_GPIO_DEBUG is not set # end of Wireless Coexistence @@ -916,8 +1042,11 @@ CONFIG_ESP_ERR_TO_NAME_LOOKUP=y # # ESP-Driver:DAC Configurations # +# default: # CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_DAC_ISR_IRAM_SAFE is not set +# default: # CONFIG_DAC_ENABLE_DEBUG_LOG is not set CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # end of ESP-Driver:DAC Configurations @@ -925,7 +1054,9 @@ CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # # ESP-Driver:GPIO Configurations # +# default: # CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set +# default: # CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:GPIO Configurations @@ -933,68 +1064,90 @@ CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # ESP-Driver:GPTimer Configurations # CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y +# default: # CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# default: # CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:GPTimer Configurations # # ESP-Driver:I2C Configurations # +# default: # CONFIG_I2C_ISR_IRAM_SAFE is not set +# default: # CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# default: # CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set # end of ESP-Driver:I2C Configurations # # ESP-Driver:I2S Configurations # +# default: # CONFIG_I2S_ISR_IRAM_SAFE is not set +# default: # CONFIG_I2S_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:I2S Configurations # # ESP-Driver:LEDC Configurations # +# default: # CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:LEDC Configurations # # ESP-Driver:MCPWM Configurations # +# default: # CONFIG_MCPWM_ISR_IRAM_SAFE is not set +# default: # CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:MCPWM Configurations # # ESP-Driver:PCNT Configurations # +# default: # CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_PCNT_ISR_IRAM_SAFE is not set +# default: # CONFIG_PCNT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:PCNT Configurations # # ESP-Driver:RMT Configurations # +# default: # CONFIG_RMT_ISR_IRAM_SAFE is not set +# default: # CONFIG_RMT_RECV_FUNC_IN_IRAM is not set +# default: # CONFIG_RMT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:RMT Configurations # # ESP-Driver:Sigma Delta Modulator Configurations # +# default: # CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_SDM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Sigma Delta Modulator Configurations # # ESP-Driver:SPI Configurations # +# default: # CONFIG_SPI_MASTER_IN_IRAM is not set CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# default: # CONFIG_SPI_SLAVE_IN_IRAM is not set CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # end of ESP-Driver:SPI Configurations @@ -1002,28 +1155,36 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # # ESP-Driver:Touch Sensor Configurations # +# default: # CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_TOUCH_ISR_IRAM_SAFE is not set +# default: # CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Touch Sensor Configurations # # ESP-Driver:UART Configurations # +# default: # CONFIG_UART_ISR_IN_IRAM is not set # end of ESP-Driver:UART Configurations # # Ethernet # +# default: # CONFIG_ETH_USE_ESP32_EMAC is not set +# default: # CONFIG_ETH_USE_SPI_ETHERNET is not set +# default: # CONFIG_ETH_USE_OPENETH is not set # end of Ethernet # # Event Loop Library # +# default: # CONFIG_ESP_EVENT_LOOP_PROFILING is not set CONFIG_ESP_EVENT_POST_FROM_ISR=y CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y @@ -1033,6 +1194,7 @@ CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y # GDB Stub # CONFIG_ESP_GDBSTUB_ENABLED=y +# default: # CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y CONFIG_ESP_GDBSTUB_MAX_TASKS=32 @@ -1049,8 +1211,11 @@ CONFIG_ESPHID_TASK_SIZE_BLE=4096 # ESP HTTP client # CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 # end of ESP HTTP client @@ -1062,8 +1227,11 @@ CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 CONFIG_HTTPD_MAX_URI_LEN=512 CONFIG_HTTPD_ERR_RESP_NO_DELAY=y CONFIG_HTTPD_PURGE_BUF_LEN=32 +# default: # CONFIG_HTTPD_LOG_PURGE_DATA is not set +# default: # CONFIG_HTTPD_WS_SUPPORT is not set +# default: # CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # end of HTTP Server @@ -1071,7 +1239,9 @@ CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # # ESP HTTPS OTA # +# default: # CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# default: # CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS OTA @@ -1079,6 +1249,7 @@ CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # # ESP HTTPS server # +# default: # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS server @@ -1125,20 +1296,27 @@ CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 # CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 +# default: # CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set +# default: # CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set # end of MAC Config # # Sleep Config # +# default: # CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +# default: # CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# default: # CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 +# default: # CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set +# default: # CONFIG_ESP_SLEEP_DEBUG is not set CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y # end of Sleep Config @@ -1175,6 +1353,7 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # # ESP-Driver:LCD Controller Configurations # +# default: # CONFIG_LCD_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:LCD Controller Configurations @@ -1187,14 +1366,19 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # ESP NETIF Adapter # CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +# default: # CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set CONFIG_ESP_NETIF_TCPIP_LWIP=y # CONFIG_ESP_NETIF_LOOPBACK is not set CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y +# default: # CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# default: # CONFIG_ESP_NETIF_L2_TAP is not set +# default: # CONFIG_ESP_NETIF_BRIDGE_EN is not set +# default: # CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set # end of ESP NETIF Adapter @@ -1208,35 +1392,44 @@ CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y # CONFIG_ESP_PHY_ENABLED=y CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# default: # CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP_PHY_MAX_TX_POWER=20 +# default: # CONFIG_ESP_PHY_REDUCE_TX_POWER is not set +# default: # CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set CONFIG_ESP_PHY_RF_CAL_PARTIAL=y # CONFIG_ESP_PHY_RF_CAL_NONE is not set # CONFIG_ESP_PHY_RF_CAL_FULL is not set CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# default: # CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# default: # CONFIG_ESP_PHY_RECORD_USED_TIME is not set # end of PHY # # Power Management # +# default: # CONFIG_PM_ENABLE is not set +# default: # CONFIG_PM_SLP_IRAM_OPT is not set # end of Power Management # # ESP PSRAM # +# default: # CONFIG_SPIRAM is not set # end of ESP PSRAM # # ESP Ringbuf # +# default: # CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set # end of ESP Ringbuf @@ -1256,11 +1449,13 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 # # Memory # +# default: # CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set # # Non-backward compatible options # +# default: # CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set # end of Non-backward compatible options # end of Memory @@ -1268,6 +1463,7 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 # # Trace memory # +# default: # CONFIG_ESP32_TRAX is not set CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 # end of Trace memory @@ -1303,11 +1499,14 @@ CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 CONFIG_ESP_INT_WDT_CHECK_CPU1=y CONFIG_ESP_TASK_WDT_EN=y CONFIG_ESP_TASK_WDT_INIT=y +# default: # CONFIG_ESP_TASK_WDT_PANIC is not set CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# default: # CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# default: # CONFIG_ESP_DEBUG_STUBS_ENABLE is not set CONFIG_ESP_DEBUG_OCDAWARE=y CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y @@ -1327,6 +1526,7 @@ CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y CONFIG_ESP_BROWNOUT_DET_LVL=0 # end of Brownout Detector +# default: # CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y # end of ESP System Settings @@ -1342,15 +1542,18 @@ CONFIG_ESP_IPC_ISR_ENABLE=y # # ESP Timer (High Resolution Timer) # +# default: # CONFIG_ESP_TIMER_PROFILING is not set CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# default: # CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# default: # CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set CONFIG_ESP_TIMER_IMPL_TG0_LAC=y # end of ESP Timer (High Resolution Timer) @@ -1369,6 +1572,7 @@ CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y # CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 +# default: # CONFIG_ESP_WIFI_CSI_ENABLED is not set CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP_WIFI_TX_BA_WIN=6 @@ -1379,13 +1583,17 @@ CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +# default: # CONFIG_ESP_WIFI_IRAM_OPT is not set +# default: # CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set +# default: # CONFIG_ESP_WIFI_RX_IRAM_OPT is not set CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y CONFIG_ESP_WIFI_ENABLE_SAE_PK=y CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# default: # CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 @@ -1393,28 +1601,41 @@ CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y CONFIG_ESP_WIFI_GMAC_SUPPORT=y CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# default: # CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# default: # CONFIG_ESP_WIFI_NAN_ENABLE is not set CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# default: # CONFIG_ESP_WIFI_WAPI_PSK is not set +# default: # CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_11R_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set # # WPS Configuration Options # +# default: # CONFIG_ESP_WIFI_WPS_STRICT is not set +# default: # CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set # end of WPS Configuration Options +# default: # CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# default: # CONFIG_ESP_WIFI_TESTING_OPTIONS is not set CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y +# default: # CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set # end of Wi-Fi @@ -1461,12 +1682,15 @@ CONFIG_FATFS_CODEPAGE=437 CONFIG_FATFS_FS_LOCK=0 CONFIG_FATFS_TIMEOUT_MS=10000 CONFIG_FATFS_PER_FILE_CACHE=y +# default: # CONFIG_FATFS_USE_FASTSEEK is not set CONFIG_FATFS_USE_STRFUNC_NONE=y # CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set # CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# default: # CONFIG_FATFS_IMMEDIATE_FSYNC is not set +# default: # CONFIG_FATFS_USE_LABEL is not set CONFIG_FATFS_LINK_LOCK=y # end of FAT Filesystem support @@ -1478,7 +1702,9 @@ CONFIG_FATFS_LINK_LOCK=y # # Kernel # +# default: # CONFIG_FREERTOS_SMP is not set +# default: # CONFIG_FREERTOS_UNICORE is not set CONFIG_FREERTOS_HZ=1000 # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set @@ -1486,9 +1712,12 @@ CONFIG_FREERTOS_HZ=1000 CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +# default: # CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# default: # CONFIG_FREERTOS_USE_TICK_HOOK is not set CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# default: # CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set CONFIG_FREERTOS_USE_TIMERS=y CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" @@ -1501,28 +1730,38 @@ CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# default: # CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# default: # CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set +# default: # CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# default: # CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set # end of Kernel # # Port # +# default: # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# default: # CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set +# default: # CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y CONFIG_FREERTOS_ISR_STACKSIZE=1536 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# default: # CONFIG_FREERTOS_FPU_IN_ISR is not set CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y CONFIG_FREERTOS_CORETIMER_0=y # CONFIG_FREERTOS_CORETIMER_1 is not set CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# default: # CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +# default: # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set # end of Port @@ -1561,9 +1800,13 @@ CONFIG_HEAP_POISONING_DISABLED=y CONFIG_HEAP_TRACING_OFF=y # CONFIG_HEAP_TRACING_STANDALONE is not set # CONFIG_HEAP_TRACING_TOHOST is not set +# default: # CONFIG_HEAP_USE_HOOKS is not set +# default: # CONFIG_HEAP_TASK_TRACKING is not set +# default: # CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# default: # CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set # end of Heap memory debugging @@ -1592,6 +1835,7 @@ CONFIG_LOG_MAXIMUM_LEVEL=0 # # Level Settings # +# default: # CONFIG_LOG_MASTER_LEVEL is not set CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y # CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set @@ -1606,6 +1850,7 @@ CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 # # Format # +# default: # CONFIG_LOG_COLORS is not set CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set @@ -1617,31 +1862,45 @@ CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LWIP_ENABLE=y CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# default: # CONFIG_LWIP_NETIF_API is not set CONFIG_LWIP_TCPIP_TASK_PRIO=18 +# default: # CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# default: # CONFIG_LWIP_CHECK_THREAD_SAFETY is not set CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# default: # CONFIG_LWIP_L2_TO_L3_COPY is not set +# default: # CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# default: # CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set CONFIG_LWIP_TIMERS_ONDEMAND=y CONFIG_LWIP_ND6=y +# default: # CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set CONFIG_LWIP_MAX_SOCKETS=10 +# default: # CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# default: # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y CONFIG_LWIP_SO_RCVBUF=y +# default: # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP_DEFAULT_TTL=64 CONFIG_LWIP_IP4_FRAG=y CONFIG_LWIP_IP6_FRAG=y +# default: # CONFIG_LWIP_IP4_REASSEMBLY is not set +# default: # CONFIG_LWIP_IP6_REASSEMBLY is not set CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# default: # CONFIG_LWIP_IP_FORWARD is not set +# default: # CONFIG_LWIP_STATS is not set CONFIG_LWIP_ESP_GRATUITOUS_ARP=y CONFIG_LWIP_GARP_TMR_INTERVAL=60 @@ -1651,8 +1910,10 @@ CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y # CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set # CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set +# default: # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# default: # CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set CONFIG_LWIP_DHCP_OPTIONS_LEN=68 CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 @@ -1668,12 +1929,16 @@ CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y CONFIG_LWIP_DHCPS_ADD_DNS=y # end of DHCP server +# default: # CONFIG_LWIP_AUTOIP is not set CONFIG_LWIP_IPV4=y CONFIG_LWIP_IPV6=y +# default: # CONFIG_LWIP_IPV6_AUTOCONFIG is not set CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# default: # CONFIG_LWIP_IPV6_FORWARD is not set +# default: # CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set CONFIG_LWIP_NETIF_LOOPBACK=y CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 @@ -1697,6 +1962,7 @@ CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 CONFIG_LWIP_TCP_QUEUE_OOSEQ=y CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 +# default: # CONFIG_LWIP_TCP_SACK_OUT is not set CONFIG_LWIP_TCP_OVERSIZE_MSS=y # CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set @@ -1714,7 +1980,9 @@ CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 # # Checksums # +# default: # CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# default: # CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums @@ -1729,14 +1997,18 @@ CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 +# default: # CONFIG_LWIP_PPP_SUPPORT is not set +# default: # CONFIG_LWIP_SLIP_SUPPORT is not set # # ICMP # CONFIG_LWIP_ICMP=y +# default: # CONFIG_LWIP_MULTICAST_PING is not set +# default: # CONFIG_LWIP_BROADCAST_PING is not set # end of ICMP @@ -1750,6 +2022,7 @@ CONFIG_LWIP_MAX_RAW_PCBS=16 # SNTP # CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# default: # CONFIG_LWIP_DHCP_GET_NTP_SRV is not set CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 CONFIG_LWIP_SNTP_STARTUP_DELAY=y @@ -1761,7 +2034,9 @@ CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 # CONFIG_LWIP_DNS_MAX_HOST_IP=1 CONFIG_LWIP_DNS_MAX_SERVERS=3 +# default: # CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set +# default: # CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set # end of DNS @@ -1793,6 +2068,7 @@ CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y # CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set # end of Hooks +# default: # CONFIG_LWIP_DEBUG is not set # end of LWIP @@ -1805,15 +2081,21 @@ CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# default: # CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# default: # CONFIG_MBEDTLS_DEBUG is not set # # mbedTLS v3.x related # +# default: # CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set +# default: # CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# default: # CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# default: # CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y CONFIG_MBEDTLS_PKCS7_C=y @@ -1826,26 +2108,35 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# default: # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# default: # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 # end of Certificate Bundle +# default: # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set CONFIG_MBEDTLS_CMAC_C=y CONFIG_MBEDTLS_HARDWARE_AES=y CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y CONFIG_MBEDTLS_HARDWARE_MPI=y +# default: # CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set CONFIG_MBEDTLS_HARDWARE_SHA=y CONFIG_MBEDTLS_ROM_MD5=y +# default: # CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# default: # CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set CONFIG_MBEDTLS_HAVE_TIME=y +# default: # CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set +# default: # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y CONFIG_MBEDTLS_SHA512_C=y +# default: # CONFIG_MBEDTLS_SHA3_C is not set CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y # CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set @@ -1872,7 +2163,9 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y CONFIG_MBEDTLS_SSL_RENEGOTIATION=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# default: # CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# default: # CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set CONFIG_MBEDTLS_SSL_ALPN=y CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y @@ -1882,15 +2175,21 @@ CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y # Symmetric Ciphers # CONFIG_MBEDTLS_AES_C=y +# default: # CONFIG_MBEDTLS_CAMELLIA_C is not set +# default: # CONFIG_MBEDTLS_DES_C is not set +# default: # CONFIG_MBEDTLS_BLOWFISH_C is not set +# default: # CONFIG_MBEDTLS_XTEA_C is not set CONFIG_MBEDTLS_CCM_C=y CONFIG_MBEDTLS_GCM_C=y +# default: # CONFIG_MBEDTLS_NIST_KW_C is not set # end of Symmetric Ciphers +# default: # CONFIG_MBEDTLS_RIPEMD160_C is not set # @@ -1905,9 +2204,11 @@ CONFIG_MBEDTLS_X509_CSR_PARSE_C=y CONFIG_MBEDTLS_ECP_C=y CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y +# default: # CONFIG_MBEDTLS_DHM_C is not set CONFIG_MBEDTLS_ECDH_C=y CONFIG_MBEDTLS_ECDSA_C=y +# default: # CONFIG_MBEDTLS_ECJPAKE_C is not set CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y @@ -1922,10 +2223,15 @@ CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# default: # CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set +# default: # CONFIG_MBEDTLS_POLY1305_C is not set +# default: # CONFIG_MBEDTLS_CHACHA20_C is not set +# default: # CONFIG_MBEDTLS_HKDF_C is not set +# default: # CONFIG_MBEDTLS_THREADING_C is not set CONFIG_MBEDTLS_ERROR_STRINGS=y CONFIG_MBEDTLS_FS_IO=y @@ -1934,15 +2240,25 @@ CONFIG_MBEDTLS_FS_IO=y # # ESP-MQTT Configurations # +# default: # CONFIG_MQTT_PROTOCOL_311 is not set +# default: # CONFIG_MQTT_PROTOCOL_5 is not set +# default: # CONFIG_MQTT_TRANSPORT_SSL is not set +# default: # CONFIG_MQTT_TRANSPORT_WEBSOCKET is not set +# default: # CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# default: # CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# default: # CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# default: # CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# default: # CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# default: # CONFIG_MQTT_CUSTOM_OUTBOX is not set # end of ESP-MQTT Configurations @@ -1955,6 +2271,7 @@ CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y # CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set # CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# default: # CONFIG_NEWLIB_NANO_FORMAT is not set CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y # CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set @@ -1965,18 +2282,22 @@ CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y # # NVS # +# default: # CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# default: # CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set # end of NVS # # OpenThread # +# default: # CONFIG_OPENTHREAD_ENABLED is not set # # OpenThread Spinel # +# default: # CONFIG_OPENTHREAD_SPINEL_ONLY is not set # end of OpenThread Spinel # end of OpenThread @@ -2030,6 +2351,7 @@ CONFIG_SPI_FLASH_BROWNOUT_RESET=y # Features here require specific hardware (READ DOCS FIRST!) # CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 +# default: # CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set # end of Optional and Experimental Features (READ DOCS FIRST) # end of Main Flash configuration @@ -2037,20 +2359,27 @@ CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 # # SPI Flash driver # +# default: # CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# default: # CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y # CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set # CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# default: # CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set +# default: # CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# default: # CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# default: # CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# default: # CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set # @@ -2065,7 +2394,9 @@ CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +# default: # CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# default: # CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set # end of Auto-detect flash chips @@ -2082,14 +2413,17 @@ CONFIG_SPIFFS_MAX_PARTITIONS=3 # CONFIG_SPIFFS_CACHE=y CONFIG_SPIFFS_CACHE_WR=y +# default: # CONFIG_SPIFFS_CACHE_STATS is not set # end of SPIFFS Cache Configuration CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 +# default: # CONFIG_SPIFFS_GC_STATS is not set CONFIG_SPIFFS_PAGE_SIZE=256 CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# default: # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y @@ -2099,11 +2433,17 @@ CONFIG_SPIFFS_USE_MTIME=y # # Debug Configuration # +# default: # CONFIG_SPIFFS_DBG is not set +# default: # CONFIG_SPIFFS_API_DBG is not set +# default: # CONFIG_SPIFFS_GC_DBG is not set +# default: # CONFIG_SPIFFS_CACHE_DBG is not set +# default: # CONFIG_SPIFFS_CHECK_DBG is not set +# default: # CONFIG_SPIFFS_TEST_VISUALISATION is not set # end of Debug Configuration # end of SPIFFS Configuration @@ -2117,6 +2457,7 @@ CONFIG_SPIFFS_USE_MTIME=y # CONFIG_WS_TRANSPORT=y CONFIG_WS_BUFFER_SIZE=1024 +# default: # CONFIG_WS_DYNAMIC_BUFFER is not set # end of Websocket # end of TCP Transport @@ -2124,6 +2465,7 @@ CONFIG_WS_BUFFER_SIZE=1024 # # Ultra Low Power (ULP) Co-processor # +# default: # CONFIG_ULP_COPROC_ENABLED is not set # @@ -2137,10 +2479,14 @@ CONFIG_WS_BUFFER_SIZE=1024 # CONFIG_UNITY_ENABLE_FLOAT=y CONFIG_UNITY_ENABLE_DOUBLE=y +# default: # CONFIG_UNITY_ENABLE_64BIT is not set +# default: # CONFIG_UNITY_ENABLE_COLOR is not set CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# default: # CONFIG_UNITY_ENABLE_FIXTURE is not set +# default: # CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set # end of Unity unit testing library @@ -2151,6 +2497,7 @@ CONFIG_VFS_SUPPORT_IO=y CONFIG_VFS_SUPPORT_DIR=y CONFIG_VFS_SUPPORT_SELECT=y CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +# default: # CONFIG_VFS_SELECT_IN_RAM is not set CONFIG_VFS_SUPPORT_TERMIOS=y CONFIG_VFS_MAX_COUNT=8 @@ -2177,10 +2524,14 @@ CONFIG_WL_SECTOR_SIZE=4096 # CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# default: # CONFIG_WIFI_PROV_BLE_BONDING is not set CONFIG_WIFI_PROV_BLE_SEC_CONN=y +# default: # CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set +# default: # CONFIG_WIFI_PROV_BLE_NOTIFY is not set +# default: # CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set @@ -2189,9 +2540,33 @@ CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # # Zigbee # +# default: # CONFIG_ZB_ENABLED is not set # end of Zigbee +# +# esp-modem +# +# default: +CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y +# default: +# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set +# default: +CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 +# default: +# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set +# default: +# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set +# default: +CONFIG_ESP_MODEM_C_API_STR_MAX=128 +# default: +# CONFIG_ESP_MODEM_URC_HANDLER is not set +# default: +# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set +# default: +# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set +# end of esp-modem + # # mDNS # @@ -2210,15 +2585,20 @@ CONFIG_MDNS_TASK_AFFINITY=0x0 # CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y +# default: # CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set # end of MDNS Memory Configuration CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 CONFIG_MDNS_TIMER_PERIOD_MS=100 +# default: # CONFIG_MDNS_NETWORKING_SOCKET is not set +# default: # CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set +# default: # CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set CONFIG_MDNS_ENABLE_CONSOLE_CLI=y +# default: # CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set CONFIG_MDNS_MULTIPLE_INSTANCE=y @@ -2236,9 +2616,12 @@ CONFIG_MDNS_PREDEF_NETIF_AP=y CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 +# default: # CONFIG_NETWORK_PROV_BLE_BONDING is not set CONFIG_NETWORK_PROV_BLE_SEC_CONN=y +# default: # CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set +# default: # CONFIG_NETWORK_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y # CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set @@ -2247,6 +2630,7 @@ CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y # # LittleFS # +# default: # CONFIG_LITTLEFS_SDMMC_SUPPORT is not set CONFIG_LITTLEFS_MAX_PARTITIONS=3 CONFIG_LITTLEFS_PAGE_SIZE=256 @@ -2257,29 +2641,41 @@ CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 CONFIG_LITTLEFS_CACHE_SIZE=512 CONFIG_LITTLEFS_BLOCK_CYCLES=512 CONFIG_LITTLEFS_USE_MTIME=y +# default: # CONFIG_LITTLEFS_USE_ONLY_HASH is not set +# default: # CONFIG_LITTLEFS_HUMAN_READABLE is not set CONFIG_LITTLEFS_MTIME_USE_SECONDS=y # CONFIG_LITTLEFS_MTIME_USE_NONCE is not set +# default: # CONFIG_LITTLEFS_SPIFFS_COMPAT is not set +# default: # CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set +# default: # CONFIG_LITTLEFS_FCNTL_GET_PATH is not set +# default: # CONFIG_LITTLEFS_MULTIVERSION is not set # CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y # CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set CONFIG_LITTLEFS_ASSERTS=y +# default: # CONFIG_LITTLEFS_MMAP_PARTITION is not set # end of LittleFS # end of Component config +# default: # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set # Deprecated options for backward compatibility # CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# default: # CONFIG_NO_BLOBS is not set +# default: # CONFIG_ESP32_NO_BLOBS is not set +# default: # CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# default: # CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set # CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set # CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set @@ -2288,7 +2684,9 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y # CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set # CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set CONFIG_LOG_BOOTLOADER_LEVEL=3 +# default: # CONFIG_APP_ROLLBACK_ENABLE is not set +# default: # CONFIG_FLASH_ENCRYPTION_ENABLED is not set # CONFIG_FLASHMODE_QIO is not set # CONFIG_FLASHMODE_QOUT is not set @@ -2304,11 +2702,13 @@ CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y # CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set # CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# default: # CONFIG_CXX_EXCEPTIONS is not set CONFIG_STACK_CHECK_NONE=y # CONFIG_STACK_CHECK_NORM is not set # CONFIG_STACK_CHECK_STRONG is not set # CONFIG_STACK_CHECK_ALL is not set +# default: # CONFIG_WARN_WRITE_STRINGS is not set # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set CONFIG_ESP32_APPTRACE_DEST_NONE=y @@ -2330,7 +2730,9 @@ CONFIG_NIMBLE_ROLE_CENTRAL=y CONFIG_NIMBLE_ROLE_PERIPHERAL=y CONFIG_NIMBLE_ROLE_BROADCASTER=y CONFIG_NIMBLE_ROLE_OBSERVER=y +# default: # CONFIG_NIMBLE_NVS_PERSIST is not set +# default: # CONFIG_NIMBLE_DEBUG is not set CONFIG_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" CONFIG_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 @@ -2347,6 +2749,7 @@ CONFIG_NIMBLE_HS_FLOW_CTRL_ITVL=1000 CONFIG_NIMBLE_HS_FLOW_CTRL_THRESH=2 CONFIG_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y CONFIG_NIMBLE_RPA_TIMEOUT=900 +# default: # CONFIG_NIMBLE_MESH is not set CONFIG_NIMBLE_CRYPTO_STACK_MBEDTLS=y CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y @@ -2366,6 +2769,7 @@ CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y # CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR is not set CONFIG_SCAN_DUPLICATE_TYPE=0 CONFIG_DUPLICATE_SCAN_CACHE_SIZE=100 +# default: # CONFIG_BLE_MESH_SCAN_DUPLICATE_EN is not set CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED=y @@ -2375,16 +2779,20 @@ CONFIG_ADC2_DISABLE_DAC=y CONFIG_SW_COEXIST_ENABLE=y CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y +# default: # CONFIG_MCPWM_ISR_IN_IRAM is not set +# default: # CONFIG_EVENT_LOOP_PROFILING is not set CONFIG_POST_EVENTS_FROM_ISR=y CONFIG_POST_EVENTS_FROM_IRAM_ISR=y CONFIG_GDBSTUB_SUPPORT_TASKS=y CONFIG_GDBSTUB_MAX_TASKS=32 +# default: # CONFIG_OTA_ALLOW_HTTP is not set # CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 +# default: # CONFIG_ESP_SYSTEM_PD_FLASH is not set CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 @@ -2402,12 +2810,17 @@ CONFIG_ESP32_XTAL_FREQ_40=y # CONFIG_ESP32_XTAL_FREQ_AUTO is not set CONFIG_ESP32_XTAL_FREQ=40 CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# default: # CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# default: # CONFIG_REDUCE_PHY_TX_POWER is not set +# default: # CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set +# default: # CONFIG_SPIRAM_SUPPORT is not set +# default: # CONFIG_ESP32_SPIRAM_SUPPORT is not set # CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y @@ -2433,10 +2846,12 @@ CONFIG_INT_WDT_TIMEOUT_MS=300 CONFIG_INT_WDT_CHECK_CPU1=y CONFIG_TASK_WDT=y CONFIG_ESP_TASK_WDT=y +# default: # CONFIG_TASK_WDT_PANIC is not set CONFIG_TASK_WDT_TIMEOUT_S=5 CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# default: # CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set CONFIG_ESP32_DEBUG_OCDAWARE=y CONFIG_BROWNOUT_DET=y @@ -2459,6 +2874,7 @@ CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set CONFIG_BROWNOUT_DET_LVL=0 CONFIG_ESP32_BROWNOUT_DET_LVL=0 +# default: # CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set CONFIG_IPC_TASK_STACK_SIZE=1024 CONFIG_TIMER_TASK_STACK_SIZE=3584 @@ -2469,6 +2885,7 @@ CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# default: # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP32_WIFI_TX_BA_WIN=6 @@ -2479,20 +2896,31 @@ CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +# default: # CONFIG_ESP32_WIFI_IRAM_OPT is not set +# default: # CONFIG_ESP32_WIFI_RX_IRAM_OPT is not set CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y CONFIG_WPA_MBEDTLS_CRYPTO=y CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# default: # CONFIG_WPA_WAPI_PSK is not set +# default: # CONFIG_WPA_11KV_SUPPORT is not set +# default: # CONFIG_WPA_MBO_SUPPORT is not set +# default: # CONFIG_WPA_DPP_SUPPORT is not set +# default: # CONFIG_WPA_11R_SUPPORT is not set +# default: # CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set +# default: # CONFIG_WPA_WPS_STRICT is not set +# default: # CONFIG_WPA_DEBUG_PRINT is not set +# default: # CONFIG_WPA_TESTING_OPTIONS is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set @@ -2500,8 +2928,10 @@ CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y CONFIG_TIMER_TASK_PRIORITY=1 CONFIG_TIMER_TASK_STACK_DEPTH=2048 CONFIG_TIMER_QUEUE_LENGTH=10 +# default: # CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set # CONFIG_HAL_ASSERTION_SILIENT is not set +# default: # CONFIG_L2_TO_L3_COPY is not set CONFIG_ESP_GRATUITOUS_ARP=y CONFIG_GARP_TMR_INTERVAL=60 @@ -2523,6 +2953,7 @@ CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set # CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# default: # CONFIG_PPP_SUPPORT is not set CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y @@ -2541,6 +2972,7 @@ CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +# default: # CONFIG_ESP32_ULP_COPROC_ENABLED is not set CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y diff --git a/sdkconfig.release.old b/sdkconfig.release.old index 2d448110..0f14d870 100644 --- a/sdkconfig.release.old +++ b/sdkconfig.release.old @@ -259,9 +259,13 @@ CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y CONFIG_APP_BUILD_GENERATE_BINARIES=y CONFIG_APP_BUILD_BOOTLOADER=y CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# default: # CONFIG_APP_REPRODUCIBLE_BUILD is not set +# default: # CONFIG_APP_NO_BLOBS is not set +# default: # CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# default: # CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set # end of Build type @@ -296,6 +300,7 @@ CONFIG_BOOTLOADER_LOG_LEVEL=3 # # Format # +# default: # CONFIG_BOOTLOADER_LOG_COLORS is not set CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y # end of Format @@ -304,23 +309,32 @@ CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y # # Serial Flash Configurations # +# default: # CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y # end of Serial Flash Configurations # CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# default: # CONFIG_BOOTLOADER_FACTORY_RESET is not set +# default: # CONFIG_BOOTLOADER_APP_TEST is not set CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y CONFIG_BOOTLOADER_WDT_ENABLE=y +# default: # CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# default: # CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# default: # CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# default: # CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set # end of Bootloader config @@ -328,8 +342,11 @@ CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 # Security features # CONFIG_SECURE_BOOT_V1_SUPPORTED=y +# default: # CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# default: # CONFIG_SECURE_BOOT is not set +# default: # CONFIG_SECURE_FLASH_ENC_ENABLED is not set # end of Security features @@ -337,8 +354,11 @@ CONFIG_SECURE_BOOT_V1_SUPPORTED=y # Application manager # CONFIG_APP_COMPILE_TIME_DATE=y +# default: # CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# default: # CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# default: # CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 # end of Application manager @@ -361,6 +381,7 @@ CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y # # Serial flasher config # +# default: # CONFIG_ESPTOOLPY_NO_STUB is not set # CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set @@ -382,6 +403,7 @@ CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set CONFIG_ESPTOOLPY_FLASHSIZE="2MB" +# default: # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set @@ -411,6 +433,7 @@ CONFIG_PARTITION_TABLE_MD5=y # CONFIG_ARDUINO_VARIANT="esp32" CONFIG_ENABLE_ARDUINO_DEPENDS=y +# default: # CONFIG_AUTOSTART_ARDUINO is not set # CONFIG_ARDUINO_RUN_CORE0 is not set CONFIG_ARDUINO_RUN_CORE1=y @@ -432,7 +455,9 @@ CONFIG_ARDUINO_UDP_RUN_CORE0=y # CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set CONFIG_ARDUINO_UDP_RUNNING_CORE=0 CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 +# default: # CONFIG_ARDUINO_ISR_IRAM is not set +# default: # CONFIG_DISABLE_HAL_LOCKS is not set # @@ -445,7 +470,9 @@ CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE=y # CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set # CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=0 +# default: # CONFIG_ARDUHAL_LOG_COLORS is not set +# default: # CONFIG_ARDUHAL_ESP_LOG is not set # end of Debug Log Configuration @@ -458,19 +485,28 @@ CONFIG_ARDUHAL_PARTITION_SCHEME="min_spiffs" CONFIG_ARDUINO_SELECTIVE_COMPILATION=y CONFIG_ARDUINO_SELECTIVE_SPI=y CONFIG_ARDUINO_SELECTIVE_Wire=y -CONFIG_ARDUINO_SELECTIVE_ESP_SR=y +# default: +# CONFIG_ARDUINO_SELECTIVE_ESP_SR is not set CONFIG_ARDUINO_SELECTIVE_EEPROM=y +# default: # CONFIG_ARDUINO_SELECTIVE_Preferences is not set +# default: # CONFIG_ARDUINO_SELECTIVE_Ticker is not set CONFIG_ARDUINO_SELECTIVE_Update=y +# default: # CONFIG_ARDUINO_SELECTIVE_Zigbee is not set CONFIG_ARDUINO_SELECTIVE_FS=y +# default: # CONFIG_ARDUINO_SELECTIVE_SD is not set +# default: # CONFIG_ARDUINO_SELECTIVE_SD_MMC is not set +# default: # CONFIG_ARDUINO_SELECTIVE_SPIFFS is not set +# default: # CONFIG_ARDUINO_SELECTIVE_FFat is not set CONFIG_ARDUINO_SELECTIVE_LittleFS=y CONFIG_ARDUINO_SELECTIVE_Network=y +# default: # CONFIG_ARDUINO_SELECTIVE_Ethernet is not set CONFIG_ARDUINO_SELECTIVE_PPP=y CONFIG_ARDUINO_SELECTIVE_ArduinoOTA=y @@ -478,17 +514,24 @@ CONFIG_ARDUINO_SELECTIVE_AsyncUDP=y CONFIG_ARDUINO_SELECTIVE_DNSServer=y CONFIG_ARDUINO_SELECTIVE_ESPmDNS=y CONFIG_ARDUINO_SELECTIVE_HTTPClient=y +# default: # CONFIG_ARDUINO_SELECTIVE_Matter is not set +# default: # CONFIG_ARDUINO_SELECTIVE_NetBIOS is not set CONFIG_ARDUINO_SELECTIVE_WebServer=y CONFIG_ARDUINO_SELECTIVE_WiFi=y CONFIG_ARDUINO_SELECTIVE_NetworkClientSecure=y CONFIG_ARDUINO_SELECTIVE_WiFiProv=y CONFIG_ARDUINO_SELECTIVE_BLE=y +# default: # CONFIG_ARDUINO_SELECTIVE_BluetoothSerial is not set -CONFIG_ARDUINO_SELECTIVE_SimpleBLE=y +# default: +# CONFIG_ARDUINO_SELECTIVE_SimpleBLE is not set +# default: # CONFIG_ARDUINO_SELECTIVE_RainMaker is not set +# default: # CONFIG_ARDUINO_SELECTIVE_OpenThread is not set +# default: # CONFIG_ARDUINO_SELECTIVE_Insights is not set # end of Arduino Configuration @@ -505,25 +548,35 @@ CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# default: # CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# default: # CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# default: # CONFIG_COMPILER_CXX_RTTI is not set CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set # CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set # CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# default: # CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set +# default: # CONFIG_COMPILER_WARN_WRITE_STRINGS is not set CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y +# default: # CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# default: # CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# default: # CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set +# default: # CONFIG_COMPILER_DUMP_RTL_FILES is not set CONFIG_COMPILER_RT_LIB_GCCLIB=y CONFIG_COMPILER_RT_LIB_NAME="gcc" CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y # CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set +# default: # CONFIG_COMPILER_STATIC_ANALYZER is not set # end of Compiler options @@ -576,10 +629,15 @@ CONFIG_BT_NIMBLE_ROLE_CENTRAL=y CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y CONFIG_BT_NIMBLE_ROLE_OBSERVER=y +# default: # CONFIG_BT_NIMBLE_NVS_PERSIST is not set +# default: # CONFIG_BT_NIMBLE_SMP_ID_RESET is not set +# default: # CONFIG_BT_NIMBLE_SECURITY_ENABLE is not set +# default: # CONFIG_BT_NIMBLE_DEBUG is not set +# default: # CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nimble" CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 @@ -607,16 +665,22 @@ CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 +# default: # CONFIG_BT_NIMBLE_MESH is not set CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 +# default: # CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY is not set +# default: # CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT is not set CONFIG_BT_NIMBLE_WHITELIST_SIZE=1 +# default: # CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set +# default: # CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set CONFIG_BT_NIMBLE_USE_ESP_TIMER=y CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y +# default: # CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set # @@ -626,6 +690,7 @@ CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y # # GAP Appearance write permissions # +# default: # CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set # end of GAP Appearance write permissions @@ -641,6 +706,7 @@ CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1 # # GAP device name write permissions # +# default: # CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set # end of GAP device name write permissions @@ -652,33 +718,49 @@ CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0 CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0 +# default: # CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL is not set # end of GAP Service # # BLE Services # +# default: # CONFIG_BT_NIMBLE_HID_SERVICE is not set +# default: # CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY is not set # # Device Information Service # +# default: # CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID is not set +# default: # CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED is not set # end of Device Information Service # end of BLE Services +# default: # CONFIG_BT_NIMBLE_VS_SUPPORT is not set +# default: # CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set +# default: # CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set +# default: # CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set +# default: # CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT is not set # @@ -692,6 +774,7 @@ CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23 # end of Host-controller Transport CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 +# default: # CONFIG_BT_NIMBLE_SUBRATE is not set # end of NimBLE Options @@ -701,12 +784,12 @@ CONFIG_BT_NIMBLE_EATT_CHAN_NUM=0 CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set # CONFIG_BTDM_CTRL_MODE_BTDM is not set -CONFIG_BTDM_CTRL_BLE_MAX_CONN=3 +CONFIG_BTDM_CTRL_BLE_MAX_CONN=7 CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 CONFIG_BTDM_CTRL_PCM_FSYNCSHP_EFF=0 -CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=3 +CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=7 CONFIG_BTDM_CTRL_BR_EDR_MIN_ENC_KEY_SZ_DFT_EFF=0 CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 @@ -734,9 +817,12 @@ CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE=y CONFIG_BTDM_SCAN_DUPL_TYPE=0 CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=100 CONFIG_BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD=0 +# default: # CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN is not set CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y +# default: # CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set +# default: # CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 @@ -745,12 +831,15 @@ CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 # # BLE disconnects when Instant Passed (0x28) occurs # +# default: # CONFIG_BTDM_BLE_LLCP_CONN_UPDATE is not set +# default: # CONFIG_BTDM_BLE_LLCP_CHAN_MAP_UPDATE is not set # end of BLE disconnects when Instant Passed (0x28) occurs CONFIG_BTDM_BLE_CHAN_ASS_EN=y CONFIG_BTDM_BLE_PING_EN=y +# default: # CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 is not set CONFIG_BTDM_RESERVE_DRAM=0xdb5c CONFIG_BTDM_CTRL_HLI=y @@ -760,17 +849,21 @@ CONFIG_BTDM_CTRL_HLI=y # Common Options # CONFIG_BT_ALARM_MAX_NUM=50 +# default: # CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set # end of Common Options +# default: # CONFIG_BT_HCI_LOG_DEBUG_EN is not set # end of Bluetooth +# default: # CONFIG_BLE_MESH is not set # # Console Library # +# default: # CONFIG_CONSOLE_SORTED_HELP is not set # end of Console Library @@ -781,6 +874,7 @@ CONFIG_BT_ALARM_MAX_NUM=50 # # TWAI Configuration # +# default: # CONFIG_TWAI_ISR_IN_IRAM is not set CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y @@ -793,7 +887,9 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # Legacy ADC Driver Configuration # CONFIG_ADC_DISABLE_DAC=y +# default: # CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set # @@ -802,6 +898,7 @@ CONFIG_ADC_DISABLE_DAC=y CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y CONFIG_ADC_CAL_LUT_ENABLE=y +# default: # CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set # end of Legacy ADC Calibration Configuration # end of Legacy ADC Driver Configuration @@ -809,49 +906,63 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # # Legacy DAC Driver Configurations # +# default: # CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy DAC Driver Configurations # # Legacy MCPWM Driver Configurations # +# default: # CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy MCPWM Driver Configurations # # Legacy Timer Group Driver Configurations # +# default: # CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Timer Group Driver Configurations # # Legacy RMT Driver Configurations # +# default: # CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy RMT Driver Configurations # # Legacy I2S Driver Configurations # +# default: # CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy I2S Driver Configurations # # Legacy PCNT Driver Configurations # +# default: # CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy PCNT Driver Configurations # # Legacy SDM Driver Configurations # +# default: # CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# default: # CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy SDM Driver Configurations # end of Driver Configurations @@ -859,7 +970,9 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # # eFuse Bit Manager # +# default: # CONFIG_EFUSE_CUSTOM_TABLE is not set +# default: # CONFIG_EFUSE_VIRTUAL is not set # CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y @@ -871,19 +984,28 @@ CONFIG_EFUSE_MAX_BLK_LEN=192 # ESP-TLS # CONFIG_ESP_TLS_USING_MBEDTLS=y +# default: # CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set +# default: # CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# default: # CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set +# default: # CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set +# default: # CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set +# default: # CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# default: # CONFIG_ESP_TLS_INSECURE is not set # end of ESP-TLS # # ADC and ADC Calibration # +# default: # CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set # @@ -895,6 +1017,7 @@ CONFIG_ADC_CALI_LUT_ENABLE=y # end of ADC Calibration Configurations CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# default: # CONFIG_ADC_ENABLE_DEBUG_LOG is not set # end of ADC and ADC Calibration @@ -903,7 +1026,9 @@ CONFIG_ADC_DISABLE_DAC_OUTPUT=y # CONFIG_ESP_COEX_ENABLED=y CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y +# default: # CONFIG_ESP_COEX_POWER_MANAGEMENT is not set +# default: # CONFIG_ESP_COEX_GPIO_DEBUG is not set # end of Wireless Coexistence @@ -916,8 +1041,11 @@ CONFIG_ESP_ERR_TO_NAME_LOOKUP=y # # ESP-Driver:DAC Configurations # +# default: # CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_DAC_ISR_IRAM_SAFE is not set +# default: # CONFIG_DAC_ENABLE_DEBUG_LOG is not set CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # end of ESP-Driver:DAC Configurations @@ -925,7 +1053,9 @@ CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # # ESP-Driver:GPIO Configurations # +# default: # CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set +# default: # CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:GPIO Configurations @@ -933,68 +1063,90 @@ CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y # ESP-Driver:GPTimer Configurations # CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y +# default: # CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# default: # CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:GPTimer Configurations # # ESP-Driver:I2C Configurations # +# default: # CONFIG_I2C_ISR_IRAM_SAFE is not set +# default: # CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# default: # CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set # end of ESP-Driver:I2C Configurations # # ESP-Driver:I2S Configurations # +# default: # CONFIG_I2S_ISR_IRAM_SAFE is not set +# default: # CONFIG_I2S_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:I2S Configurations # # ESP-Driver:LEDC Configurations # +# default: # CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:LEDC Configurations # # ESP-Driver:MCPWM Configurations # +# default: # CONFIG_MCPWM_ISR_IRAM_SAFE is not set +# default: # CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:MCPWM Configurations # # ESP-Driver:PCNT Configurations # +# default: # CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_PCNT_ISR_IRAM_SAFE is not set +# default: # CONFIG_PCNT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:PCNT Configurations # # ESP-Driver:RMT Configurations # +# default: # CONFIG_RMT_ISR_IRAM_SAFE is not set +# default: # CONFIG_RMT_RECV_FUNC_IN_IRAM is not set +# default: # CONFIG_RMT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:RMT Configurations # # ESP-Driver:Sigma Delta Modulator Configurations # +# default: # CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_SDM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Sigma Delta Modulator Configurations # # ESP-Driver:SPI Configurations # +# default: # CONFIG_SPI_MASTER_IN_IRAM is not set CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# default: # CONFIG_SPI_SLAVE_IN_IRAM is not set CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # end of ESP-Driver:SPI Configurations @@ -1002,28 +1154,36 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # # ESP-Driver:Touch Sensor Configurations # +# default: # CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set +# default: # CONFIG_TOUCH_ISR_IRAM_SAFE is not set +# default: # CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Touch Sensor Configurations # # ESP-Driver:UART Configurations # +# default: # CONFIG_UART_ISR_IN_IRAM is not set # end of ESP-Driver:UART Configurations # # Ethernet # +# default: # CONFIG_ETH_USE_ESP32_EMAC is not set +# default: # CONFIG_ETH_USE_SPI_ETHERNET is not set +# default: # CONFIG_ETH_USE_OPENETH is not set # end of Ethernet # # Event Loop Library # +# default: # CONFIG_ESP_EVENT_LOOP_PROFILING is not set CONFIG_ESP_EVENT_POST_FROM_ISR=y CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y @@ -1033,6 +1193,7 @@ CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y # GDB Stub # CONFIG_ESP_GDBSTUB_ENABLED=y +# default: # CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y CONFIG_ESP_GDBSTUB_MAX_TASKS=32 @@ -1049,8 +1210,11 @@ CONFIG_ESPHID_TASK_SIZE_BLE=4096 # ESP HTTP client # CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# default: # CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 # end of ESP HTTP client @@ -1062,8 +1226,11 @@ CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 CONFIG_HTTPD_MAX_URI_LEN=512 CONFIG_HTTPD_ERR_RESP_NO_DELAY=y CONFIG_HTTPD_PURGE_BUF_LEN=32 +# default: # CONFIG_HTTPD_LOG_PURGE_DATA is not set +# default: # CONFIG_HTTPD_WS_SUPPORT is not set +# default: # CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # end of HTTP Server @@ -1071,7 +1238,9 @@ CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # # ESP HTTPS OTA # +# default: # CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# default: # CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS OTA @@ -1079,6 +1248,7 @@ CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # # ESP HTTPS server # +# default: # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS server @@ -1125,20 +1295,27 @@ CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 # CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 +# default: # CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set +# default: # CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set # end of MAC Config # # Sleep Config # +# default: # CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +# default: # CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# default: # CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 +# default: # CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set +# default: # CONFIG_ESP_SLEEP_DEBUG is not set CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y # end of Sleep Config @@ -1175,6 +1352,7 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # # ESP-Driver:LCD Controller Configurations # +# default: # CONFIG_LCD_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:LCD Controller Configurations @@ -1187,14 +1365,19 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # ESP NETIF Adapter # CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +# default: # CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set CONFIG_ESP_NETIF_TCPIP_LWIP=y # CONFIG_ESP_NETIF_LOOPBACK is not set CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y +# default: # CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# default: # CONFIG_ESP_NETIF_L2_TAP is not set +# default: # CONFIG_ESP_NETIF_BRIDGE_EN is not set +# default: # CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set # end of ESP NETIF Adapter @@ -1208,35 +1391,44 @@ CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y # CONFIG_ESP_PHY_ENABLED=y CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# default: # CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP_PHY_MAX_TX_POWER=20 +# default: # CONFIG_ESP_PHY_REDUCE_TX_POWER is not set +# default: # CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set CONFIG_ESP_PHY_RF_CAL_PARTIAL=y # CONFIG_ESP_PHY_RF_CAL_NONE is not set # CONFIG_ESP_PHY_RF_CAL_FULL is not set CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# default: # CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# default: # CONFIG_ESP_PHY_RECORD_USED_TIME is not set # end of PHY # # Power Management # +# default: # CONFIG_PM_ENABLE is not set +# default: # CONFIG_PM_SLP_IRAM_OPT is not set # end of Power Management # # ESP PSRAM # +# default: # CONFIG_SPIRAM is not set # end of ESP PSRAM # # ESP Ringbuf # +# default: # CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set # end of ESP Ringbuf @@ -1256,11 +1448,13 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 # # Memory # +# default: # CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set # # Non-backward compatible options # +# default: # CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set # end of Non-backward compatible options # end of Memory @@ -1268,6 +1462,7 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 # # Trace memory # +# default: # CONFIG_ESP32_TRAX is not set CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 # end of Trace memory @@ -1303,11 +1498,14 @@ CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 CONFIG_ESP_INT_WDT_CHECK_CPU1=y CONFIG_ESP_TASK_WDT_EN=y CONFIG_ESP_TASK_WDT_INIT=y +# default: # CONFIG_ESP_TASK_WDT_PANIC is not set CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# default: # CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# default: # CONFIG_ESP_DEBUG_STUBS_ENABLE is not set CONFIG_ESP_DEBUG_OCDAWARE=y CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y @@ -1327,6 +1525,7 @@ CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y CONFIG_ESP_BROWNOUT_DET_LVL=0 # end of Brownout Detector +# default: # CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y # end of ESP System Settings @@ -1342,15 +1541,18 @@ CONFIG_ESP_IPC_ISR_ENABLE=y # # ESP Timer (High Resolution Timer) # +# default: # CONFIG_ESP_TIMER_PROFILING is not set CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# default: # CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# default: # CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set CONFIG_ESP_TIMER_IMPL_TG0_LAC=y # end of ESP Timer (High Resolution Timer) @@ -1369,6 +1571,7 @@ CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y # CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 +# default: # CONFIG_ESP_WIFI_CSI_ENABLED is not set CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP_WIFI_TX_BA_WIN=6 @@ -1379,13 +1582,17 @@ CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +# default: # CONFIG_ESP_WIFI_IRAM_OPT is not set +# default: # CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set +# default: # CONFIG_ESP_WIFI_RX_IRAM_OPT is not set CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y CONFIG_ESP_WIFI_ENABLE_SAE_PK=y CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# default: # CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 @@ -1393,28 +1600,41 @@ CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y CONFIG_ESP_WIFI_GMAC_SUPPORT=y CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# default: # CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# default: # CONFIG_ESP_WIFI_NAN_ENABLE is not set CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# default: # CONFIG_ESP_WIFI_WAPI_PSK is not set +# default: # CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_11R_SUPPORT is not set +# default: # CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set # # WPS Configuration Options # +# default: # CONFIG_ESP_WIFI_WPS_STRICT is not set +# default: # CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set # end of WPS Configuration Options +# default: # CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# default: # CONFIG_ESP_WIFI_TESTING_OPTIONS is not set CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y +# default: # CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set # end of Wi-Fi @@ -1461,12 +1681,15 @@ CONFIG_FATFS_CODEPAGE=437 CONFIG_FATFS_FS_LOCK=0 CONFIG_FATFS_TIMEOUT_MS=10000 CONFIG_FATFS_PER_FILE_CACHE=y +# default: # CONFIG_FATFS_USE_FASTSEEK is not set CONFIG_FATFS_USE_STRFUNC_NONE=y # CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set # CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# default: # CONFIG_FATFS_IMMEDIATE_FSYNC is not set +# default: # CONFIG_FATFS_USE_LABEL is not set CONFIG_FATFS_LINK_LOCK=y # end of FAT Filesystem support @@ -1478,7 +1701,9 @@ CONFIG_FATFS_LINK_LOCK=y # # Kernel # +# default: # CONFIG_FREERTOS_SMP is not set +# default: # CONFIG_FREERTOS_UNICORE is not set CONFIG_FREERTOS_HZ=1000 # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set @@ -1486,9 +1711,12 @@ CONFIG_FREERTOS_HZ=1000 CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +# default: # CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# default: # CONFIG_FREERTOS_USE_TICK_HOOK is not set CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# default: # CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set CONFIG_FREERTOS_USE_TIMERS=y CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" @@ -1501,28 +1729,38 @@ CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# default: # CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# default: # CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set +# default: # CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# default: # CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set # end of Kernel # # Port # +# default: # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# default: # CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set +# default: # CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y CONFIG_FREERTOS_ISR_STACKSIZE=1536 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# default: # CONFIG_FREERTOS_FPU_IN_ISR is not set CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y CONFIG_FREERTOS_CORETIMER_0=y # CONFIG_FREERTOS_CORETIMER_1 is not set CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# default: # CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +# default: # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set # end of Port @@ -1561,9 +1799,13 @@ CONFIG_HEAP_POISONING_DISABLED=y CONFIG_HEAP_TRACING_OFF=y # CONFIG_HEAP_TRACING_STANDALONE is not set # CONFIG_HEAP_TRACING_TOHOST is not set +# default: # CONFIG_HEAP_USE_HOOKS is not set +# default: # CONFIG_HEAP_TASK_TRACKING is not set +# default: # CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# default: # CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set # end of Heap memory debugging @@ -1592,6 +1834,7 @@ CONFIG_LOG_MAXIMUM_LEVEL=0 # # Level Settings # +# default: # CONFIG_LOG_MASTER_LEVEL is not set CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y # CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set @@ -1606,6 +1849,7 @@ CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 # # Format # +# default: # CONFIG_LOG_COLORS is not set CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set @@ -1617,31 +1861,45 @@ CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LWIP_ENABLE=y CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# default: # CONFIG_LWIP_NETIF_API is not set CONFIG_LWIP_TCPIP_TASK_PRIO=18 +# default: # CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# default: # CONFIG_LWIP_CHECK_THREAD_SAFETY is not set CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# default: # CONFIG_LWIP_L2_TO_L3_COPY is not set +# default: # CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# default: # CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set CONFIG_LWIP_TIMERS_ONDEMAND=y CONFIG_LWIP_ND6=y +# default: # CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set CONFIG_LWIP_MAX_SOCKETS=10 +# default: # CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# default: # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y CONFIG_LWIP_SO_RCVBUF=y +# default: # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP_DEFAULT_TTL=64 CONFIG_LWIP_IP4_FRAG=y CONFIG_LWIP_IP6_FRAG=y +# default: # CONFIG_LWIP_IP4_REASSEMBLY is not set +# default: # CONFIG_LWIP_IP6_REASSEMBLY is not set CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# default: # CONFIG_LWIP_IP_FORWARD is not set +# default: # CONFIG_LWIP_STATS is not set CONFIG_LWIP_ESP_GRATUITOUS_ARP=y CONFIG_LWIP_GARP_TMR_INTERVAL=60 @@ -1651,8 +1909,10 @@ CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y # CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set # CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set +# default: # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# default: # CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set CONFIG_LWIP_DHCP_OPTIONS_LEN=68 CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 @@ -1668,12 +1928,16 @@ CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y CONFIG_LWIP_DHCPS_ADD_DNS=y # end of DHCP server +# default: # CONFIG_LWIP_AUTOIP is not set CONFIG_LWIP_IPV4=y CONFIG_LWIP_IPV6=y +# default: # CONFIG_LWIP_IPV6_AUTOCONFIG is not set CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# default: # CONFIG_LWIP_IPV6_FORWARD is not set +# default: # CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set CONFIG_LWIP_NETIF_LOOPBACK=y CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 @@ -1697,6 +1961,7 @@ CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 CONFIG_LWIP_TCP_QUEUE_OOSEQ=y CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 +# default: # CONFIG_LWIP_TCP_SACK_OUT is not set CONFIG_LWIP_TCP_OVERSIZE_MSS=y # CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set @@ -1714,7 +1979,9 @@ CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 # # Checksums # +# default: # CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# default: # CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums @@ -1729,14 +1996,18 @@ CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 +# default: # CONFIG_LWIP_PPP_SUPPORT is not set +# default: # CONFIG_LWIP_SLIP_SUPPORT is not set # # ICMP # CONFIG_LWIP_ICMP=y +# default: # CONFIG_LWIP_MULTICAST_PING is not set +# default: # CONFIG_LWIP_BROADCAST_PING is not set # end of ICMP @@ -1750,6 +2021,7 @@ CONFIG_LWIP_MAX_RAW_PCBS=16 # SNTP # CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# default: # CONFIG_LWIP_DHCP_GET_NTP_SRV is not set CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 CONFIG_LWIP_SNTP_STARTUP_DELAY=y @@ -1761,7 +2033,9 @@ CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 # CONFIG_LWIP_DNS_MAX_HOST_IP=1 CONFIG_LWIP_DNS_MAX_SERVERS=3 +# default: # CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set +# default: # CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set # end of DNS @@ -1793,6 +2067,7 @@ CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y # CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set # end of Hooks +# default: # CONFIG_LWIP_DEBUG is not set # end of LWIP @@ -1805,15 +2080,21 @@ CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# default: # CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# default: # CONFIG_MBEDTLS_DEBUG is not set # # mbedTLS v3.x related # +# default: # CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set +# default: # CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# default: # CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# default: # CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y CONFIG_MBEDTLS_PKCS7_C=y @@ -1826,26 +2107,35 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# default: # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# default: # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 # end of Certificate Bundle +# default: # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set CONFIG_MBEDTLS_CMAC_C=y CONFIG_MBEDTLS_HARDWARE_AES=y CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y CONFIG_MBEDTLS_HARDWARE_MPI=y +# default: # CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set CONFIG_MBEDTLS_HARDWARE_SHA=y CONFIG_MBEDTLS_ROM_MD5=y +# default: # CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# default: # CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set CONFIG_MBEDTLS_HAVE_TIME=y +# default: # CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set +# default: # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y CONFIG_MBEDTLS_SHA512_C=y +# default: # CONFIG_MBEDTLS_SHA3_C is not set CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y # CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set @@ -1872,7 +2162,9 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y CONFIG_MBEDTLS_SSL_RENEGOTIATION=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# default: # CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# default: # CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set CONFIG_MBEDTLS_SSL_ALPN=y CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y @@ -1882,15 +2174,21 @@ CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y # Symmetric Ciphers # CONFIG_MBEDTLS_AES_C=y +# default: # CONFIG_MBEDTLS_CAMELLIA_C is not set +# default: # CONFIG_MBEDTLS_DES_C is not set +# default: # CONFIG_MBEDTLS_BLOWFISH_C is not set +# default: # CONFIG_MBEDTLS_XTEA_C is not set CONFIG_MBEDTLS_CCM_C=y CONFIG_MBEDTLS_GCM_C=y +# default: # CONFIG_MBEDTLS_NIST_KW_C is not set # end of Symmetric Ciphers +# default: # CONFIG_MBEDTLS_RIPEMD160_C is not set # @@ -1905,9 +2203,11 @@ CONFIG_MBEDTLS_X509_CSR_PARSE_C=y CONFIG_MBEDTLS_ECP_C=y CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y +# default: # CONFIG_MBEDTLS_DHM_C is not set CONFIG_MBEDTLS_ECDH_C=y CONFIG_MBEDTLS_ECDSA_C=y +# default: # CONFIG_MBEDTLS_ECJPAKE_C is not set CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y @@ -1922,10 +2222,15 @@ CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# default: # CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set +# default: # CONFIG_MBEDTLS_POLY1305_C is not set +# default: # CONFIG_MBEDTLS_CHACHA20_C is not set +# default: # CONFIG_MBEDTLS_HKDF_C is not set +# default: # CONFIG_MBEDTLS_THREADING_C is not set CONFIG_MBEDTLS_ERROR_STRINGS=y CONFIG_MBEDTLS_FS_IO=y @@ -1934,15 +2239,25 @@ CONFIG_MBEDTLS_FS_IO=y # # ESP-MQTT Configurations # +# default: # CONFIG_MQTT_PROTOCOL_311 is not set +# default: # CONFIG_MQTT_PROTOCOL_5 is not set +# default: # CONFIG_MQTT_TRANSPORT_SSL is not set +# default: # CONFIG_MQTT_TRANSPORT_WEBSOCKET is not set +# default: # CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# default: # CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# default: # CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# default: # CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# default: # CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# default: # CONFIG_MQTT_CUSTOM_OUTBOX is not set # end of ESP-MQTT Configurations @@ -1955,6 +2270,7 @@ CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y # CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set # CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# default: # CONFIG_NEWLIB_NANO_FORMAT is not set CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y # CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set @@ -1965,18 +2281,22 @@ CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y # # NVS # +# default: # CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# default: # CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set # end of NVS # # OpenThread # +# default: # CONFIG_OPENTHREAD_ENABLED is not set # # OpenThread Spinel # +# default: # CONFIG_OPENTHREAD_SPINEL_ONLY is not set # end of OpenThread Spinel # end of OpenThread @@ -2030,6 +2350,7 @@ CONFIG_SPI_FLASH_BROWNOUT_RESET=y # Features here require specific hardware (READ DOCS FIRST!) # CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 +# default: # CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set # end of Optional and Experimental Features (READ DOCS FIRST) # end of Main Flash configuration @@ -2037,20 +2358,27 @@ CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 # # SPI Flash driver # +# default: # CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# default: # CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y # CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set # CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# default: # CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set +# default: # CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# default: # CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# default: # CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# default: # CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set # @@ -2065,7 +2393,9 @@ CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +# default: # CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# default: # CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set # end of Auto-detect flash chips @@ -2082,14 +2412,17 @@ CONFIG_SPIFFS_MAX_PARTITIONS=3 # CONFIG_SPIFFS_CACHE=y CONFIG_SPIFFS_CACHE_WR=y +# default: # CONFIG_SPIFFS_CACHE_STATS is not set # end of SPIFFS Cache Configuration CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 +# default: # CONFIG_SPIFFS_GC_STATS is not set CONFIG_SPIFFS_PAGE_SIZE=256 CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# default: # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y @@ -2099,11 +2432,17 @@ CONFIG_SPIFFS_USE_MTIME=y # # Debug Configuration # +# default: # CONFIG_SPIFFS_DBG is not set +# default: # CONFIG_SPIFFS_API_DBG is not set +# default: # CONFIG_SPIFFS_GC_DBG is not set +# default: # CONFIG_SPIFFS_CACHE_DBG is not set +# default: # CONFIG_SPIFFS_CHECK_DBG is not set +# default: # CONFIG_SPIFFS_TEST_VISUALISATION is not set # end of Debug Configuration # end of SPIFFS Configuration @@ -2117,6 +2456,7 @@ CONFIG_SPIFFS_USE_MTIME=y # CONFIG_WS_TRANSPORT=y CONFIG_WS_BUFFER_SIZE=1024 +# default: # CONFIG_WS_DYNAMIC_BUFFER is not set # end of Websocket # end of TCP Transport @@ -2124,6 +2464,7 @@ CONFIG_WS_BUFFER_SIZE=1024 # # Ultra Low Power (ULP) Co-processor # +# default: # CONFIG_ULP_COPROC_ENABLED is not set # @@ -2137,10 +2478,14 @@ CONFIG_WS_BUFFER_SIZE=1024 # CONFIG_UNITY_ENABLE_FLOAT=y CONFIG_UNITY_ENABLE_DOUBLE=y +# default: # CONFIG_UNITY_ENABLE_64BIT is not set +# default: # CONFIG_UNITY_ENABLE_COLOR is not set CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# default: # CONFIG_UNITY_ENABLE_FIXTURE is not set +# default: # CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set # end of Unity unit testing library @@ -2151,6 +2496,7 @@ CONFIG_VFS_SUPPORT_IO=y CONFIG_VFS_SUPPORT_DIR=y CONFIG_VFS_SUPPORT_SELECT=y CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +# default: # CONFIG_VFS_SELECT_IN_RAM is not set CONFIG_VFS_SUPPORT_TERMIOS=y CONFIG_VFS_MAX_COUNT=8 @@ -2177,10 +2523,14 @@ CONFIG_WL_SECTOR_SIZE=4096 # CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# default: # CONFIG_WIFI_PROV_BLE_BONDING is not set CONFIG_WIFI_PROV_BLE_SEC_CONN=y +# default: # CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set +# default: # CONFIG_WIFI_PROV_BLE_NOTIFY is not set +# default: # CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set @@ -2189,9 +2539,33 @@ CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # # Zigbee # +# default: # CONFIG_ZB_ENABLED is not set # end of Zigbee +# +# esp-modem +# +# default: +CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y +# default: +# CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED is not set +# default: +CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP=0 +# default: +# CONFIG_ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY is not set +# default: +# CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE is not set +# default: +CONFIG_ESP_MODEM_C_API_STR_MAX=128 +# default: +# CONFIG_ESP_MODEM_URC_HANDLER is not set +# default: +# CONFIG_ESP_MODEM_PPP_ESCAPE_BEFORE_EXIT is not set +# default: +# CONFIG_ESP_MODEM_ADD_DEBUG_LOGS is not set +# end of esp-modem + # # mDNS # @@ -2210,15 +2584,20 @@ CONFIG_MDNS_TASK_AFFINITY=0x0 # CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y +# default: # CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set # end of MDNS Memory Configuration CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 CONFIG_MDNS_TIMER_PERIOD_MS=100 +# default: # CONFIG_MDNS_NETWORKING_SOCKET is not set +# default: # CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set +# default: # CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set CONFIG_MDNS_ENABLE_CONSOLE_CLI=y +# default: # CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set CONFIG_MDNS_MULTIPLE_INSTANCE=y @@ -2236,9 +2615,12 @@ CONFIG_MDNS_PREDEF_NETIF_AP=y CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI=y CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=16 CONFIG_NETWORK_PROV_AUTOSTOP_TIMEOUT=30 +# default: # CONFIG_NETWORK_PROV_BLE_BONDING is not set CONFIG_NETWORK_PROV_BLE_SEC_CONN=y +# default: # CONFIG_NETWORK_PROV_BLE_FORCE_ENCRYPTION is not set +# default: # CONFIG_NETWORK_PROV_KEEP_BLE_ON_AFTER_PROV is not set CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y # CONFIG_NETWORK_PROV_WIFI_STA_FAST_SCAN is not set @@ -2247,6 +2629,7 @@ CONFIG_NETWORK_PROV_WIFI_STA_ALL_CHANNEL_SCAN=y # # LittleFS # +# default: # CONFIG_LITTLEFS_SDMMC_SUPPORT is not set CONFIG_LITTLEFS_MAX_PARTITIONS=3 CONFIG_LITTLEFS_PAGE_SIZE=256 @@ -2257,20 +2640,28 @@ CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 CONFIG_LITTLEFS_CACHE_SIZE=512 CONFIG_LITTLEFS_BLOCK_CYCLES=512 CONFIG_LITTLEFS_USE_MTIME=y +# default: # CONFIG_LITTLEFS_USE_ONLY_HASH is not set +# default: # CONFIG_LITTLEFS_HUMAN_READABLE is not set CONFIG_LITTLEFS_MTIME_USE_SECONDS=y # CONFIG_LITTLEFS_MTIME_USE_NONCE is not set +# default: # CONFIG_LITTLEFS_SPIFFS_COMPAT is not set +# default: # CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set +# default: # CONFIG_LITTLEFS_FCNTL_GET_PATH is not set +# default: # CONFIG_LITTLEFS_MULTIVERSION is not set # CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y # CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set CONFIG_LITTLEFS_ASSERTS=y +# default: # CONFIG_LITTLEFS_MMAP_PARTITION is not set # end of LittleFS # end of Component config +# default: # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index d3e6d324..8603dfdd 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -224,48 +224,41 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } void fillAllCadenceLines(ptIndex index, PTData& ptData, bool addReading = false) { + int16_t targetCalculation = 0; for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { + targetCalculation = ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (i - index.cadIndex) * (index.wattIndex + 10); // Create positions for all cadence lines if they are not set. // This gives us a monotonic table with a linear progression of target positions. - if (ptData.tableRow[i].tableEntry[index.wattIndex].readings == 0) { - ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = - ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (i - index.cadIndex) * (index.wattIndex + 10); - // add a reading + if (ptData.tableRow[i].tableEntry[index.wattIndex].readings <= 1) { + ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = targetCalculation; + // add a reading if (addReading) { - ptData.tableRow[i].tableEntry[index.wattIndex].readings++; + ptData.tableRow[i].tableEntry[index.wattIndex].readings = 1; } } - // Positions with a higher row should have lower targetPosition, so enforce monotonicity + // Positions with a lower row (lower cadence) should have higher targetPosition, so enforce monotonicity if (i < index.cadIndex) { - ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = - std::max(ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition, - (int16_t)(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (i - index.cadIndex) * (index.wattIndex + 10))); + ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = std::max(ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition, targetCalculation); } else if (i > index.cadIndex) { - ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = - std::min(ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition, - (int16_t)(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (i - index.cadIndex) * (index.wattIndex + 10))); + ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = std::min(ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition, targetCalculation); } } } void fillAllWattColumns(ptIndex index, PTData& ptData) { + int16_t targetCalculation = 0; for (int i = 0; i < POWERTABLE_WATT_SIZE; i++) { + targetCalculation = ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (index.wattIndex - i) * (index.cadIndex + 10); // Create positions for all watt columns if they are not set. // This gives us a monotonic table with a linear progression of target positions. - if (ptData.tableRow[index.cadIndex].tableEntry[i].readings == 0) { - ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition = - ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (index.wattIndex - i) * (index.cadIndex + 10); - ptData.tableRow[index.cadIndex].tableEntry[i].readings ++; // add a reading + if (ptData.tableRow[index.cadIndex].tableEntry[i].readings <= 1) { + ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition = targetCalculation; } // Each column to the right should have a higher targetPosition, so enforce monotonicity if (i > index.wattIndex) { - ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition = - std::max(ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition, - (int16_t)(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (index.wattIndex - i) * (index.cadIndex + 10))); + ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition = std::max(ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition, targetCalculation); } else if (i < index.wattIndex) { - ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition = - std::min(ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition, - (int16_t)(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (index.wattIndex - i) * (index.cadIndex + 10))); + ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition = std::min(ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition, targetCalculation); } ptIndex newIndex; newIndex.cadIndex = index.cadIndex; @@ -286,12 +279,12 @@ void fillAllWattColumns(ptIndex index, PTData& ptData) { * @param pos The new target position to record or average. */ void PowerTable::enterData(ptIndex index, int pos) { - if (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings <= 0) { // if first reading in this entry + if (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings == 0) { // if first reading in this entry this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition = pos; SS2K_LOG(POWERTABLE_LOG_TAG, "New entry recorded (%d)(%d)(%d)", index.cadIndex, index.wattIndex, this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition); - this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings++; // for initial spot on readings, give 2 (one below as well) - } else { // Average and update the readings. + this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings++; // for initial spot on readings, give 2 (one below as well) + } else { // Average and update the readings. this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition = (pos + (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition * this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings)) / (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings + 1.0f); @@ -308,7 +301,7 @@ void PowerTable::enterData(ptIndex index, int pos) { } void PowerTable::fillTable() { - return ; // testing + return; // testing static int entries = 0; static int newEntries = 0; static int8_t step = 0; From 4e917b8aba338c6aa293db6eaaab7101de30403f Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sun, 13 Jul 2025 15:29:04 -0500 Subject: [PATCH 279/451] Test now creates a power table that you can scroll through time on by using a logfile. --- .gitignore | 2 +- include/PowerTable_Helpers.h | 19 +- include/Power_Table.h | 15 - include/data_helpers.h | 0 src/Main.cpp | 1 - src/PowerTable_Helpers.cpp | 632 +- src/Power_Table.cpp | 211 +- test/data/Ride_Log.txt | 10906 +++++++++++++++++++++++++++++++ test/data_helpers.cpp | 361 +- test/test_table_fill.cpp | 127 +- test/test_write_PowerTable.cpp | 2 +- 11 files changed, 11291 insertions(+), 985 deletions(-) create mode 100644 include/data_helpers.h create mode 100644 test/data/Ride_Log.txt diff --git a/.gitignore b/.gitignore index 86f966d5..9368c42a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ .vscode/extensions.json .idea/ test/tmp_pio_test_transport.cpp -test/output/*.* +test/output/ data/config.txt include/telegram_token.h Errors diff --git a/include/PowerTable_Helpers.h b/include/PowerTable_Helpers.h index 12d38942..6114cc36 100644 --- a/include/PowerTable_Helpers.h +++ b/include/PowerTable_Helpers.h @@ -105,34 +105,21 @@ class TestResults { } }; -class CubicSpline { - public: - void set_points(std::pair, std::vector> xy, size_t n); - float interpolate(float x_val) const; - float extrapolate(float x_val) const; - bool shouldUseNaturalSpline(std::pair, std::vector> xy, size_t n); - - private: - std::vector x, y, h, alpha, l, mu, z, c, b, d; -}; - class PTHelpers { public: TestResults testNeighbors(ptIndex index, int value, PTData& ptData); int32_t lookup(int watts, int cad, PTData& ptData); - bool extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, std::pair, std::vector> xy, size_t n, bool horizontal, - bool naturalSpline, PTData& ptData); - bool splineFill(PTData& ptData, bool firtHalf = true,bool horizontal = true); float linearExtrapolate(std::pair, std::vector> xy, size_t n, float j); - bool linearFill(PTData& ptData); int32_t lookupWatts(int cad, int32_t targetPosition, PTData& ptData); int32_t extrapolateCadenceWatts(int cad, float targetPosition, PTData& ptData); int extrapolateWattsFromCadence(int cad, int32_t targetPosition, PTData& ptData); // return number of readings in the table. If minReadings is set, it will only count entries with at least that many readings. int getNumEntries(PTData& ptData, int minReadings = 0); int getTotalReadings(PTData& ptData); - bool completePowerTable(PTData& data); ptIndex calculateIndex(int watts, int cad); + void enterData(PTData& ptData,ptIndex index, int pos); + void fillAllWattColumns(ptIndex index, PTData& ptData); + void fillAllCadenceLines(ptIndex index, PTData& ptData, bool addReading); std::pair, std::vector> getRow(int row, PTData& ptData); std::pair, std::vector> getColumn(int column, PTData& ptData); }; \ No newline at end of file diff --git a/include/Power_Table.h b/include/Power_Table.h index 69042403..7239e0de 100644 --- a/include/Power_Table.h +++ b/include/Power_Table.h @@ -34,17 +34,9 @@ class PowerTable { // Interpolates and extrapolates the power table. void fillTable(); - // enters data into power table - void enterData(ptIndex index, int pos); - - void downVoteData(ptIndex index, float target, int neighbor); - // returns target position for given cadence and watts. Returns RETURN_ERROR if not found. int32_t lookup(int watts, int cad) { return this->ptHelpers.lookup(watts, cad, this->ptData); } - // returns - int32_t splineLookup(int watts, int cad); - // returns watts for given cadence and target position. Returns RETURN_ERROR if not found. int32_t lookupWatts(int cad, int32_t targetPosition) { return this->ptHelpers.lookupWatts(cad, targetPosition, this->ptData); } @@ -60,13 +52,6 @@ class PowerTable { // Display power table in log void toLog(); - void fillEmptyTable(int outerValue, const std::vector& emptyIndices, const float* x, const float* y, size_t n, bool horizontal, bool useNaturalSpline); - - float calculatePosition(float watts, float cad, float targetPos, ptIndex index); - - void processNeighbor(ptIndex index, float targetPosition, ptIndex neighborIndex, int neighbor_targetPosition, ptIndex oppositeNeighborIndex, - int oppositeNeighbor_targetPosition, float rangeFactor); - private: unsigned long lastSaveTime = millis(); diff --git a/include/data_helpers.h b/include/data_helpers.h new file mode 100644 index 00000000..e69de29b diff --git a/src/Main.cpp b/src/Main.cpp index f801866c..c6607eeb 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -204,7 +204,6 @@ void SS2K::maintenanceLoop(void *pvParameters) { ss2k->moveStepper(); ss2k->FTMSModeShiftModifier(); ergMode->runERG(); - powerTable->fillTable(); } // wattbikeService.parseNemit(); } diff --git a/src/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp index 10f9c9aa..e6d2dc32 100644 --- a/src/PowerTable_Helpers.cpp +++ b/src/PowerTable_Helpers.cpp @@ -292,215 +292,6 @@ int32_t PTHelpers::lookup(int watts, int cad, PTData& ptData) { return resistance; // All lookup methods failed } -/** - * @brief Extrapolates and fills empty indices in a power table row or column using cubic spline interpolation and neighbor blending. - * returns false if the operation takes too long. - * - * This function takes a set of empty indices within a row or column of a power table and attempts to extrapolate their values - * based on existing (x, y) data points using cubic spline interpolation. The extrapolated value is then blended with nearby - * valid neighbors to ensure smoothness and avoid abrupt transitions. The function also ensures that the extrapolated values - * remain within a reasonable range, slightly extended beyond the min/max of the known values. Neighbor blending uses a - * distance-based decay to weight closer neighbors more heavily. - * - * @param outerIndex The index of the row or column being processed, depending on the orientation. - * @param emptyIndices The indices within the row or column that are empty and need to be extrapolated. - * @param xy A pair of vectors representing the known (x, y) data points for interpolation. - * @param n The number of valid (x, y) data points. - * @param horizontal If true, extrapolation is performed horizontally (across columns); otherwise, vertically (across rows). - * @param naturalSpline If true, use a natural cubic spline for interpolation (currently unused in this function). - * @param ptData Reference to the power table data structure to be updated with extrapolated values. - */ -bool PTHelpers::extrapolateEmptyIndices(int outerIndex, const std::vector& emptyIndices, std::pair, std::vector> xy, size_t n, bool horizontal, - bool naturalSpline, PTData& ptData) { - unsigned long timeout = millis() + COMPUTATION_TIMEOUT_MS; // Set timeout for computation - ptIndex index; - if (n >= 3) { - bool validForSpline = true; - for (size_t i = 1; i < n; ++i) { - if (xy.first[i] <= xy.first[i - 1]) { - validForSpline = false; - break; - } - } - if (!validForSpline) { - SS2K_LOG(PTDATA_LOG_TAG, "Duplicate or non-increasing x-values detected!"); - return true; - } - - CubicSpline spline; - spline.set_points(xy, n); // Pass pointer-based data - - for (int innerIndex : emptyIndices) { - index.cadIndex = horizontal ? outerIndex : innerIndex; - index.wattIndex = horizontal ? innerIndex : outerIndex; - - float extrapolated_value = spline.extrapolate(innerIndex); - float minVal = *std::min_element(xy.second.begin(), xy.second.end()); - float maxVal = *std::max_element(xy.second.begin(), xy.second.end()); - float range = maxVal - minVal; - extrapolated_value = std::max(minVal - 0.1f * range, std::min(extrapolated_value, maxVal + 0.1f * range)); - int tempValue = (ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition == INT16_MIN) - ? round(extrapolated_value) - : round((extrapolated_value + ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition) / 2.0f); - - if (testNeighbors(index, tempValue, ptData).allNeighborsPassed) { - // Blend with nearby valid neighbors to ensure smoothness - float blendedValue = tempValue; - float totalWeight = 1.0f; // Start with original value - - // Check horizontal and vertical neighbors within 2 steps - const int blendRadius = 2; - const float distanceDecay = 0.7f; // Weight decreases with distance - - for (int di = -blendRadius; di <= blendRadius; di++) { - for (int dj = -blendRadius; dj <= blendRadius; dj++) { - // Skip self - if (di == 0 && dj == 0) continue; - - int ni = index.cadIndex + (horizontal ? 0 : di); - int nj = index.wattIndex + (horizontal ? di : 0); - - // Check if neighbor is valid - if (ni >= 0 && ni < POWERTABLE_CAD_SIZE && nj >= 0 && nj < POWERTABLE_WATT_SIZE) { - int16_t neighborVal = ptData.tableRow[ni].tableEntry[nj].targetPosition; - - if (neighborVal != INT16_MIN) { - // Calculate distance-based weight - float distance = std::fabs(di) + std::fabs(dj); // Manhattan distance - float weight = std::pow(distanceDecay, distance); - - // Add to weighted average - blendedValue += neighborVal * weight; - totalWeight += weight; - } - } - } - } - - // Compute final blended value if we found neighbors - if (totalWeight > 1.0f) { - // More weight to original spline value (70%) for trend preservation - float originalWeight = 0.7f; - float neighborWeight = 1.0f - originalWeight; - - blendedValue = (originalWeight * tempValue + neighborWeight * (blendedValue - tempValue) / (totalWeight - 1.0f)); - } - ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition = static_cast(round(blendedValue)); - if (millis() > timeout) { - SS2K_LOG(PTDATA_LOG_TAG, "Spline fill operation timed out!"); - return false; // Exit if computation takes too long - } - } - } - } - return true; -} - -/** - * @brief Fills missing entries in the power table using cubic spline interpolation. - * - * This function processes either the first or second half of the table rows or columns, - * depending on the `firstHalf` parameter, and interpolates missing values (marked by INT16_MIN) - * using cubic splines. The interpolation is performed either horizontally (across watt indices) - * or vertically (across cadence indices) as determined by the `horizontal` parameter. - * The function ensures overlap between the two halves to provide smooth transitions. - * - * @param ptData Reference to the power table data structure to be filled. - * @param firstHalf (optional) If true, processes the first half (with overlap); otherwise, processes the second half. Default is true. - * @param horizontal (optional) If true, fills across watt indices (rows); if false, fills across cadence indices (columns). Default is true. - */ -bool PTHelpers::splineFill(PTData& ptData, bool firstHalf /*= true*/, bool horizontal /*= true*/) { - bool completedWithoutTimeout = true; - int outerSize = horizontal ? POWERTABLE_CAD_SIZE : POWERTABLE_WATT_SIZE; - int innerSize = horizontal ? POWERTABLE_WATT_SIZE : POWERTABLE_CAD_SIZE; - - std::vector> unique_xy; - std::vector emptyIndices; - std::vector x, y; - int rangeStart, rangeEnd; - - // Determine the range for inner loop based on firstHalf or secondHalf - // This logic for 'rangeStart' and 'rangeEnd' applies to the 'innerIndex' loop - if (firstHalf) { - rangeStart = 0; - // Ensure overlap: process a bit more than half, e.g., 2/3 or 3/4 - // The amount of overlap might need tuning. Let's try 2/3 for now. - rangeEnd = (innerSize * 2) / 3; - if (rangeEnd > innerSize) rangeEnd = innerSize; // cap at innerSize - } else { - // Start from a point that ensures overlap with the first half - rangeStart = innerSize / 3; - rangeEnd = innerSize; - } - - int mid_outer = outerSize / 2; - int max_k_outer = 0; - if (outerSize > 0) { - max_k_outer = std::max(mid_outer, (outerSize - 1) - mid_outer); - } - - auto processOuterIndex = [&](int currentOuterIndex) { - unique_xy.clear(); - emptyIndices.clear(); - x.clear(); - y.clear(); - - ptIndex index; - // Collect data points for the currentOuterIndex across the specified inner range - for (int innerIndex = rangeStart; innerIndex < rangeEnd; ++innerIndex) { - index.cadIndex = horizontal ? currentOuterIndex : innerIndex; - index.wattIndex = horizontal ? innerIndex : currentOuterIndex; - - // Boundary checks for safety, though currentOuterIndex should be valid by loop logic - if (index.cadIndex < 0 || index.cadIndex >= POWERTABLE_CAD_SIZE || index.wattIndex < 0 || index.wattIndex >= POWERTABLE_WATT_SIZE) { - continue; - } - - // Gather valid data points. Exclude points with 0 readings and a valid targetPosition - those are previously interpolated points. - if (ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings > 0 && ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition != INT16_MIN) { - unique_xy.emplace_back(innerIndex, static_cast(ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition)); - } else { - emptyIndices.push_back(innerIndex); - } - } - - if (unique_xy.size() < 2) return; // Skip if not enough data - - std::sort(unique_xy.begin(), unique_xy.end()); - - for (const auto& it : unique_xy) { - x.push_back(it.first); - y.push_back(it.second); - } - - CubicSpline spline; - // The decision to use natural spline might be based on the characteristics of x, y - // For now, let's assume shouldUseNaturalSpline is available and correctly implemented - bool useNaturalSpline = spline.shouldUseNaturalSpline(std::make_pair(x, y), x.size()); - - // Fill empty table entries using the determined spline type - completedWithoutTimeout = extrapolateEmptyIndices(currentOuterIndex, emptyIndices, std::make_pair(x, y), x.size(), horizontal, useNaturalSpline, ptData); - }; - - for (int k = 0; k <= max_k_outer; ++k) { - if (!completedWithoutTimeout) { - return false; // Exit if computation takes too long - } - int outer_upper = mid_outer + k; - if (outer_upper < outerSize) { - processOuterIndex(outer_upper); - } - - if (k > 0) { - int outer_lower = mid_outer - k; - if (outer_lower >= 0) { - processOuterIndex(outer_lower); - } - } - } - return completedWithoutTimeout; // Return true if all operations completed without timeout -} - /** * @brief Estimates the y-coordinate corresponding to a given x-coordinate `j` * using linear extrapolation or interpolation based on provided data points. @@ -537,69 +328,6 @@ float PTHelpers::linearExtrapolate(std::pair, std::vectorlookup(watts, cad, ptData); - if (resistance == RETURN_ERROR) { - // SS2K_LOG(PTDATA_LOG_TAG, "Failed to lookup resistance for watts: %d, cadence: %d", watts, cad); - return; // Skip this cell processing - } else { - resistance = resistance / TABLE_DIVISOR; - } - ptIndex current_pt_idx; - current_pt_idx.wattIndex = currentColIndex; - current_pt_idx.cadIndex = currentRowIndex; - TestResults results = this->testNeighbors(current_pt_idx, resistance, ptData); - if (results.allNeighborsPassed == 1) { - ptData.tableRow[currentRowIndex].tableEntry[currentColIndex].targetPosition = - (ptData.tableRow[currentRowIndex].tableEntry[currentColIndex].targetPosition == INT16_MIN) - ? resistance - : round((ptData.tableRow[currentRowIndex].tableEntry[currentColIndex].targetPosition + resistance) / 2.0f); - // SS2K_LOG(PTDATA_LOG_TAG, "Filled position (%d, %d) with resistance: %d", currentRowIndex, currentColIndex, resistance); - } else { // log the failure to in insert the value - // Serial.printf("Failed to fill position (%d, %d) with resistance: %d\n", currentRowIndex, currentColIndex, resistance); - } - } - }; - - for (int k = 0; k <= max_k; ++k) { - // Process row from mid upwards: mid, mid+1, mid+2, ... - int i_upper = mid + k; - if (i_upper < POWERTABLE_CAD_SIZE) { // Ensure i_upper is a valid row index - for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - processCell(i_upper, j); - } - } - - // Process row from mid downwards: mid-1, mid-2, ..., only if k > 0 to avoid re-processing 'mid' - if (k > 0) { - int i_lower = mid - k; - if (i_lower >= 0) { // Ensure i_lower is a valid row index - for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - processCell(i_lower, j); - } - } - } - } - return true; // Return true if all operations completed without timeout -} - /** * @brief Counts the number of valid entries in the power table. * @@ -764,312 +492,78 @@ int PTHelpers::extrapolateWattsFromCadence(int cad, int32_t targetPosition, PTDa return watts; } -void CubicSpline::set_points(std::pair, std::vector> xy, size_t n) { - if (n < 2) return; // Ensure sufficient points - - x.assign(xy.first.begin(), xy.first.end()); - y.assign(xy.second.begin(), xy.second.end()); - - std::vector h(n - 1), alpha(n, 0.0f); - c.resize(n, 0.0f); - b.resize(n - 1, 0.0f); - d.resize(n - 1, 0.0f); - - for (size_t i = 0; i < n - 1; ++i) { - h[i] = x[i + 1] - x[i]; - if (h[i] == 0.0f) return; // Avoid duplicate x values - } - - for (size_t i = 1; i < n - 1; ++i) { - alpha[i] = (3.0f / h[i]) * (y[i + 1] - y[i]) - (3.0f / h[i - 1]) * (y[i] - y[i - 1]); - } - - float l = 1.0f, mu = 0.0f, z = 0.0f, prev_l = 1.0f, prev_z = 0.0f; - - for (size_t i = 1; i < n - 1; ++i) { - l = 2.0f * (x[i + 1] - x[i - 1]) - h[i - 1] * mu; - mu = h[i] / l; - z = (alpha[i] - h[i - 1] * prev_z) / l; - prev_z = z; - prev_l = l; - } - - for (int j = n - 2; j >= 0; --j) { - c[j] = z - mu * c[j + 1]; - b[j] = (y[j + 1] - y[j]) / h[j] - h[j] * (c[j + 1] + 2.0f * c[j]) / 3.0f; - d[j] = (c[j + 1] - c[j]) / (3.0f * h[j]); - } -} - -float CubicSpline::interpolate(float x_val) const { - if (x_val < x.front() || x_val > x.back()) { - return INT16_MIN; // Out of range - } - - int i = std::upper_bound(x.begin(), x.end(), x_val) - x.begin() - 1; - float dx = x_val - x[i]; - return y[i] + b[i] * dx + c[i] * dx * dx + d[i] * dx * dx * dx; -} - -float CubicSpline::extrapolate(float x_val) const { - if (x_val < x.front()) { - float dx = x_val - x[0]; - return y[0] + b[0] * dx + c[0] * dx * dx + d[0] * dx * dx * dx; - } - if (x_val > x.back()) { - int n = x.size() - 1; - float dx = x_val - x[n]; - return y[n] + b[n - 1] * dx + c[n - 1] * dx * dx + d[n - 1] * dx * dx * dx; +void PTHelpers::fillAllCadenceLines(ptIndex index, PTData& ptData, bool addReading = false) { + int16_t targetCalculation = 0; + for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { + targetCalculation = ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (i - index.cadIndex) * (index.wattIndex + 10); + // Create positions for all cadence lines if they are not set. + // This gives us a monotonic table with a linear progression of target positions. + if (ptData.tableRow[i].tableEntry[index.wattIndex].readings <= 1) { + ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = targetCalculation; + // add a reading + if (addReading) { + ptData.tableRow[i].tableEntry[index.wattIndex].readings = 1; + } + } + // Positions with a lower row (lower cadence) should have higher targetPosition, so enforce monotonicity + if (i < index.cadIndex) { + ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = std::max(ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition, targetCalculation); + } else if (i > index.cadIndex) { + ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = std::min(ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition, targetCalculation); + } } - return INT16_MIN; // Out of range } -bool CubicSpline::shouldUseNaturalSpline(std::pair, std::vector> xy, size_t n) { - if (n < 3) return true; // Default to natural spline for small data sets - - // Compute approximate first derivatives at endpoints - float startSlope = (xy.second[1] - xy.second[0]) / (xy.first[1] - xy.first[0]); - float endSlope = (xy.second[n - 1] - xy.second[n - 2]) / (xy.first[n - 1] - xy.first[n - 2]); - - // Adaptive slope threshold - float dataRange = *std::max_element(xy.second.begin(), xy.second.end()) - *std::min_element(xy.second.begin(), xy.second.end()); - float slopeThreshold = 0.1f * dataRange; - - if (abs(startSlope) > slopeThreshold || abs(endSlope) > slopeThreshold) { - return false; // Use clamped spline - } - - if (n < 4) return true; // Not enough points for second derivative check - - // Compute second derivatives safely - float h0 = xy.first[1] - xy.first[0], h1 = xy.first[2] - xy.first[1]; - if (h0 == 0.0f || h1 == 0.0f) return true; // Avoid division by zero - - float secondDerivativeStart = (xy.second[2] - 2 * xy.second[1] + xy.second[0]) / (h0 * h1); - - float hn1 = xy.first[n - 2] - xy.first[n - 3], hn2 = xy.first[n - 1] - xy.first[n - 2]; - if (hn1 == 0.0f || hn2 == 0.0f) return true; // Avoid division by zero - - float secondDerivativeEnd = (xy.second[n - 1] - 2 * xy.second[n - 2] + xy.second[n - 3]) / (hn1 * hn2); - - float curvatureThreshold = 1.0f; - return !(abs(secondDerivativeStart) > curvatureThreshold || abs(secondDerivativeEnd) > curvatureThreshold); -} - -// --- Helper Functions --- - -// Check if a cell is considered "filled" with valid data -bool isFilled(const TableEntry& entry, int readings = 0) { - return entry.targetPosition != INT16_MIN && entry.readings >= readings; -} - -// Linearly interpolate or extrapolate a value. -// Interpolates if x is between x0 and x1. -// Extrapolates if x is outside x0 and x1. -double linear_interpolate(double x, double x0, double y0, double x1, double y1) { - if (x0 == x1) { - return y0; // Avoid division by zero, return one of the points +void PTHelpers::fillAllWattColumns(ptIndex index, PTData& ptData) { + int16_t targetCalculation = 0; + for (int i = 0; i < POWERTABLE_WATT_SIZE; i++) { + targetCalculation = ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (index.wattIndex - i) * (index.cadIndex + 10); + // Create positions for all watt columns if they are not set. + // This gives us a monotonic table with a linear progression of target positions. + if (ptData.tableRow[index.cadIndex].tableEntry[i].readings <= 1) { + ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition = targetCalculation; + } + // Each column to the right should have a higher targetPosition, so enforce monotonicity + if (i > index.wattIndex) { + ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition = std::max(ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition, targetCalculation); + } else if (i < index.wattIndex) { + ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition = std::min(ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition, targetCalculation); + } + ptIndex newIndex; + newIndex.cadIndex = index.cadIndex; + newIndex.wattIndex = i; + fillAllCadenceLines(newIndex, ptData, false); } - // Formula: y = y0 + (x - x0) * (y1 - y0) / (x1 - x0) - return y0 + (x - x0) * (y1 - y0) / (x1 - x0); } -// --- Core Logic --- - /** - * @brief Completes the power table using an iterative interpolation and enforcement strategy. - * - * This function fills in a partially completed PTData table. It operates in a loop until - * the table is stable (no more changes are made). Each loop consists of two main passes: - * - * 1. Interpolation/Extrapolation Pass: - * - Iterates through each cell that is modifiable (empty or readings == 0). - * - For each cell, it finds the nearest filled neighbors in its row and column. - * - It uses this information to perform bilinear interpolation (if possible), - * linear interpolation, or linear extrapolation to estimate a value. - * - This ensures the filled data follows the trend of the existing measurements. - * - * 2. Monotonicity Enforcement Pass: - * - After interpolation, this pass guarantees all rules are met. - * - It sweeps the grid from bottom-left (0,0) to top-right. - * - It enforces rule 1: cell[r][c] > cell[r][c-1] - * - It enforces rule 2: cell[r][c] > cell[r-1][c] - * - If a rule is violated, the cell's value is minimally adjusted (e.g., incremented by 1) - * to satisfy the rule. This also handles "outliers" with actual readings that - * violate the monotonic structure, correcting them as a last resort. + * @brief Updates or enters data into the power table for a specific row and entry. * - * The loop continues until a full iteration makes no changes, resulting in a complete and - * rule-compliant table. - * - * @param data A reference to the PTData object to be completed in-place. + * This function records a new target position or averages the new position with + * existing data for a specific table entry. It ensures that the number of readings + * does not exceed a defined limit to prevent dilution of recent data. Additionally, + * it triggers table filling and extrapolation processes if the number of entries + * exceeds a threshold. + * @param index The index of the table entry + * @param pos The new target position to record or average. */ -bool PTHelpers::completePowerTable(PTData& data) { - bool changedInIteration = true; - int max_iterations = 100; // Safety break to prevent infinite loops - int iteration_count = 0; - - while (changedInIteration && iteration_count < max_iterations) { - changedInIteration = false; - iteration_count++; - - // --- PASS 1: Interpolation and Extrapolation --- - for (int r = 0; r < POWERTABLE_CAD_SIZE; ++r) { - for (int c = 0; c < POWERTABLE_WATT_SIZE; ++c) { - if (isFilled(data.tableRow[r].tableEntry[c], 1)) { - continue; - } - - // Find horizontal anchors (left and right) for interpolation - int left_c = -1, right_c = -1; - for (int i = c - 1; i >= 0; --i) { - if (isFilled(data.tableRow[r].tableEntry[i], 1)) { - left_c = i; - break; - } - } - for (int i = c + 1; i < POWERTABLE_WATT_SIZE; ++i) { - if (isFilled(data.tableRow[r].tableEntry[i], 1)) { - right_c = i; - break; - } - } - - // Find vertical anchors (bottom and top) for interpolation - int bottom_r = -1, top_r = -1; - for (int i = r - 1; i >= 0; --i) { - if (isFilled(data.tableRow[i].tableEntry[c], 1)) { - bottom_r = i; - break; - } - } - for (int i = r + 1; i < POWERTABLE_CAD_SIZE; ++i) { - if (isFilled(data.tableRow[i].tableEntry[c], 1)) { - top_r = i; - break; - } - } - - double h_val = 0, v_val = 0; - bool h_ok = false, v_ok = false; - - // Horizontal Estimation - if (left_c != -1 && right_c != -1) { - h_val = linear_interpolate(c, left_c, data.tableRow[r].tableEntry[left_c].targetPosition, right_c, data.tableRow[r].tableEntry[right_c].targetPosition); - h_ok = true; - } else if (left_c != -1) { - int l2 = -1; - for (int i = left_c - 1; i >= 0; --i) - if (isFilled(data.tableRow[r].tableEntry[i], 1)) { - l2 = i; - break; - } - if (l2 != -1) - h_val = linear_interpolate(c, l2, data.tableRow[r].tableEntry[l2].targetPosition, left_c, data.tableRow[r].tableEntry[left_c].targetPosition); - else - h_val = data.tableRow[r].tableEntry[left_c].targetPosition; - h_ok = true; - } else if (right_c != -1) { - int r2 = -1; - for (int i = right_c + 1; i < POWERTABLE_WATT_SIZE; ++i) - if (isFilled(data.tableRow[r].tableEntry[i], 1)) { - r2 = i; - break; - } - if (r2 != -1) - h_val = linear_interpolate(c, right_c, data.tableRow[r].tableEntry[right_c].targetPosition, r2, data.tableRow[r].tableEntry[r2].targetPosition); - else - h_val = data.tableRow[r].tableEntry[right_c].targetPosition; - h_ok = true; - } - - // Vertical Estimation - if (bottom_r != -1 && top_r != -1) { - v_val = linear_interpolate(r, bottom_r, data.tableRow[bottom_r].tableEntry[c].targetPosition, top_r, data.tableRow[top_r].tableEntry[c].targetPosition); - v_ok = true; - } else if (bottom_r != -1) { - int b2 = -1; - for (int i = bottom_r - 1; i >= 0; --i) - if (isFilled(data.tableRow[i].tableEntry[c], 1)) { - b2 = i; - break; - } - if (b2 != -1) - v_val = linear_interpolate(r, b2, data.tableRow[b2].tableEntry[c].targetPosition, bottom_r, data.tableRow[bottom_r].tableEntry[c].targetPosition); - else - v_val = data.tableRow[bottom_r].tableEntry[c].targetPosition; - v_ok = true; - } else if (top_r != -1) { - int t2 = -1; - for (int i = top_r + 1; i < POWERTABLE_CAD_SIZE; ++i) - if (isFilled(data.tableRow[i].tableEntry[c], 1)) { - t2 = i; - break; - } - if (t2 != -1) - v_val = linear_interpolate(r, top_r, data.tableRow[top_r].tableEntry[c].targetPosition, t2, data.tableRow[t2].tableEntry[c].targetPosition); - else - v_val = data.tableRow[top_r].tableEntry[c].targetPosition; - v_ok = true; - } - - double final_val = 0; - if (h_ok && v_ok) { - final_val = (h_val + v_val) / 2.0; - } else if (h_ok) { - final_val = h_val; - } else if (v_ok) { - final_val = v_val; - } else { - continue; - } - - int16_t new_pos = static_cast(round(final_val)); - if (data.tableRow[r].tableEntry[c].targetPosition != new_pos) { - data.tableRow[r].tableEntry[c].targetPosition = new_pos; - data.tableRow[r].tableEntry[c].readings = 0; - changedInIteration = true; - } - } +void PTHelpers::enterData(PTData& ptData, ptIndex index, int pos) { + if (ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings == 0) { // if first reading in this entry + ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition = pos; + SS2K_LOG(PTDATA_LOG_TAG, "New entry recorded (%d)(%d)(%d)", index.cadIndex, index.wattIndex, ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition); + ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings++; // for initial spot on readings, give 2 (one below as well) + } else { // Average and update the readings. + ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition = + (pos + (ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition * ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings)) / + (ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings + 1.0f); + SS2K_LOG(PTDATA_LOG_TAG, "Existing entry averaged (%d)(%d)(%d), readings(%d)", index.cadIndex, index.wattIndex, + ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition, ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings); + if (ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings > MAX_NEIGHBOR_WEIGHT) { + ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings = MAX_NEIGHBOR_WEIGHT; } - - // --- PASS 2: Monotonicity Enforcement --- - for (int r = 0; r < POWERTABLE_CAD_SIZE; ++r) { - for (int c = 0; c < POWERTABLE_WATT_SIZE; ++c) { - if (!isFilled(data.tableRow[r].tableEntry[c])) continue; - // --- MODIFIED RULE --- - // Enforce Rule: Neighbor above (row r-1) must be higher. - // This means the value at [r] must be LESS than the value at [r-1]. - if (r > 0 && isFilled(data.tableRow[r - 1].tableEntry[c])) { - if (data.tableRow[r].tableEntry[c].targetPosition >= data.tableRow[r - 1].tableEntry[c].targetPosition) { - if(data.tableRow[r].tableEntry[c].readings > data.tableRow[r - 1].tableEntry[c].readings) { - data.tableRow[r].tableEntry[c].targetPosition += 1; - } else { - data.tableRow[r].tableEntry[c].targetPosition = data.tableRow[r - 1].tableEntry[c].targetPosition - 1; - changedInIteration = true; - } - - } - } - - // Enforce Rule: Neighbor left (column c-1) must be lower. - // This means the value at [c] must be GREATER than the value at [c-1]. - if (c > 0 && isFilled(data.tableRow[r].tableEntry[c - 1])) { - if (data.tableRow[r].tableEntry[c].targetPosition <= data.tableRow[r].tableEntry[c - 1].targetPosition) { - if(data.tableRow[r].tableEntry[c].readings > data.tableRow[r].tableEntry[c - 1].readings) { - data.tableRow[r].tableEntry[c].targetPosition += 1; - } else { - data.tableRow[r].tableEntry[c].targetPosition = data.tableRow[r].tableEntry[c - 1].targetPosition + 1; - changedInIteration = true; - } - - } - } - } - } - } - if (iteration_count >= max_iterations) { - SS2K_LOG(PTDATA_LOG_TAG, "Warning: Table completion reached max iterations. Result may be unstable."); - return false; // Indicate that the table may not be fully completed } - return true; // Indicate that the table was successfully completed + ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings++; + // because of monotonicity, we can make some assumptions in order to fill the table. + fillAllCadenceLines(index, ptData, true); + fillAllWattColumns(index, ptData); } diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index 8603dfdd..b3b11d04 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -53,7 +53,7 @@ void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, Measur if (powerBuffer.powerEntry[0].readings == 0) { // we need to make sure stepper position is not negative so it only takes positive resistance values // Take Initial reading powerBuffer.set(0); - // Check if the current stepper posistion is within a 5% range of the previous stepper position and that the current position is not negative + // Check if the current stepper position is within a 5% range of the previous stepper position and that the current position is not negative } int currentPos = ss2k->getCurrentPosition() / TABLE_DIVISOR; @@ -218,90 +218,13 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { // return; // } - this->enterData(index, (int)targetPosition); + ptHelpers.enterData(ptData, index, (int)targetPosition); fillTableFlag = true; // set flag to fill table BLE_ss2kCustomCharacteristic::notify(0x27, index.cadIndex); } -void fillAllCadenceLines(ptIndex index, PTData& ptData, bool addReading = false) { - int16_t targetCalculation = 0; - for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { - targetCalculation = ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (i - index.cadIndex) * (index.wattIndex + 10); - // Create positions for all cadence lines if they are not set. - // This gives us a monotonic table with a linear progression of target positions. - if (ptData.tableRow[i].tableEntry[index.wattIndex].readings <= 1) { - ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = targetCalculation; - // add a reading - if (addReading) { - ptData.tableRow[i].tableEntry[index.wattIndex].readings = 1; - } - } - // Positions with a lower row (lower cadence) should have higher targetPosition, so enforce monotonicity - if (i < index.cadIndex) { - ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = std::max(ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition, targetCalculation); - } else if (i > index.cadIndex) { - ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition = std::min(ptData.tableRow[i].tableEntry[index.wattIndex].targetPosition, targetCalculation); - } - } -} - -void fillAllWattColumns(ptIndex index, PTData& ptData) { - int16_t targetCalculation = 0; - for (int i = 0; i < POWERTABLE_WATT_SIZE; i++) { - targetCalculation = ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition - (index.wattIndex - i) * (index.cadIndex + 10); - // Create positions for all watt columns if they are not set. - // This gives us a monotonic table with a linear progression of target positions. - if (ptData.tableRow[index.cadIndex].tableEntry[i].readings <= 1) { - ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition = targetCalculation; - } - // Each column to the right should have a higher targetPosition, so enforce monotonicity - if (i > index.wattIndex) { - ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition = std::max(ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition, targetCalculation); - } else if (i < index.wattIndex) { - ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition = std::min(ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition, targetCalculation); - } - ptIndex newIndex; - newIndex.cadIndex = index.cadIndex; - newIndex.wattIndex = i; - fillAllCadenceLines(newIndex, ptData, false); - } -} - -/** - * @brief Updates or enters data into the power table for a specific row and entry. - * - * This function records a new target position or averages the new position with - * existing data for a specific table entry. It ensures that the number of readings - * does not exceed a defined limit to prevent dilution of recent data. Additionally, - * it triggers table filling and extrapolation processes if the number of entries - * exceeds a threshold. - * @param index The index of the table entry - * @param pos The new target position to record or average. - */ -void PowerTable::enterData(ptIndex index, int pos) { - if (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings == 0) { // if first reading in this entry - this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition = pos; - SS2K_LOG(POWERTABLE_LOG_TAG, "New entry recorded (%d)(%d)(%d)", index.cadIndex, index.wattIndex, - this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition); - this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings++; // for initial spot on readings, give 2 (one below as well) - } else { // Average and update the readings. - this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition = - (pos + (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition * this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings)) / - (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings + 1.0f); - SS2K_LOG(POWERTABLE_LOG_TAG, "Existing entry averaged (%d)(%d)(%d), readings(%d)", index.cadIndex, index.wattIndex, - this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition, this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings); - if (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings > MAX_NEIGHBOR_WEIGHT) { - this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings = MAX_NEIGHBOR_WEIGHT; - } - } - this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings++; - // because of monotonicity, we can make some assumptions in order to fill the table. - fillAllCadenceLines(index, this->ptData, true); - fillAllWattColumns(index, this->ptData); -} - void PowerTable::fillTable() { - return; // testing + return; // testing ****************************<<<<<<<<<<<<<<<<*****************<<<<<<<<<<<<<<<<<< static int entries = 0; static int newEntries = 0; static int8_t step = 0; @@ -328,7 +251,7 @@ void PowerTable::fillTable() { if (step == 0) { SS2K_LOG(POWERTABLE_LOG_TAG, "Fill start with %d entries", entries); prevEntries = entries; - ptHelpers.completePowerTable(ptData); + //ptHelpers.completePowerTable(ptData); completed = true; } else if (step == 1) { // completed = ptHelpers.splineFill(ptData, false); @@ -350,132 +273,6 @@ void PowerTable::fillTable() { } } -/** - * @brief Processes a neighbor entry in the power table. - * - * This function checks if the target position of a neighbor entry is within a certain range - * of the current entry's target position. If so, it attempts to enter or update data for the - * neighbor entry based on various conditions. If all tests fail, it downvotes the neighbor entry. - * - * @param index The index of the current entry. - * @param targetPosition The target position of the current entry. - * @param neighborIndex The index of the neighbor entry. - * @param neighbor_targetPosition The target position of the neighbor entry. - * @param oppositeNeighborIndex The index of the opposite neighbor entry. - * @param oppositeNeighbor_targetPosition The target position of the opposite neighbor entry. - * @param rangeFactor A factor used to determine the range for comparison. - */ -void PowerTable::processNeighbor(ptIndex index, float targetPosition, ptIndex neighborIndex, int neighbor_targetPosition, ptIndex oppositeNeighborIndex, - int oppositeNeighbor_targetPosition, float rangeFactor) { - float avgPosition = (targetPosition + neighbor_targetPosition) / 2; - float positionThreshold = 500 * pow(TABLE_DIVISOR, -rangeFactor); - - auto handleNeighbor = [&](ptIndex testIndex, float testPosition, const char* logMessage) { - if (ptHelpers.testNeighbors(testIndex, testPosition, ptData).allNeighborsPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, logMessage, testPosition); - this->enterData(testIndex, testPosition); - return true; - } - return false; - }; - - if (std::abs(neighbor_targetPosition - targetPosition) <= positionThreshold && static_cast(targetPosition) != neighbor_targetPosition) { - bool anyPassed = false; - - anyPassed |= handleNeighbor(index, avgPosition, "Avg position is valid with current cadence and watts! Avg position: %f"); - anyPassed |= handleNeighbor(neighborIndex, targetPosition, "Current Position was valid! Current position: %f"); - anyPassed |= handleNeighbor(oppositeNeighborIndex, neighbor_targetPosition, "Neighbor position was moved from! Neighbor Position: %d"); - - if (!anyPassed) { - SS2K_LOG(POWERTABLE_LOG_TAG, "All tests failed at (%d)(%d)(%d), readings (%d)", oppositeNeighborIndex.cadIndex, oppositeNeighborIndex.wattIndex, - oppositeNeighbor_targetPosition, this->ptData.tableRow[oppositeNeighborIndex.cadIndex].tableEntry[oppositeNeighborIndex.wattIndex].readings); - this->downVoteData(index, targetPosition, neighbor_targetPosition); - } - } else { - SS2K_LOG(POWERTABLE_LOG_TAG, "Was not in range failed at (%d)(%d)(%d), readings (%d)", oppositeNeighborIndex.cadIndex, oppositeNeighborIndex.wattIndex, - oppositeNeighbor_targetPosition, this->ptData.tableRow[oppositeNeighborIndex.cadIndex].tableEntry[oppositeNeighborIndex.wattIndex].readings); - this->downVoteData(neighborIndex, targetPosition, neighbor_targetPosition); - } -} - -/** - * @brief Calculates the target position for a given power table entry based on neighboring values. - * - * This function determines the new target position for a power table entry by analyzing its neighbors - * and applying weighted adjustments based on the differences in watts and cadence. If the current entry - * is invalid or does not pass neighbor tests, the function retains the old target position. - * - * @param watts The power in watts for the current entry. - * @param cad The cadence in RPM for the current entry. - * @param targetPos The current target position to be adjusted. - * @param k The cadence index in the power table. - * @param i The watt index in the power table. - * @return The calculated target position after applying adjustments based on neighbors. - */ -float PowerTable::calculatePosition(float watts, float cad, float targetPos, ptIndex index) { - TestResults testResults = ptHelpers.testNeighbors(index, targetPos, ptData); - - if (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition == INT16_MIN || - !(testResults.bottomNeighbor.passedTest || testResults.topNeighbor.passedTest || testResults.rightNeighbor.passedTest || testResults.leftNeighbor.passedTest) || - this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition == targetPos) { - SS2K_LOG(POWERTABLE_LOG_TAG, "index.cadIndex old targetPosition: (%f)", targetPos); - return targetPos; - } - - int wattPosition = POWERTABLE_WATT_INCREMENT * index.wattIndex; - int cadPosition = MINIMUM_TABLE_CAD + (POWERTABLE_CAD_INCREMENT * index.cadIndex); - - float deltas[] = {float(POWERTABLE_WATT_INCREMENT), float(POWERTABLE_WATT_INCREMENT), float(POWERTABLE_CAD_INCREMENT), float(POWERTABLE_CAD_INCREMENT)}; - float positions[] = {float(wattPosition + POWERTABLE_WATT_INCREMENT), float(wattPosition - POWERTABLE_WATT_INCREMENT), float(cadPosition + POWERTABLE_CAD_INCREMENT), - float(cadPosition - POWERTABLE_CAD_INCREMENT)}; - bool passedTests[] = {testResults.rightNeighbor.passedTest, testResults.leftNeighbor.passedTest, testResults.bottomNeighbor.passedTest, testResults.topNeighbor.passedTest}; - bool isValid[] = {testResults.rightNeighbor.found, testResults.leftNeighbor.found, testResults.bottomNeighbor.found, testResults.topNeighbor.found}; - - float totalValue = 0.0f; - int count = 0; - - for (int idx = 0; idx < sizeof(passedTests) / sizeof(passedTests[0]); ++idx) { - if (passedTests[idx] && isValid[idx]) { - float delta = deltas[idx] / abs(targetPos - float(this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition)); - float x = abs((idx < 2 ? watts : cad) - positions[idx]); - totalValue += targetPos - (x / delta); - count++; - } - } - - if (count > 0) { - targetPos = totalValue / float(count); - } - - SS2K_LOG(POWERTABLE_LOG_TAG, "New averaged targetPosition: (%f) count: (%d)", targetPos, count); - return targetPos; -} - -/** - * @brief Applies a downvote penalty to a specific entry in the power table. - * - * This function reduces the number of readings for a specific entry in the power table - * based on a calculated penalty. If the resulting number of readings falls below zero, - * it is set to zero. This is used to penalize entries that have failed validation. - * - * @param index The index of the table entry to be downvoted. - * @param target The target position value for the entry. - * @param neighbor The neighbor position value for the entry. (used to calculate penalty) - */ -void PowerTable::downVoteData(ptIndex index, float target, int neighbor) { - // determine penalty amount before applying to failed neighbor - int penalty = 1; - - if (this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings < penalty) { - this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings = 0; - this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].targetPosition = INT16_MIN; // remove target position if readings are zero. - } else { - this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings -= penalty; - } - SS2K_LOG(POWERTABLE_LOG_TAG, "PT failed (%d)(%d)(%d), readings (%d)", index.cadIndex, index.wattIndex, neighbor, - this->ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex].readings); -} - bool PowerTable::_manageSaveState(bool canSkipReliabilityChecks) { // Check if the table has been loaded in this session if (!this->_hasBeenLoadedThisSession) { diff --git a/test/data/Ride_Log.txt b/test/data/Ride_Log.txt new file mode 100644 index 00000000..ca1bfa83 --- /dev/null +++ b/test/data/Ride_Log.txt @@ -0,0 +1,10906 @@ + Number New Column + 350217 [2319024][E](PTable): Success! + 350218 [2319024][E](PTable): Clean Power Table + 350219 [2319025][E](PTable): Averaged Entry: watts=132.399994, cad=86.000000, targetPosition=1190.00000, (5)(4) + 350220 [2319036][E](PTable): cellValue: (106) wattDelta: (2.307692) cadDelta: (0.384615) allNeighborsPassed: (0) + 350221 [2319047][E](PTable): rightValue: (0.000000) leftValue: (100.626671) bottomValue: (108.599998) topValue: (0.000000) New averaged targetPosition: (104.613335) count: (2) + 350222 [2319058][E](PTable): Bottom failed at: (105) Target pos: (104.613335) Avg pos: (104) + 350223 [2319070][E](PTable): Current Position moved down is valid! Current position: 104.613335 + 350224 [2319070][E](PTable): Existing entry averaged (6)(4)(104), readings(11) + 350225 [2319578][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350226 [2319601][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 350227 [2319633][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 209 | 212 | 215 | 218 | 219 | 220 | 221 | 222 | | | | | | 224 | | 225 | 226 | | | | | | | | | | + 350228 [2319654][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 199 | 202 | 205 | 208 | 209 | | | | | | | 210 | 214 | 218 | 219 | | | | | | | | | | | | + 350229 [2319688][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 201 | 203 | | | | | 204 | | | 216 | | 224 | | | | | | | | | | | + 350230 [2319710][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | | | 186 | | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | 218 | 223 | 225 | | | | | | | | | | + 350231 [2319732][E](PTable): 85 rpm | | 24 | 84 | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 174 | 176 | 178 | | 179 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | | | | | | | | | | | | | + 350232 [2319764][E](PTable): 90 rpm | 12 | 18 | 80 | | 104 | 108 | 117 | 124 | 137 | 143 | 145 | 150 | 155 | 167 | 169 | 170 | 172 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350233 [2319786][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 106 | 115 | 122 | 133 | 141 | 142 | 146 | 152 | 161 | 163 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350234 [2319820][E](PTable): 100 rpm | -12 | 11 | 72 | 98 | 100 | 104 | 113 | 119 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 350235 [2319842][E](PTable): 105 rpm | -24 | 10 | 69 | 94 | 98 | 102 | 107 | 116 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 350236 [2319873][E](PTable): Power Table Reset + 350237 [2319889][E](Custom_C): 01 19 <-targetPosition + 350238 [2319896][E](PTable): Success! + 350239 [2320600][E](PTable): Success! + 350240 [2320878][E](Custom_C): 01 2a <-hMin + 350241 [2320912][E](Custom_C): 01 19 <-targetPosition + 350242 [2320957][E](Custom_C): 01 2b <-hMax + 350243 [2321301][E](PTable): Success! + 350244 [2321902][E](Custom_C): 01 19 <-targetPosition + 350245 [2322006][E](PTable): Success! + 350246 [2322007][E](PTable): Clean Power Table + 350247 [2322007][E](PTable): Averaged Entry: watts=136.000000, cad=86.000000, targetPosition=1184.00002, (5)(5) + 350248 [2322020][E](PTable): cellValue: (111) wattDelta: (4.054053) cadDelta: (0.675676) allNeighborsPassed: (1) + 350249 [2322021][E](PTable): rightValue: (107.546669) leftValue: (114.453331) bottomValue: (112.480003) topValue: (109.519997) New averaged targetPosition: (111.000000) count: (4) + 350250 [2322043][E](PTable): Existing entry averaged (5)(5)(111), readings(11) + 350251 [2322262][E](Custom_C): 01 25 <-Firmware Version + 350252 [2322590][E](Custom_C): 01 27 05 <-Power Tab Data + 350253 [2322596][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350254 [2322618][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 350255 [2322651][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 209 | 212 | 215 | 218 | 219 | 220 | 221 | 222 | | | | | | 224 | | 225 | 226 | | | | | | | | | | + 350256 [2322674][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 199 | 202 | 205 | 208 | 209 | | | | | | | 210 | 214 | 218 | 219 | | | | | | | | | | | | + 350257 [2322706][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 201 | 203 | | | | | 204 | | | 216 | | 224 | | | | | | | | | | | + 350258 [2322727][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | | | 186 | | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | 218 | 223 | 225 | | | | | | | | | | + 350259 [2322760][E](PTable): 85 rpm | | 24 | 84 | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 174 | 176 | 178 | | 179 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | | | | | | | | | | | | | + 350260 [2322782][E](PTable): 90 rpm | 12 | 18 | 80 | | 104 | 108 | 117 | 124 | 137 | 143 | 145 | 150 | 155 | 167 | 169 | 170 | 172 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350261 [2322814][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 106 | 115 | 122 | 133 | 141 | 142 | 146 | 152 | 161 | 163 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350262 [2322836][E](PTable): 100 rpm | -12 | 11 | 72 | 98 | 100 | 104 | 113 | 119 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 350263 [2322871][E](PTable): 105 rpm | -24 | 10 | 69 | 94 | 98 | 102 | 107 | 116 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 350264 [2322911][E](PTable): Power Table Reset + 350265 [2322912][E](ERG_Mode): Proportional: -8.000000, Integral: -6.200000, Derivative: 1.000000 + 350266 [2323150][E](PTable): Success! + 350267 [2323652][E](FTMS_SERVER): 05 36 01 -> ERG Mode Target: 310 Current: 174 Incline: 117.910004 + 350268 [2323660][E](Custom_C): 01 28 <-targetWatts + 350269 [2323853][E](PTable): Success! + 350270 [2323854][E](PTable): Lookup debug 270 X1 330 X2 85 Y1 95 Y2 -28072604246195435514974028981590701511867830719136396278069932117904226716950353991841713355400276241151069821024799196853636969031294784354382733939572736 + 350271 [2323868][E](PTable): Lookup used neighbors L 143 R 150 R1 148 + 350272 [2323881][E](Custom_C): 01 19 <-targetPosition + 350273 [2323884][E](PTable): Lookup used neighbors U 152 D 142 R2 148 + 350274 [2323886][E](PTable): Lookup used actual 145 R3 145 + 350275 [2323887][E](PTable): Lookup result: 310w 89cad 14600 + 350276 [2323897][E](ERG_Mode): SetPoint changed:310w PowerTable Result: 14600 + 350277 [2323904][E](PTable): Success! + 350278 [2324611][E](PTable): Success! + 350279 [2324612][E](PTable): Clean Power Table + 350280 [2324612][E](PTable): Averaged Entry: watts=160.399994, cad=88.199997, targetPosition=1190.00000, (6)(5) + 350281 [2324624][E](PTable): cellValue: (108) wattDelta: (2.727273) cadDelta: (0.454545) allNeighborsPassed: (0) + 350282 [2324635][E](PTable): rightValue: (0.000000) leftValue: (104.186668) bottomValue: (104.039993) topValue: (0.000000) New averaged targetPosition: (104.113327) count: (2) + 350283 [2324646][E](PTable): Left failed at: (104) Target pos: (104.113327) Avg pos: (104) + 350284 [2324657][E](PTable): Was not in range failed left (6)(4)(104), readings (11) + 350285 [2324658][E](PTable): WEIGHTED DOWNVOTING: Target Value: (104), NeighborValue: (104) + 350286 [2324668][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 350287 [2324668][E](PTable): PT failed (6)(4)(104), readings (11) + 350288 [2324679][E](PTable): Bottom failed at: (106) Target pos: (104.113327) Avg pos: (105) + 350289 [2324690][E](PTable): Current Position moved down is valid! Current position: 104.113327 + 350290 [2324691][E](PTable): Existing entry averaged (7)(5)(105), readings(11) + 350291 [2324884][E](Custom_C): 01 19 <-targetPosition + 350292 [2325248][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350293 [2325272][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 350294 [2325293][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 209 | 212 | 215 | 218 | 219 | 220 | 221 | 222 | | | | | | 224 | | 225 | 226 | | | | | | | | | | + 350295 [2325325][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 199 | 202 | 205 | 208 | 209 | | | | | | | 210 | 214 | 218 | 219 | | | | | | | | | | | | + 350296 [2325348][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 201 | 203 | | | | | 204 | | | 216 | | 224 | | | | | | | | | | | + 350297 [2325380][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | | | 186 | | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | 218 | 223 | 225 | | | | | | | | | | + 350298 [2325402][E](PTable): 85 rpm | | 24 | 84 | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 174 | 176 | 178 | | 179 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | | | | | | | | | | | | | + 350299 [2325434][E](PTable): 90 rpm | 12 | 18 | 80 | | 104 | 108 | 117 | 124 | 137 | 143 | 145 | 150 | 155 | 167 | 169 | 170 | 172 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350300 [2325457][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 146 | 152 | 161 | 163 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350301 [2325489][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 119 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 350302 [2325512][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 116 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 350303 [2325543][E](PTable): Power Table Reset + 350304 [2325829][E](PTable): Success! + 350305 [2325896][E](Custom_C): 01 2a <-hMin + 350306 [2325989][E](Custom_C): 01 19 <-targetPosition + 350307 [2326020][E](Custom_C): 01 2b <-hMax + 350308 [2326098][E](Custom_C): 01 25 <-Firmware Version + 350309 [2326531][E](PTable): Success! + 350310 [2326898][E](Custom_C): 01 19 <-targetPosition + 350311 [2327236][E](PTable): Success! + 350312 [2327924][E](Custom_C): 01 19 <-targetPosition + 350313 [2327941][E](PTable): Success! + 350314 [2327942][E](PTable): Clean Power Table + 350315 [2327942][E](PTable): Averaged Entry: watts=218.399994, cad=94.199997, targetPosition=1491.99997, (7)(7) + 350316 [2327954][E](PTable): cellValue: (122) wattDelta: (1.102941) cadDelta: (0.183824) allNeighborsPassed: (0) + 350317 [2327965][E](PTable): rightValue: (0.000000) leftValue: (114.384003) bottomValue: (117.647987) topValue: (0.000000) New averaged targetPosition: (116.015991) count: (2) + 350318 [2327976][E](PTable): Bottom failed at: (119) Target pos: (116.015991) Avg pos: (117) + 350319 [2327989][E](PTable): Current Position moved down is valid! Current position: 116.015991 + 350320 [2327992][E](PTable): Existing entry averaged (8)(7)(118), readings(8) + 350321 [2328513][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350322 [2328535][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 350323 [2328567][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 209 | 212 | 215 | 218 | 219 | 220 | 221 | 222 | | | | | | 224 | | 225 | 226 | | | | | | | | | | + 350324 [2328589][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 199 | 202 | 205 | 208 | 209 | | | | | | | 210 | 214 | 218 | 219 | | | | | | | | | | | | + 350325 [2328621][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 201 | 203 | | | | | 204 | | | 216 | | 224 | | | | | | | | | | | + 350326 [2328643][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | | | 186 | | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | 218 | 223 | 225 | | | | | | | | | | + 350327 [2328665][E](PTable): 85 rpm | | 24 | 84 | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 174 | 176 | 178 | | 179 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | | | | | | | | | | | | | + 350328 [2328698][E](PTable): 90 rpm | 12 | 18 | 80 | | 104 | 108 | 117 | 124 | 137 | 143 | 145 | 150 | 155 | 167 | 169 | 170 | 172 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350329 [2328720][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 146 | 152 | 161 | 163 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350330 [2328752][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 350331 [2328774][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 350332 [2328806][E](PTable): Power Table Reset + 350333 [2328809][E](ERG_Mode): Proportional: -16.000000, Integral: 2.600000, Derivative: 2.600000 + 350334 [2328838][E](PTable): Success! + 350335 [2328889][E](Custom_C): 01 19 <-targetPosition + 350336 [2329541][E](PTable): Success! + 350337 [2329900][E](Custom_C): 01 19 <-targetPosition + 350338 [2330243][E](PTable): Success! + 350339 [2330903][E](Custom_C): 01 27 00 <-Power Tab Data + 350340 [2330935][E](Custom_C): 01 2a <-hMin + 350341 [2330943][E](PTable): Success! + 350342 [2330944][E](PTable): Clean Power Table + 350343 [2330945][E](PTable): Averaged Entry: watts=324.399994, cad=94.599998, targetPosition=1503.99994, (7)(11) + 350344 [2330960][E](PTable): cellValue: (146) wattDelta: (6.818191) cadDelta: (1.136365) allNeighborsPassed: (0) + 350345 [2330961][E](PTable): rightValue: (145.178665) leftValue: (146.821335) bottomValue: (145.647995) topValue: (0.000000) New averaged targetPosition: (145.882675) count: (3) + 350346 [2330982][E](PTable): Existing entry averaged (7)(11)(145), readings(11) + 350347 [2330992][E](Custom_C): 01 19 <-targetPosition + 350348 [2331049][E](Custom_C): 01 27 01 <-Power Tab Data + 350349 [2331081][E](Custom_C): 01 2b <-hMax + 350350 [2331127][E](Custom_C): 01 27 02 <-Power Tab Data + 350351 [2331184][E](Custom_C): 01 27 03 <-Power Tab Data + 350352 [2331229][E](Custom_C): 01 27 04 <-Power Tab Data + 350353 [2331308][E](Custom_C): 01 27 05 <-Power Tab Data + 350354 [2331352][E](Custom_C): 01 27 06 <-Power Tab Data + 350355 [2331399][E](Custom_C): 01 27 07 <-Power Tab Data + 350356 [2331443][E](Custom_C): 01 27 08 <-Power Tab Data + 350357 [2331488][E](Custom_C): 01 27 09 <-Power Tab Data + 350358 [2331618][E](Custom_C): 01 27 07 <-Power Tab Data + 350359 [2331624][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350360 [2331646][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 350361 [2331679][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 209 | 212 | 215 | 218 | 219 | 220 | 221 | 222 | | | | | | 224 | | 225 | 226 | | | | | | | | | | + 350362 [2331701][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 199 | 202 | 205 | 208 | 209 | | | | | | | 210 | 214 | 218 | 219 | | | | | | | | | | | | + 350363 [2331734][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 201 | 203 | | | | | 204 | | | 216 | | 224 | | | | | | | | | | | + 350364 [2331756][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | | | 186 | | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | 218 | 223 | 225 | | | | | | | | | | + 350365 [2331790][E](PTable): 85 rpm | | 24 | 84 | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 174 | 176 | 178 | | 179 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | | | | | | | | | | | | | + 350366 [2331812][E](PTable): 90 rpm | 12 | 18 | 80 | | 104 | 108 | 117 | 124 | 137 | 143 | 145 | 150 | 155 | 167 | 169 | 170 | 172 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350367 [2331844][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 161 | 163 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350368 [2331866][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 350369 [2331897][E](Custom_C): 01 19 <-targetPosition + 350370 [2331901][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 350371 [2331923][E](PTable): Power Table Reset + 350372 [2332269][E](PTable): Success! + 350373 [2332881][E](Custom_C): 01 19 <-targetPosition + 350374 [2332971][E](PTable): Success! + 350375 [2333676][E](PTable): Success! + 350376 [2333883][E](Custom_C): 01 19 <-targetPosition + 350377 [2334380][E](PTable): Success! + 350378 [2334381][E](PTable): Clean Power Table + 350379 [2334383][E](PTable): Averaged Entry: watts=312.799988, cad=92.800003, targetPosition=1493.99994, (7)(10) + 350380 [2334394][E](PTable): cellValue: (142) wattDelta: (4.054058) cadDelta: (0.675676) allNeighborsPassed: (0) + 350381 [2334395][E](PTable): rightValue: (0.000000) leftValue: (138.842667) bottomValue: (138.744003) topValue: (0.000000) New averaged targetPosition: (138.793335) count: (2) + 350382 [2334416][E](PTable): Left failed at: (141) Target pos: (138.793335) Avg pos: (139) + 350383 [2334427][E](PTable): All test failed left (7)(9)(141), readings (11) + 350384 [2334427][E](PTable): WEIGHTED DOWNVOTING: Target Value: (138), NeighborValue: (141) + 350385 [2334438][E](PTable): WEIGHTED DOWNVOTING: Delta: (3), Penalty: (0) + 350386 [2334438][E](PTable): PT failed (7)(9)(141), readings (11) + 350387 [2334449][E](PTable): Bottom failed at: (141) Target pos: (138.793335) Avg pos: (139) + 350388 [2334450][E](PTable): All test failed bottom (6)(10)(145), readings (11) + 350389 [2334460][E](PTable): WEIGHTED DOWNVOTING: Target Value: (138), NeighborValue: (141) + 350390 [2334471][E](PTable): WEIGHTED DOWNVOTING: Delta: (3), Penalty: (0) + 350391 [2334471][E](PTable): PT failed (8)(10)(141), readings (8) + 350392 [2334485][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350393 [2334506][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350394 [2334539][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350395 [2334561][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350396 [2334584][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350397 [2334616][E](PTable): 80 rpm | | 58 | | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350398 [2334639][E](PTable): 85 rpm | | 24 | | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350399 [2334671][E](PTable): 90 rpm | | | | | 104 | 108 | 117 | 124 | 137 | 143 | 145 | 150 | 155 | 167 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350400 [2334692][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350401 [2334724][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 350402 [2334749][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350403 [2334780][E](PTable): Power Table Reset + 350404 [2334780][E](ERG_Mode): Proportional: -24.000000, Integral: -2.000000, Derivative: -1.000000 + 350405 [2334897][E](Custom_C): 01 19 <-targetPosition + 350406 [2335082][E](PTable): Success! + 350407 [2335787][E](PTable): Success! + 350408 [2335909][E](Custom_C): 01 2a <-hMin + 350409 [2335942][E](Custom_C): 01 19 <-targetPosition + 350410 [2335998][E](Custom_C): 01 2b <-hMax + 350411 [2336489][E](PTable): Success! + 350412 [2336920][E](Custom_C): 01 19 <-targetPosition + 350413 [2337191][E](PTable): Success! + 350414 [2337192][E](PTable): Clean Power Table + 350415 [2337192][E](PTable): Averaged Entry: watts=293.600006, cad=92.199997, targetPosition=1496.00006, (6)(10) + 350416 [2337205][E](PTable): cellValue: (145) wattDelta: (6.521730) cadDelta: (1.086955) allNeighborsPassed: (1) + 350417 [2337206][E](PTable): rightValue: (144.018661) leftValue: (145.981339) bottomValue: (147.024002) topValue: (142.975998) New averaged targetPosition: (145.000000) count: (4) + 350418 [2337227][E](PTable): Existing entry averaged (6)(10)(145), readings(11) + 350419 [2337747][E](Custom_C): 01 27 06 <-Power Tab Data + 350420 [2337752][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350421 [2337775][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 350422 [2337808][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 209 | 212 | 215 | 218 | 219 | 220 | 221 | 222 | | | | | | 224 | | 225 | 226 | | | | | | | | | | + 350423 [2337832][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 199 | 202 | 205 | 208 | 209 | | | | | | | 210 | 214 | 218 | 219 | | | | | | | | | | | | + 350424 [2337854][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 201 | 203 | | | | | 204 | | | 216 | | 224 | | | | | | | | | | | + 350425 [2337888][E](Custom_C): 01 19 <-targetPosition + 350426 [2337891][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | | | 186 | | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | 218 | 223 | 225 | | | | | | | | | | + 350427 [2337915][E](PTable): 85 rpm | | 24 | 84 | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 174 | 176 | 178 | | 179 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | | | | | | | | | | | | | + 350428 [2337947][E](PTable): 90 rpm | 12 | 18 | 80 | | 104 | 108 | 117 | 124 | 137 | 143 | 145 | 150 | 155 | 167 | 169 | 170 | 172 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350429 [2337969][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 161 | 163 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350430 [2338001][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 350431 [2338026][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 350432 [2338057][E](PTable): Power Table Reset + 350433 [2338296][E](PTable): Success! + 350434 [2338911][E](Custom_C): 01 19 <-targetPosition + 350435 [2338998][E](PTable): Success! + 350436 [2339700][E](PTable): Success! + 350437 [2339890][E](Custom_C): 01 19 <-targetPosition + 350438 [2340404][E](PTable): Success! + 350439 [2340405][E](PTable): Clean Power Table + 350440 [2340405][E](PTable): Averaged Entry: watts=291.600006, cad=89.400002, targetPosition=1510.00000, (6)(10) + 350441 [2340417][E](PTable): cellValue: (145) wattDelta: (5.000000) cadDelta: (0.833333) allNeighborsPassed: (0) + 350442 [2340428][E](PTable): rightValue: (0.000000) leftValue: (146.679993) bottomValue: (144.279999) topValue: (145.720001) New averaged targetPosition: (145.559998) count: (3) + 350443 [2340439][E](PTable): Existing entry averaged (6)(10)(145), readings(11) + 350444 [2340881][E](Custom_C): 01 2a <-hMin + 350445 [2340925][E](Custom_C): 01 19 <-targetPosition + 350446 [2340947][E](Custom_C): 01 2b <-hMax + 350447 [2340996][E](Custom_C): 01 27 06 <-Power Tab Data + 350448 [2341001][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350449 [2341024][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 350450 [2341057][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 209 | 212 | 215 | 218 | 219 | 220 | 221 | 222 | | | | | | 224 | | 225 | 226 | | | | | | | | | | + 350451 [2341079][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 199 | 202 | 205 | 208 | 209 | | | | | | | 210 | 214 | 218 | 219 | | | | | | | | | | | | + 350452 [2341111][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 201 | 203 | | | | | 204 | | | 216 | | 224 | | | | | | | | | | | + 350453 [2341133][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | | | 186 | | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | 218 | 223 | 225 | | | | | | | | | | + 350454 [2341165][E](PTable): 85 rpm | | 24 | 84 | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 174 | 176 | 178 | | 179 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | | | | | | | | | | | | | + 350455 [2341187][E](PTable): 90 rpm | 12 | 18 | 80 | | 104 | 108 | 117 | 124 | 137 | 143 | 145 | 150 | 155 | 167 | 169 | 170 | 172 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350456 [2341221][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 161 | 163 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350457 [2341243][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 350458 [2341265][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 350459 [2341296][E](PTable): Power Table Reset + 350460 [2341297][E](ERG_Mode): Proportional: 32.000000, Integral: 6.800000, Derivative: -1.200000 + 350461 [2341323][E](PTable): Success! + 350462 [2341881][E](Custom_C): 01 19 <-targetPosition + 350463 [2342028][E](PTable): Success! + 350464 [2342275][E](Custom_C): 01 25 <-Firmware Version + 350465 [2342730][E](PTable): Success! + 350466 [2342883][E](Custom_C): 01 19 <-targetPosition + 350467 [2343435][E](PTable): Success! + 350468 [2343436][E](PTable): Clean Power Table + 350469 [2343436][E](PTable): Averaged Entry: watts=303.600006, cad=89.199997, targetPosition=1526.00006, (6)(10) + 350470 [2343448][E](PTable): cellValue: (145) wattDelta: (3.947365) cadDelta: (0.657894) allNeighborsPassed: (0) + 350471 [2343459][E](PTable): rightValue: (0.000000) leftValue: (144.087997) bottomValue: (143.783997) topValue: (0.000000) New averaged targetPosition: (143.936005) count: (2) + 350472 [2343470][E](PTable): Left failed at: (143) Target pos: (143.936005) Avg pos: (143) + 350473 [2343481][E](PTable): Was not in range failed left (6)(9)(143), readings (11) + 350474 [2343481][E](PTable): WEIGHTED DOWNVOTING: Target Value: (143), NeighborValue: (143) + 350475 [2343492][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 350476 [2343492][E](PTable): PT failed (6)(9)(143), readings (11) + 350477 [2343504][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350478 [2343526][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350479 [2343558][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350480 [2343580][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350481 [2343612][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350482 [2343633][E](PTable): 80 rpm | | 58 | | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350483 [2343667][E](PTable): 85 rpm | | 24 | | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350484 [2343689][E](PTable): 90 rpm | | | | | 104 | 108 | 117 | 124 | 137 | 143 | 145 | 150 | 155 | 167 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350485 [2343721][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350486 [2343743][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 350487 [2343775][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350488 [2343796][E](PTable): Power Table Reset + 350489 [2343919][E](Custom_C): 01 19 <-targetPosition + 350490 [2344137][E](PTable): Success! + 350491 [2344840][E](PTable): Success! + 350492 [2344897][E](Custom_C): 01 19 <-targetPosition + 350493 [2345542][E](PTable): Success! + 350494 [2345911][E](Custom_C): 01 27 00 <-Power Tab Data + 350495 [2345931][E](Custom_C): 01 2a <-hMin + 350496 [2345965][E](Custom_C): 01 19 <-targetPosition + 350497 [2346000][E](Custom_C): 01 27 01 <-Power Tab Data + 350498 [2346033][E](Custom_C): 01 2b <-hMax + 350499 [2346090][E](Custom_C): 01 27 02 <-Power Tab Data + 350500 [2346161][E](Custom_C): 01 27 03 <-Power Tab Data + 350501 [2346203][E](Custom_C): 01 27 04 <-Power Tab Data + 350502 [2346243][E](PTable): Success! + 350503 [2346244][E](PTable): Clean Power Table + 350504 [2346245][E](PTable): Averaged Entry: watts=305.200012, cad=89.400002, targetPosition=1530.00000, (6)(10) + 350505 [2346259][E](PTable): cellValue: (145) wattDelta: (3.750000) cadDelta: (0.625000) allNeighborsPassed: (0) + 350506 [2346261][E](PTable): rightValue: (0.000000) leftValue: (143.613327) bottomValue: (144.040009) topValue: (0.000000) New averaged targetPosition: (143.826660) count: (2) + 350507 [2346283][E](PTable): Left failed at: (143) Target pos: (143.826660) Avg pos: (143) + 350508 [2346322][E](PTable): Was not in range failed left (6)(9)(143), readings (11) + 350509 [2346323][E](PTable): WEIGHTED DOWNVOTING: Target Value: (143), NeighborValue: (143) + 350510 [2346334][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 350511 [2346334][E](PTable): PT failed (6)(9)(143), readings (11) + 350512 [2346347][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350513 [2346372][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350514 [2346434][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350515 [2346456][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350516 [2346489][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350517 [2346543][E](PTable): 80 rpm | | 58 | | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350518 [2346565][E](PTable): 85 rpm | | 24 | | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350519 [2346621][E](PTable): 90 rpm | | | | | 104 | 108 | 117 | 124 | 137 | 143 | 145 | 150 | 155 | 167 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350520 [2346644][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350521 [2346677][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 350522 [2346737][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350523 [2346758][E](PTable): Power Table Reset + 350524 [2346758][E](ERG_Mode): Proportional: 48.000000, Integral: 7.200000, Derivative: -0.200000 + 350525 [2346769][E](Custom_C): 01 25 <-Firmware Version + 350526 [2346888][E](Custom_C): 01 19 <-targetPosition + 350527 [2346944][E](PTable): Success! + 350528 [2347651][E](PTable): Success! + 350529 [2347878][E](Custom_C): 01 19 <-targetPosition + 350530 [2348354][E](PTable): Success! + 350531 [2348913][E](Custom_C): 01 19 <-targetPosition + 350532 [2349059][E](PTable): Success! + 350533 [2349060][E](PTable): Clean Power Table + 350534 [2349060][E](PTable): Averaged Entry: watts=310.799988, cad=88.199997, targetPosition=1530.00000, (6)(10) + 350535 [2349071][E](PTable): cellValue: (145) wattDelta: (3.750000) cadDelta: (0.625000) allNeighborsPassed: (0) + 350536 [2349085][E](PTable): rightValue: (0.000000) leftValue: (142.120010) bottomValue: (142.119995) topValue: (0.000000) New averaged targetPosition: (142.119995) count: (2) + 350537 [2349097][E](PTable): Left failed at: (143) Target pos: (142.119995) Avg pos: (142) + 350538 [2349097][E](PTable): Current Position moved left was valid! Current position: 142.119995 + 350539 [2349108][E](PTable): Existing entry averaged (6)(9)(142), readings(11) + 350540 [2349602][E](PTable): Bottom failed at: (142) Target pos: (142.119995) Avg pos: (142) + 350541 [2349603][E](PTable): Was not in range failed bottom (7)(10)(142), readings (11) + 350542 [2349614][E](PTable): WEIGHTED DOWNVOTING: Target Value: (142), NeighborValue: (142) + 350543 [2349614][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 350544 [2349624][E](PTable): PT failed (7)(10)(142), readings (11) + 350545 [2349638][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350546 [2349659][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 350547 [2349693][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 209 | 212 | 215 | 218 | 219 | 220 | 221 | 222 | | | | | | 224 | | 225 | 226 | | | | | | | | | | + 350548 [2349715][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 199 | 202 | 205 | 208 | 209 | | | | | | | 210 | 214 | 218 | 219 | | | | | | | | | | | | + 350549 [2349747][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 201 | 203 | | | | | 204 | | | 216 | | 224 | | | | | | | | | | | + 350550 [2349768][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | | | 186 | | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | 218 | 223 | 225 | | | | | | | | | | + 350551 [2349801][E](PTable): 85 rpm | | 24 | 84 | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 174 | 176 | 178 | | 179 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | | | | | | | | | | | | | + 350552 [2349823][E](PTable): 90 rpm | 12 | 18 | 80 | | 104 | 108 | 117 | 124 | 137 | 142 | 145 | 150 | 155 | 167 | 169 | 170 | 172 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350553 [2349855][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 161 | 163 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350554 [2349877][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 350555 [2349913][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 350556 [2349944][E](PTable): Power Table Reset + 350557 [2350197][E](PTable): Success! + 350558 [2350881][E](Custom_C): 01 2a <-hMin + 350559 [2350900][E](PTable): Success! + 350560 [2350901][E](PTable): Using detected travel limits during homing + 350561 [2350915][E](Custom_C): 01 19 <-targetPosition + 350562 [2350972][E](Custom_C): 01 2b <-hMax + 350563 [2351601][E](PTable): Success! + 350564 [2351883][E](Custom_C): 01 19 <-targetPosition + 350565 [2352305][E](PTable): Success! + 350566 [2352305][E](PTable): Clean Power Table + 350567 [2352306][E](PTable): Averaged Entry: watts=298.000000, cad=85.199997, targetPosition=1533.99994, (5)(10) + 350568 [2352317][E](PTable): cellValue: (152) wattDelta: (21.428665) cadDelta: (3.571444) allNeighborsPassed: (0) + 350569 [2352328][E](PTable): rightValue: (151.906662) leftValue: (152.093338) bottomValue: (152.056000) topValue: (0.000000) New averaged targetPosition: (152.018661) count: (3) + 350570 [2352339][E](PTable): Existing entry averaged (5)(10)(152), readings(1) + 350571 [2352858][E](Custom_C): 01 27 05 <-Power Tab Data + 350572 [2352868][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350573 [2352890][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 350574 [2352914][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 209 | 212 | 215 | 218 | 219 | 220 | 221 | 222 | | | | | | 224 | | 225 | 226 | | | | | | | | | | + 350575 [2352957][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 199 | 202 | 205 | 208 | 209 | | | | | | | 210 | 214 | 218 | 219 | | | | | | | | | | | | + 350576 [2352980][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 201 | 203 | | | | | 204 | | | 216 | | 224 | | | | | | | | | | | + 350577 [2353013][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | | | 186 | | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | 218 | 223 | 225 | | | | | | | | | | + 350578 [2353034][E](PTable): 85 rpm | | 24 | 84 | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 174 | 176 | 178 | | 179 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | | | | | | | | | | | | | + 350579 [2353066][E](PTable): 90 rpm | 12 | 18 | 80 | | 104 | 108 | 117 | 124 | 137 | 142 | 145 | 150 | 155 | 167 | 169 | 170 | 172 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350580 [2353088][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 161 | 163 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350581 [2353121][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 350582 [2353142][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 350583 [2353174][E](PTable): Power Table Reset + 350584 [2353174][E](ERG_Mode): Proportional: 112.000000, Integral: 8.800000, Derivative: 0.400000 + 350585 [2353203][E](PTable): Success! + 350586 [2353707][E](FTMS_SERVER): 05 82 00 -> ERG Mode Target: 130 Current: 280 Incline: 154.500000 + 350587 [2353714][E](Custom_C): 01 28 <-targetWatts + 350588 [2353885][E](Custom_C): 01 19 <-targetPosition + 350589 [2353904][E](PTable): Success! + 350590 [2353905][E](PTable): Lookup debug 60 X1 150 X2 80 Y1 90 Y2 -28072597853317318631495944269605137709470556405398469059638733523301993263934200670475972536742741939883091650229084242741624190670042762340801994217750528 + 350591 [2353918][E](PTable): Lookup used neighbors L 84 R 111 R1 105 + 350592 [2353929][E](PTable): Lookup used neighbors U 108 D 104 R2 106 + 350593 [2353929][E](PTable): Lookup used actual 106 R3 106 + 350594 [2353940][E](PTable): Lookup result: 130w 85cad 10500 + 350595 [2353940][E](ERG_Mode): SetPoint changed:130w PowerTable Result: 10500 + 350596 [2353957][E](PTable): Success! + 350597 [2354660][E](PTable): Success! + 350598 [2354661][E](PTable): Clean Power Table + 350599 [2354662][E](PTable): Averaged Entry: watts=290.399994, cad=84.599998, targetPosition=1523.99994, (5)(10) + 350600 [2354673][E](PTable): cellValue: (152) wattDelta: (75.001144) cadDelta: (12.500191) allNeighborsPassed: (1) + 350601 [2354684][E](PTable): rightValue: (151.872009) leftValue: (152.127991) bottomValue: (151.968002) topValue: (152.031998) New averaged targetPosition: (152.000000) count: (4) + 350602 [2354695][E](PTable): Existing entry averaged (5)(10)(152), readings(2) + 350603 [2354898][E](Custom_C): 01 19 <-targetPosition + 350604 [2355280][E](Custom_C): 01 27 05 <-Power Tab Data + 350605 [2355286][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350606 [2355308][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 350607 [2355343][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 209 | 212 | 215 | 218 | 219 | 220 | 221 | 222 | | | | | | 224 | | 225 | 226 | | | | | | | | | | + 350608 [2355365][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 199 | 202 | 205 | 208 | 209 | | | | | | | 210 | 214 | 218 | 219 | | | | | | | | | | | | + 350609 [2355398][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 201 | 203 | | | | | 204 | | | 216 | | 224 | | | | | | | | | | | + 350610 [2355419][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | | | 186 | | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | 218 | 223 | 225 | | | | | | | | | | + 350611 [2355452][E](PTable): 85 rpm | | 24 | 84 | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 174 | 176 | 178 | | 179 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | | | | | | | | | | | | | + 350612 [2355474][E](PTable): 90 rpm | 12 | 18 | 80 | | 104 | 108 | 117 | 124 | 137 | 142 | 145 | 150 | 155 | 167 | 169 | 170 | 172 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350613 [2355496][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 161 | 163 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350614 [2355530][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 350615 [2355553][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 350616 [2355584][E](PTable): Power Table Reset + 350617 [2355808][E](PTable): Success! + 350618 [2355910][E](Custom_C): 01 2a <-hMin + 350619 [2355933][E](Custom_C): 01 19 <-targetPosition + 350620 [2356001][E](Custom_C): 01 2b <-hMax + 350621 [2356511][E](PTable): Success! + 350622 [2356901][E](Custom_C): 01 19 <-targetPosition + 350623 [2357213][E](PTable): Success! + 350624 [2357913][E](Custom_C): 01 19 <-targetPosition + 350625 [2357917][E](PTable): Success! + 350626 [2357917][E](PTable): Clean Power Table + 350627 [2357917][E](PTable): Averaged Entry: watts=182.399994, cad=83.800003, targetPosition=1075.99998, (5)(6) + 350628 [2357930][E](PTable): cellValue: (124) wattDelta: (1.829268) cadDelta: (0.304878) allNeighborsPassed: (0) + 350629 [2357932][E](PTable): rightValue: (92.511993) leftValue: (0.000000) bottomValue: (0.000000) topValue: (95.135986) New averaged targetPosition: (93.823990) count: (2) + 350630 [2357953][E](PTable): Left failed at: (111) Target pos: (93.823990) Avg pos: (102) + 350631 [2357954][E](PTable): All test failed left (5)(5)(111), readings (11) + 350632 [2357964][E](PTable): WEIGHTED DOWNVOTING: Target Value: (93), NeighborValue: (111) + 350633 [2357975][E](PTable): WEIGHTED DOWNVOTING: Delta: (18), Penalty: (3) + 350634 [2357975][E](PTable): PT failed (5)(5)(111), readings (8) + 350635 [2357986][E](PTable): Bottom failed at: (117) Target pos: (93.823990) Avg pos: (105) + 350636 [2357987][E](PTable): Was not in range failed bottom (6)(6)(117), readings (11) + 350637 [2357998][E](PTable): WEIGHTED DOWNVOTING: Target Value: (93), NeighborValue: (117) + 350638 [2358009][E](PTable): WEIGHTED DOWNVOTING: Delta: (24), Penalty: (4) + 350639 [2358009][E](PTable): PT failed (6)(6)(117), readings (7) + 350640 [2358021][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350641 [2358044][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350642 [2358075][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350643 [2358098][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350644 [2358130][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350645 [2358151][E](PTable): 80 rpm | | 58 | | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350646 [2358184][E](PTable): 85 rpm | | 24 | | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350647 [2358205][E](PTable): 90 rpm | | | | | 104 | 108 | 117 | 124 | 137 | 142 | 145 | 150 | 155 | 167 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350648 [2358237][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350649 [2358259][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 350650 [2358292][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350651 [2358314][E](PTable): Power Table Reset + 350652 [2358315][E](ERG_Mode): Proportional: 128.000000, Integral: -1.800000, Derivative: 5.000000 + 350653 [2358620][E](PTable): Success! + 350654 [2358882][E](Custom_C): 01 19 <-targetPosition + 350655 [2359325][E](PTable): Success! + 350656 [2359881][E](Custom_C): 01 19 <-targetPosition + 350657 [2360028][E](PTable): Success! + 350658 [2360729][E](PTable): Success! + 350659 [2360730][E](PTable): Clean Power Table + 350660 [2360730][E](PTable): Averaged Entry: watts=92.800003, cad=88.199997, targetPosition=1064.00002, (6)(3) + 350661 [2360741][E](PTable): Keep old targetPosition: (106.400002) + 350662 [2360742][E](PTable): Right failed at: (104) Target pos: (106.400002) Avg pos: (105) + 350663 [2360752][E](PTable): All test failed right (6)(4)(104), readings (11) + 350664 [2360764][E](PTable): WEIGHTED DOWNVOTING: Target Value: (106), NeighborValue: (104) + 350665 [2360765][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 350666 [2360775][E](PTable): PT failed (6)(4)(104), readings (11) + 350667 [2360777][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350668 [2360809][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350669 [2360831][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350670 [2360863][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350671 [2360887][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350672 [2360943][E](PTable): 80 rpm | | 58 | | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350673 [2360966][E](PTable): 85 rpm | | 24 | | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350674 [2360997][E](Custom_C): 01 2a <-hMin + 350675 [2361001][E](PTable): 90 rpm | | | | | 104 | 108 | 117 | 124 | 137 | 142 | 145 | 150 | 155 | 167 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350676 [2361023][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350677 [2361072][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 350678 [2361093][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350679 [2361125][E](PTable): Power Table Reset + 350680 [2361136][E](Custom_C): 01 27 01 <-Power Tab Data + 350681 [2361177][E](Custom_C): 01 2b <-hMax + 350682 [2361234][E](Custom_C): 01 27 02 <-Power Tab Data + 350683 [2361305][E](Custom_C): 01 27 03 <-Power Tab Data + 350684 [2361348][E](Custom_C): 01 27 04 <-Power Tab Data + 350685 [2361418][E](Custom_C): 01 27 05 <-Power Tab Data + 350686 [2361472][E](Custom_C): 01 27 06 <-Power Tab Data + 350687 [2361549][E](Custom_C): 01 27 07 <-Power Tab Data + 350688 [2361610][E](PTable): Success! + 350689 [2361619][E](Custom_C): 01 27 08 <-Power Tab Data + 350690 [2361660][E](Custom_C): 01 27 09 <-Power Tab Data + 350691 [2361895][E](Custom_C): 01 19 <-targetPosition + 350692 [2362278][E](Custom_C): 01 25 <-Firmware Version + 350693 [2362311][E](PTable): Success! + 350694 [2362885][E](Custom_C): 01 19 <-targetPosition + 350695 [2363016][E](PTable): Success! + 350696 [2363723][E](PTable): Success! + 350697 [2363723][E](PTable): Clean Power Table + 350698 [2363723][E](PTable): Averaged Entry: watts=105.599998, cad=87.400002, targetPosition=1108.00003, (5)(4) + 350699 [2363735][E](PTable): cellValue: (106) wattDelta: (6.249996) cadDelta: (1.041666) allNeighborsPassed: (0) + 350700 [2363746][E](PTable): rightValue: (103.695999) leftValue: (108.304001) bottomValue: (108.304001) topValue: (0.000000) New averaged targetPosition: (106.768005) count: (3) + 350701 [2363758][E](PTable): Existing entry averaged (5)(4)(106), readings(11) + 350702 [2363897][E](Custom_C): 01 19 <-targetPosition + 350703 [2364268][E](Custom_C): 01 27 05 <-Power Tab Data + 350704 [2364273][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350705 [2364295][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 350706 [2364327][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 209 | 212 | 215 | 218 | 219 | 220 | 221 | 222 | | | | | | 224 | | 225 | 226 | | | | | | | | | | + 350707 [2364349][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 199 | 202 | 205 | 208 | 209 | | | | | | | 210 | 214 | 218 | 219 | | | | | | | | | | | | + 350708 [2364381][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 201 | 203 | | | | | 204 | | | 216 | | 224 | | | | | | | | | | | + 350709 [2364403][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | | | 186 | | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | 218 | 223 | 225 | | | | | | | | | | + 350710 [2364437][E](PTable): 85 rpm | | 24 | 84 | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 174 | 176 | 178 | | 179 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | | | | | | | | | | | | | + 350711 [2364459][E](PTable): 90 rpm | 12 | 18 | 80 | | 104 | 108 | 117 | 124 | 137 | 142 | 145 | 150 | 155 | 167 | 169 | 170 | 172 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350712 [2364491][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 161 | 163 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350713 [2364513][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 350714 [2364547][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 350715 [2364567][E](PTable): Power Table Reset + 350716 [2364568][E](ERG_Mode): Proportional: 72.000000, Integral: 7.800000, Derivative: 1.600000 + 350717 [2364596][E](PTable): Success! + 350718 [2364890][E](Custom_C): 01 19 <-targetPosition + 350719 [2365297][E](PTable): Success! + 350720 [2365900][E](Custom_C): 01 2a <-hMin + 350721 [2365922][E](Custom_C): 01 19 <-targetPosition + 350722 [2365968][E](Custom_C): 01 2b <-hMax + 350723 [2366000][E](PTable): Success! + 350724 [2366035][E](Custom_C): 01 25 <-Firmware Version + 350725 [2366704][E](PTable): Success! + 350726 [2366706][E](PTable): Clean Power Table + 350727 [2366706][E](PTable): Averaged Entry: watts=118.400002, cad=87.199997, targetPosition=1120.00000, (5)(4) + 350728 [2366717][E](PTable): cellValue: (106) wattDelta: (5.000000) cadDelta: (0.833333) allNeighborsPassed: (0) + 350729 [2366728][E](PTable): rightValue: (0.000000) leftValue: (106.320000) bottomValue: (108.639999) topValue: (0.000000) New averaged targetPosition: (107.479996) count: (2) + 350730 [2366739][E](PTable): Existing entry averaged (5)(4)(106), readings(11) + 350731 [2366890][E](Custom_C): 01 19 <-targetPosition + 350732 [2367265][E](Custom_C): 01 27 05 <-Power Tab Data + 350733 [2367271][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350734 [2367294][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 350735 [2367327][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 209 | 212 | 215 | 218 | 219 | 220 | 221 | 222 | | | | | | 224 | | 225 | 226 | | | | | | | | | | + 350736 [2367348][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 199 | 202 | 205 | 208 | 209 | | | | | | | 210 | 214 | 218 | 219 | | | | | | | | | | | | + 350737 [2367380][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 201 | 203 | | | | | 204 | | | 216 | | 224 | | | | | | | | | | | + 350738 [2367402][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | | | 186 | | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | 218 | 223 | 225 | | | | | | | | | | + 350739 [2367435][E](PTable): 85 rpm | | 24 | 84 | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 174 | 176 | 178 | | 179 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | | | | | | | | | | | | | + 350740 [2367457][E](PTable): 90 rpm | 12 | 18 | 80 | | 104 | 108 | 117 | 124 | 137 | 142 | 145 | 150 | 155 | 167 | 169 | 170 | 172 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350741 [2367489][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 161 | 163 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350742 [2367511][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 350743 [2367543][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 350744 [2367564][E](PTable): Power Table Reset + 350745 [2367791][E](PTable): Success! + 350746 [2367892][E](Custom_C): 01 19 <-targetPosition + 350747 [2368492][E](PTable): Success! + 350748 [2368915][E](Custom_C): 01 19 <-targetPosition + 350749 [2369196][E](PTable): Success! + 350750 [2369898][E](PTable): Success! + 350751 [2369899][E](PTable): Clean Power Table + 350752 [2369899][E](PTable): Averaged Entry: watts=111.199997, cad=86.199997, targetPosition=1128.00003, (5)(4) + 350753 [2369911][E](Custom_C): 01 19 <-targetPosition + 350754 [2369915][E](PTable): cellValue: (106) wattDelta: (4.411763) cadDelta: (0.735294) allNeighborsPassed: (0) + 350755 [2369927][E](PTable): rightValue: (0.000000) leftValue: (107.994667) bottomValue: (107.631996) topValue: (0.000000) New averaged targetPosition: (107.813332) count: (2) + 350756 [2369938][E](PTable): Existing entry averaged (5)(4)(106), readings(11) + 350757 [2370450][E](Custom_C): 01 27 05 <-Power Tab Data + 350758 [2370455][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350759 [2370479][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 350760 [2370511][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 209 | 212 | 215 | 218 | 219 | 220 | 221 | 222 | | | | | | 224 | | 225 | 226 | | | | | | | | | | + 350761 [2370533][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 199 | 202 | 205 | 208 | 209 | | | | | | | 210 | 214 | 218 | 219 | | | | | | | | | | | | + 350762 [2370565][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 201 | 203 | | | | | 204 | | | 216 | | 224 | | | | | | | | | | | + 350763 [2370588][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | | | 186 | | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | 218 | 223 | 225 | | | | | | | | | | + 350764 [2370620][E](PTable): 85 rpm | | 24 | 84 | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 174 | 176 | 178 | | 179 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | | | | | | | | | | | | | + 350765 [2370642][E](PTable): 90 rpm | 12 | 18 | 80 | | 104 | 108 | 117 | 124 | 137 | 142 | 145 | 150 | 155 | 167 | 169 | 170 | 172 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350766 [2370674][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 161 | 163 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350767 [2370696][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 350768 [2370728][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 350769 [2370749][E](PTable): Power Table Reset + 350770 [2370749][E](ERG_Mode): Proportional: 88.000000, Integral: 8.200000, Derivative: 0.400000 + 350771 [2370776][E](PTable): Success! + 350772 [2370919][E](Custom_C): 01 2a <-hMin + 350773 [2370963][E](Custom_C): 01 19 <-targetPosition + 350774 [2371035][E](Custom_C): 01 2b <-hMax + 350775 [2371479][E](PTable): Success! + 350776 [2371896][E](Custom_C): 01 19 <-targetPosition + 350777 [2372181][E](PTable): Success! + 350778 [2372883][E](PTable): Success! + 350779 [2372885][E](PTable): Clean Power Table + 350780 [2372886][E](PTable): Averaged Entry: watts=108.000000, cad=86.599998, targetPosition=1148.00003, (5)(4) + 350781 [2372897][E](Custom_C): 01 19 <-targetPosition + 350782 [2372900][E](PTable): cellValue: (106) wattDelta: (3.409090) cadDelta: (0.568182) allNeighborsPassed: (0) + 350783 [2372911][E](PTable): rightValue: (0.000000) leftValue: (109.520004) bottomValue: (108.816002) topValue: (0.000000) New averaged targetPosition: (109.167999) count: (2) + 350784 [2372922][E](PTable): Top failed at: (108) Target pos: (109.167999) Avg pos: (108) + 350785 [2372934][E](PTable): Current Position moved up was valid! Current position: 109.167999 + 350786 [2372935][E](PTable): Existing entry averaged (4)(4)(108), readings(11) + 350787 [2373438][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350788 [2373460][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 350789 [2373482][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 209 | 212 | 215 | 218 | 219 | 220 | 221 | 222 | | | | | | 224 | | 225 | 226 | | | | | | | | | | + 350790 [2373515][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 199 | 202 | 205 | 208 | 209 | | | | | | | 210 | 214 | 218 | 219 | | | | | | | | | | | | + 350791 [2373537][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 201 | 203 | | | | | 204 | | | 216 | | 224 | | | | | | | | | | | + 350792 [2373569][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | | | 186 | | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | 218 | 223 | 225 | | | | | | | | | | + 350793 [2373591][E](PTable): 85 rpm | | 24 | 84 | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 174 | 176 | 178 | | 179 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | | | | | | | | | | | | | + 350794 [2373623][E](PTable): 90 rpm | 12 | 18 | 80 | | 104 | 108 | 117 | 124 | 137 | 142 | 145 | 150 | 155 | 167 | 169 | 170 | 172 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350795 [2373644][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 161 | 163 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350796 [2373676][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 350797 [2373698][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 350798 [2373729][E](PTable): Power Table Reset + 350799 [2373890][E](Custom_C): 01 19 <-targetPosition + 350800 [2373974][E](PTable): Success! + 350801 [2374676][E](PTable): Success! + 350802 [2374878][E](Custom_C): 01 19 <-targetPosition + 350803 [2375379][E](PTable): Success! + 350804 [2375903][E](Custom_C): 01 27 00 <-Power Tab Data + 350805 [2375958][E](Custom_C): 01 2a <-hMin + 350806 [2375992][E](Custom_C): 01 19 <-targetPosition + 350807 [2376060][E](Custom_C): 01 27 01 <-Power Tab Data + 350808 [2376081][E](Custom_C): 01 2b <-hMax + 350809 [2376085][E](PTable): Success! + 350810 [2376085][E](PTable): Clean Power Table + 350811 [2376085][E](PTable): Averaged Entry: watts=110.400002, cad=85.000000, targetPosition=1170.00000, (5)(4) + 350812 [2376097][E](PTable): cellValue: (106) wattDelta: (2.727273) cadDelta: (0.454545) allNeighborsPassed: (0) + 350813 [2376108][E](PTable): rightValue: (0.000000) leftValue: (109.519997) bottomValue: (106.000000) topValue: (0.000000) New averaged targetPosition: (107.759995) count: (2) + 350814 [2376122][E](PTable): Existing entry averaged (5)(4)(106), readings(11) + 350815 [2376150][E](Custom_C): 01 27 02 <-Power Tab Data + 350816 [2376196][E](Custom_C): 01 27 03 <-Power Tab Data + 350817 [2376252][E](Custom_C): 01 27 04 <-Power Tab Data + 350818 [2376285][E](Custom_C): 01 27 05 <-Power Tab Data + 350819 [2376353][E](Custom_C): 01 27 06 <-Power Tab Data + 350820 [2376397][E](Custom_C): 01 27 07 <-Power Tab Data + 350821 [2376443][E](Custom_C): 01 27 08 <-Power Tab Data + 350822 [2376487][E](Custom_C): 01 27 09 <-Power Tab Data + 350823 [2376710][E](Custom_C): 01 27 05 <-Power Tab Data + 350824 [2376716][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350825 [2376738][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 350826 [2376770][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 209 | 212 | 215 | 218 | 219 | 220 | 221 | 222 | | | | | | 224 | | 225 | 226 | | | | | | | | | | + 350827 [2376792][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 199 | 202 | 205 | 208 | 209 | | | | | | | 210 | 214 | 218 | 219 | | | | | | | | | | | | + 350828 [2376824][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 201 | 203 | | | | | 204 | | | 216 | | 224 | | | | | | | | | | | + 350829 [2376846][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | | | 186 | | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | 218 | 223 | 225 | | | | | | | | | | + 350830 [2376878][E](PTable): 85 rpm | | 24 | 84 | | 106 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 174 | 176 | 178 | | 179 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | | | | | | | | | | | | | + 350831 [2376899][E](Custom_C): 01 19 <-targetPosition + 350832 [2376912][E](PTable): 90 rpm | 12 | 18 | 80 | | 104 | 108 | 117 | 124 | 137 | 142 | 145 | 150 | 155 | 167 | 169 | 170 | 172 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350833 [2376934][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 161 | 163 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350834 [2376960][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 350835 [2376992][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 350836 [2377012][E](PTable): Power Table Reset + 350837 [2377013][E](ERG_Mode): Proportional: 56.000000, Integral: 7.400000, Derivative: -1.000000 + 350838 [2377048][E](PTable): Success! + 350839 [2377755][E](PTable): Success! + 350840 [2377893][E](Custom_C): 01 19 <-targetPosition + 350841 [2378454][E](PTable): Success! + 350842 [2378905][E](Custom_C): 01 19 <-targetPosition + 350843 [2379155][E](PTable): Success! + 350844 [2379156][E](PTable): Clean Power Table + 350845 [2379156][E](PTable): Averaged Entry: watts=118.800003, cad=84.400002, targetPosition=1185.99998, (5)(4) + 350846 [2379167][E](PTable): cellValue: (106) wattDelta: (2.380953) cadDelta: (0.396825) allNeighborsPassed: (0) + 350847 [2379178][E](PTable): rightValue: (0.000000) leftValue: (106.503998) bottomValue: (104.488007) topValue: (0.000000) New averaged targetPosition: (105.496002) count: (2) + 350848 [2379189][E](PTable): Existing entry averaged (5)(4)(105), readings(11) + 350849 [2379698][E](Custom_C): 01 27 05 <-Power Tab Data + 350850 [2379705][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350851 [2379728][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 350852 [2379759][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 209 | 212 | 215 | 218 | 219 | 220 | 221 | 222 | | | | | | 224 | | 225 | 226 | | | | | | | | | | + 350853 [2379781][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 199 | 202 | 205 | 208 | 209 | | | | | | | 210 | 214 | 218 | 219 | | | | | | | | | | | | + 350854 [2379815][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 201 | 203 | | | | | 204 | | | 216 | | 224 | | | | | | | | | | | + 350855 [2379837][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | | | 186 | | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | 218 | 223 | 225 | | | | | | | | | | + 350856 [2379869][E](PTable): 85 rpm | | 24 | 84 | | 105 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 174 | 176 | 178 | | 179 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | | | | | | | | | | | | | + 350857 [2379890][E](PTable): 90 rpm | 12 | 18 | 80 | | 104 | 108 | 117 | 124 | 137 | 142 | 145 | 150 | 155 | 167 | 169 | 170 | 172 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350858 [2379937][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 161 | 163 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350859 [2379959][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 350860 [2379991][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 350861 [2380012][E](PTable): Power Table Reset + 350862 [2380228][E](PTable): Success! + 350863 [2380885][E](Custom_C): 01 2a <-hMin + 350864 [2380931][E](PTable): Success! + 350865 [2380942][E](Custom_C): 01 19 <-targetPosition + 350866 [2380976][E](Custom_C): 01 2b <-hMax + 350867 [2381634][E](PTable): Success! + 350868 [2381897][E](Custom_C): 01 19 <-targetPosition + 350869 [2382282][E](Custom_C): 01 25 <-Firmware Version + 350870 [2382335][E](PTable): Success! + 350871 [2382336][E](PTable): Clean Power Table + 350872 [2382336][E](PTable): Averaged Entry: watts=120.400002, cad=83.199997, targetPosition=1195.99998, (5)(4) + 350873 [2382349][E](PTable): cellValue: (105) wattDelta: (2.054795) cadDelta: (0.342466) allNeighborsPassed: (0) + 350874 [2382350][E](PTable): rightValue: (0.000000) leftValue: (104.805336) bottomValue: (99.743988) topValue: (0.000000) New averaged targetPosition: (102.274658) count: (2) + 350875 [2382371][E](PTable): Bottom failed at: (104) Target pos: (102.274658) Avg pos: (103) + 350876 [2382375][E](PTable): All test failed bottom (4)(4)(108), readings (11) + 350877 [2382385][E](PTable): WEIGHTED DOWNVOTING: Target Value: (102), NeighborValue: (104) + 350878 [2382396][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 350879 [2382396][E](PTable): PT failed (6)(4)(104), readings (11) + 350880 [2382409][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350881 [2382431][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350882 [2382463][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350883 [2382485][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350884 [2382508][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350885 [2382540][E](PTable): 80 rpm | | 58 | | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350886 [2382563][E](PTable): 85 rpm | | 24 | | | 105 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350887 [2382595][E](PTable): 90 rpm | | | | | 104 | 108 | 117 | 124 | 137 | 142 | 145 | 150 | 155 | 167 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350888 [2382617][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 350889 [2382649][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 350890 [2382672][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 350891 [2382703][E](PTable): Power Table Reset + 350892 [2382703][E](ERG_Mode): Proportional: 16.000000, Integral: 6.400000, Derivative: -0.600000 + 350893 [2382888][E](Custom_C): 01 19 <-targetPosition + 350894 [2383038][E](PTable): Success! + 350895 [2383740][E](PTable): Success! + 350896 [2383878][E](Custom_C): 01 19 <-targetPosition + 350897 [2384062][E](FTMS_SERVER): 05 59 01 -> ERG Mode Target: 345 Current: 120 Incline: 121.837997 + 350898 [2384069][E](Custom_C): 01 28 <-targetWatts + 350899 [2384442][E](PTable): Success! + 350900 [2384443][E](PTable): Lookup debug 300 X1 -3840 X2 80 Y1 90 Y2 -28072597855658832489169139049937346553876994564836862117658371403771055066555426859690436400329759714521683831737342949146297107947636215625790622980374528 + 350901 [2384455][E](PTable): Lookup used neighbors U 171 D 155 R2 165 + 350902 [2384466][E](PTable): Lookup used actual 160 R3 160 + 350903 [2384467][E](PTable): Lookup result: 345w 84cad 16200 + 350904 [2384478][E](ERG_Mode): SetPoint changed:345w PowerTable Result: 16200 + 350905 [2384484][E](PTable): Success! + 350906 [2384485][E](PTable): Clean Power Table + 350907 [2384485][E](PTable): Averaged Entry: watts=119.199997, cad=84.000000, targetPosition=1205.99998, (5)(4) + 350908 [2384496][E](PTable): cellValue: (105) wattDelta: (1.923077) cadDelta: (0.320513) allNeighborsPassed: (0) + 350909 [2384507][E](PTable): rightValue: (0.000000) leftValue: (105.416000) bottomValue: (101.880005) topValue: (0.000000) New averaged targetPosition: (103.648003) count: (2) + 350910 [2384519][E](PTable): Bottom failed at: (104) Target pos: (103.648003) Avg pos: (103) + 350911 [2384530][E](PTable): Current Position moved down is valid! Current position: 103.648003 + 350912 [2384531][E](PTable): Existing entry averaged (6)(4)(103), readings(11) + 350913 [2384890][E](Custom_C): 01 19 <-targetPosition + 350914 [2385084][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350915 [2385106][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 350916 [2385130][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 209 | 212 | 215 | 218 | 219 | 220 | 221 | 222 | | | | | | 224 | | 225 | 226 | | | | | | | | | | + 350917 [2385162][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 199 | 202 | 205 | 208 | 209 | | | | | | | 210 | 214 | 218 | 219 | | | | | | | | | | | | + 350918 [2385185][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 201 | 203 | | | | | 204 | | | 216 | | 224 | | | | | | | | | | | + 350919 [2385217][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | | | 186 | | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | 218 | 223 | 225 | | | | | | | | | | + 350920 [2385239][E](PTable): 85 rpm | | 24 | 84 | | 105 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 174 | 176 | 178 | | 179 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | | | | | | | | | | | | | + 350921 [2385272][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 145 | 150 | 155 | 167 | 169 | 170 | 172 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350922 [2385294][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 161 | 163 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350923 [2385326][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 350924 [2385348][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 350925 [2385380][E](PTable): Power Table Reset + 350926 [2385715][E](PTable): Success! + 350927 [2385881][E](Custom_C): 01 2a <-hMin + 350928 [2385925][E](Custom_C): 01 19 <-targetPosition + 350929 [2385971][E](Custom_C): 01 2b <-hMax + 350930 [2385994][E](Custom_C): 01 25 <-Firmware Version + 350931 [2386419][E](PTable): Power Table Reset + 350932 [2386893][E](Custom_C): 01 19 <-targetPosition + 350933 [2387124][E](PTable): Success! + 350934 [2387825][E](PTable): Success! + 350935 [2387826][E](ERG_Mode): Proportional: 44.000000, Integral: 7.100000, Derivative: -9.800000 + 350936 [2387882][E](Custom_C): 01 19 <-targetPosition + 350937 [2388526][E](PTable): Success! + 350938 [2388527][E](PTable): Using detected travel limits during homing + 350939 [2388895][E](Custom_C): 01 19 <-targetPosition + 350940 [2389229][E](PTable): Success! + 350941 [2389230][E](PTable): Clean Power Table + 350942 [2389231][E](PTable): Averaged Entry: watts=308.799988, cad=87.000000, targetPosition=1643.99994, (5)(10) + 350943 [2389242][E](PTable): cellValue: (152) wattDelta: (2.419356) cadDelta: (0.403226) allNeighborsPassed: (0) + 350944 [2389253][E](PTable): rightValue: (0.000000) leftValue: (148.362671) bottomValue: (156.959991) topValue: (0.000000) New averaged targetPosition: (152.661331) count: (2) + 350945 [2389264][E](PTable): Existing entry averaged (5)(10)(152), readings(3) + 350946 [2389798][E](Custom_C): 01 27 05 <-Power Tab Data + 350947 [2389804][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350948 [2389826][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 350949 [2389862][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 209 | 212 | 215 | 218 | 219 | 220 | 221 | 222 | | | | | | 224 | | 225 | 226 | | | | | | | | | | + 350950 [2389885][E](Custom_C): 01 19 <-targetPosition + 350951 [2389889][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 199 | 202 | 205 | 208 | 209 | | | | | | | 210 | 214 | 218 | 219 | | | | | | | | | | | | + 350952 [2389921][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 201 | 203 | | | | | 204 | | | 216 | | 224 | | | | | | | | | | | + 350953 [2389943][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | | | 186 | | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | 218 | 223 | 225 | | | | | | | | | | + 350954 [2389975][E](PTable): 85 rpm | | 24 | 84 | | 105 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 174 | 176 | 178 | | 179 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | | | | | | | | | | | | | + 350955 [2389997][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 145 | 150 | 155 | 167 | 169 | 170 | 172 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350956 [2390029][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 161 | 163 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350957 [2390051][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 350958 [2390082][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 350959 [2390103][E](PTable): Power Table Reset + 350960 [2390321][E](PTable): Success! + 350961 [2390910][E](Custom_C): 01 27 00 <-Power Tab Data + 350962 [2390942][E](Custom_C): 01 2a <-hMin + 350963 [2390987][E](Custom_C): 01 19 <-targetPosition + 350964 [2391026][E](PTable): Success! + 350965 [2391044][E](Custom_C): 01 27 01 <-Power Tab Data + 350966 [2391078][E](Custom_C): 01 2b <-hMax + 350967 [2391124][E](Custom_C): 01 27 02 <-Power Tab Data + 350968 [2391171][E](Custom_C): 01 27 03 <-Power Tab Data + 350969 [2391214][E](Custom_C): 01 27 04 <-Power Tab Data + 350970 [2391269][E](Custom_C): 01 27 05 <-Power Tab Data + 350971 [2391318][E](Custom_C): 01 27 06 <-Power Tab Data + 350972 [2391353][E](Custom_C): 01 27 07 <-Power Tab Data + 350973 [2391452][E](Custom_C): 01 27 08 <-Power Tab Data + 350974 [2391533][E](Custom_C): 01 27 09 <-Power Tab Data + 350975 [2391729][E](PTable): Success! + 350976 [2391922][E](Custom_C): 01 19 <-targetPosition + 350977 [2392431][E](PTable): Success! + 350978 [2392432][E](PTable): Clean Power Table + 350979 [2392433][E](PTable): Averaged Entry: watts=434.399994, cad=92.000000, targetPosition=1616.00006, (6)(14) + 350980 [2392444][E](PTable): Keep old targetPosition: (161.600006) + 350981 [2392444][E](PTable): Left failed at: (167) Target pos: (161.600006) Avg pos: (164) + 350982 [2392455][E](PTable): Current Position moved left was valid! Current position: 161.600006 + 350983 [2392466][E](PTable): Existing entry averaged (6)(13)(165), readings(4) + 350984 [2392878][E](Custom_C): 01 19 <-targetPosition + 350985 [2392984][E](PTable): Bottom failed at: (161) Target pos: (161.600006) Avg pos: (161) + 350986 [2392985][E](PTable): Was not in range failed bottom (8)(14)(161), readings (1) + 350987 [2392996][E](PTable): WEIGHTED DOWNVOTING: Target Value: (161), NeighborValue: (161) + 350988 [2392996][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 350989 [2393007][E](PTable): PT failed (8)(14)(161), readings (1) + 350990 [2393020][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 350991 [2393042][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 350992 [2393073][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 350993 [2393095][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 350994 [2393127][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 350995 [2393149][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 350996 [2393181][E](PTable): 85 rpm | | 24 | 84 | | 105 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 350997 [2393202][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 145 | 150 | 155 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 350998 [2393234][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 350999 [2393256][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351000 [2393288][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351001 [2393309][E](PTable): Power Table Reset + 351002 [2393611][E](PTable): Success! + 351003 [2393612][E](ERG_Mode): Proportional: -76.000000, Integral: -7.900000, Derivative: 6.400000 + 351004 [2393890][E](Custom_C): 01 19 <-targetPosition + 351005 [2394313][E](PTable): Success! + 351006 [2394880][E](Custom_C): 01 19 <-targetPosition + 351007 [2395016][E](PTable): Success! + 351008 [2395717][E](PTable): Success! + 351009 [2395718][E](PTable): Clean Power Table + 351010 [2395718][E](PTable): Averaged Entry: watts=363.200012, cad=92.599998, targetPosition=1548.00003, (7)(12) + 351011 [2395730][E](PTable): cellValue: (152) wattDelta: (10.714274) cadDelta: (1.785712) allNeighborsPassed: (1) + 351012 [2395741][E](PTable): rightValue: (152.298676) leftValue: (151.701324) bottomValue: (150.655991) topValue: (153.344009) New averaged targetPosition: (152.000000) count: (4) + 351013 [2395752][E](PTable): Existing entry averaged (7)(12)(152), readings(11) + 351014 [2395893][E](Custom_C): 01 2a <-hMin + 351015 [2395937][E](Custom_C): 01 19 <-targetPosition + 351016 [2396005][E](Custom_C): 01 2b <-hMax + 351017 [2396293][E](Custom_C): 01 27 07 <-Power Tab Data + 351018 [2396300][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351019 [2396322][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351020 [2396354][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351021 [2396376][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351022 [2396409][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351023 [2396431][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351024 [2396453][E](PTable): 85 rpm | | 24 | 84 | | 105 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351025 [2396485][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 145 | 150 | 155 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351026 [2396517][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351027 [2396539][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351028 [2396570][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351029 [2396591][E](PTable): Power Table Reset + 351030 [2396609][E](PTable): Success! + 351031 [2396883][E](Custom_C): 01 19 <-targetPosition + 351032 [2397314][E](PTable): Success! + 351033 [2397895][E](Custom_C): 01 19 <-targetPosition + 351034 [2398019][E](PTable): Success! + 351035 [2398720][E](PTable): Success! + 351036 [2398721][E](PTable): Clean Power Table + 351037 [2398721][E](PTable): Averaged Entry: watts=359.200012, cad=94.000000, targetPosition=1531.99997, (7)(12) + 351038 [2398732][E](PTable): cellValue: (152) wattDelta: (25.000063) cadDelta: (4.166677) allNeighborsPassed: (1) + 351039 [2398743][E](PTable): rightValue: (151.968002) leftValue: (152.031998) bottomValue: (151.759995) topValue: (152.240005) New averaged targetPosition: (152.000000) count: (4) + 351040 [2398754][E](PTable): Existing entry averaged (7)(12)(152), readings(11) + 351041 [2398896][E](Custom_C): 01 19 <-targetPosition + 351042 [2399300][E](Custom_C): 01 27 07 <-Power Tab Data + 351043 [2399308][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351044 [2399330][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351045 [2399364][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351046 [2399386][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351047 [2399417][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351048 [2399439][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351049 [2399471][E](PTable): 85 rpm | | 24 | 84 | | 105 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351050 [2399493][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 145 | 150 | 155 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351051 [2399524][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351052 [2399546][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351053 [2399579][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351054 [2399600][E](PTable): Power Table Reset + 351055 [2399600][E](ERG_Mode): Proportional: -28.000000, Integral: -6.700000, Derivative: 0.000000 + 351056 [2399842][E](PTable): Success! + 351057 [2399899][E](Custom_C): 01 19 <-targetPosition + 351058 [2400543][E](PTable): Success! + 351059 [2400888][E](Custom_C): 01 2a <-hMin + 351060 [2400955][E](Custom_C): 01 19 <-targetPosition + 351061 [2401046][E](Custom_C): 01 2b <-hMax + 351062 [2401246][E](PTable): Success! + 351063 [2401878][E](Custom_C): 01 19 <-targetPosition + 351064 [2401948][E](PTable): Success! + 351065 [2401949][E](PTable): Clean Power Table + 351066 [2401950][E](PTable): Averaged Entry: watts=324.000000, cad=92.199997, targetPosition=1530.00000, (6)(11) + 351067 [2401962][E](PTable): cellValue: (150) wattDelta: (10.000000) cadDelta: (1.666667) allNeighborsPassed: (1) + 351068 [2401964][E](PTable): rightValue: (149.399994) leftValue: (150.600006) bottomValue: (151.319992) topValue: (148.680008) New averaged targetPosition: (150.000000) count: (4) + 351069 [2401985][E](PTable): Existing entry averaged (6)(11)(150), readings(11) + 351070 [2402261][E](Custom_C): 01 25 <-Firmware Version + 351071 [2402506][E](Custom_C): 01 27 06 <-Power Tab Data + 351072 [2402511][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351073 [2402533][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351074 [2402566][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351075 [2402588][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351076 [2402619][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351077 [2402642][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351078 [2402674][E](PTable): 85 rpm | | 24 | 84 | | 105 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351079 [2402696][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 145 | 150 | 155 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351080 [2402728][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351081 [2402750][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351082 [2402783][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351083 [2402803][E](PTable): Power Table Reset + 351084 [2402831][E](PTable): Success! + 351085 [2402890][E](Custom_C): 01 19 <-targetPosition + 351086 [2403533][E](PTable): Success! + 351087 [2403892][E](Custom_C): 01 19 <-targetPosition + 351088 [2404238][E](PTable): Success! + 351089 [2404881][E](Custom_C): 01 19 <-targetPosition + 351090 [2404942][E](PTable): Success! + 351091 [2404943][E](PTable): Clean Power Table + 351092 [2404943][E](PTable): Averaged Entry: watts=332.799988, cad=91.199997, targetPosition=1551.99997, (6)(11) + 351093 [2404954][E](PTable): cellValue: (150) wattDelta: (5.769234) cadDelta: (0.961539) allNeighborsPassed: (0) + 351094 [2404965][E](PTable): rightValue: (0.000000) leftValue: (149.514664) bottomValue: (151.248001) topValue: (148.751999) New averaged targetPosition: (149.838211) count: (3) + 351095 [2404976][E](PTable): Existing entry averaged (6)(11)(149), readings(11) + 351096 [2405488][E](Custom_C): 01 27 06 <-Power Tab Data + 351097 [2405493][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351098 [2405515][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351099 [2405547][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351100 [2405568][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351101 [2405601][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351102 [2405624][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351103 [2405656][E](PTable): 85 rpm | | 24 | 84 | | 105 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351104 [2405678][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 145 | 149 | 155 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351105 [2405711][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 152 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351106 [2405733][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351107 [2405765][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351108 [2405786][E](PTable): Power Table Reset + 351109 [2405796][E](ERG_Mode): Proportional: -44.000000, Integral: 2.600000, Derivative: -2.000000 + 351110 [2405896][E](Custom_C): 01 27 00 <-Power Tab Data + 351111 [2405951][E](Custom_C): 01 2a <-hMin + 351112 [2405995][E](Custom_C): 01 19 <-targetPosition + 351113 [2406098][E](Custom_C): 01 27 01 <-Power Tab Data + 351114 [2406154][E](Custom_C): 01 2b <-hMax + 351115 [2406187][E](PTable): Success! + 351116 [2406210][E](Custom_C): 01 27 02 <-Power Tab Data + 351117 [2406290][E](Custom_C): 01 27 03 <-Power Tab Data + 351118 [2406369][E](Custom_C): 01 27 04 <-Power Tab Data + 351119 [2406412][E](Custom_C): 01 27 05 <-Power Tab Data + 351120 [2406469][E](Custom_C): 01 27 06 <-Power Tab Data + 351121 [2406514][E](Custom_C): 01 27 07 <-Power Tab Data + 351122 [2406569][E](Custom_C): 01 27 08 <-Power Tab Data + 351123 [2406604][E](Custom_C): 01 27 09 <-Power Tab Data + 351124 [2406648][E](Custom_C): 01 25 <-Firmware Version + 351125 [2406887][E](PTable): Success! + 351126 [2406895][E](Custom_C): 01 19 <-targetPosition + 351127 [2407589][E](PTable): Success! + 351128 [2407853][E](BLE_Client): HRM battery updated 100 + 351129 [2407897][E](Custom_C): 01 19 <-targetPosition + 351130 [2408294][E](PTable): Success! + 351131 [2408295][E](PTable): Clean Power Table + 351132 [2408295][E](PTable): Averaged Entry: watts=353.600006, cad=92.800003, targetPosition=1553.99994, (7)(12) + 351133 [2408306][E](PTable): cellValue: (152) wattDelta: (8.823545) cadDelta: (1.470591) allNeighborsPassed: (0) + 351134 [2408317][E](PTable): rightValue: (151.274673) leftValue: (152.725327) bottomValue: (150.503998) topValue: (0.000000) New averaged targetPosition: (151.501328) count: (3) + 351135 [2408328][E](PTable): Existing entry averaged (7)(12)(151), readings(11) + 351136 [2408834][E](Custom_C): 01 27 07 <-Power Tab Data + 351137 [2408839][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351138 [2408861][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351139 [2408893][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351140 [2408930][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351141 [2408952][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351142 [2408984][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351143 [2409006][E](PTable): 85 rpm | | 24 | 84 | | 105 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351144 [2409038][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 145 | 149 | 155 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351145 [2409060][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 151 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351146 [2409092][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351147 [2409114][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351148 [2409145][E](PTable): Power Table Reset + 351149 [2409368][E](PTable): Success! + 351150 [2409888][E](Custom_C): 01 19 <-targetPosition + 351151 [2410072][E](PTable): Success! + 351152 [2410773][E](PTable): Success! + 351153 [2410899][E](Custom_C): 01 2a <-hMin + 351154 [2410922][E](Custom_C): 01 19 <-targetPosition + 351155 [2410956][E](Custom_C): 01 2b <-hMax + 351156 [2411475][E](PTable): Success! + 351157 [2411476][E](PTable): Clean Power Table + 351158 [2411476][E](PTable): Averaged Entry: watts=355.200012, cad=92.199997, targetPosition=1543.99994, (6)(12) + 351159 [2411487][E](PTable): cellValue: (155) wattDelta: (49.999493) cadDelta: (8.333248) allNeighborsPassed: (1) + 351160 [2411490][E](PTable): rightValue: (153.703979) leftValue: (153.895996) bottomValue: (154.063995) topValue: (153.535980) New averaged targetPosition: (153.799988) count: (4) + 351161 [2411511][E](PTable): Existing entry averaged (6)(12)(154), readings(4) + 351162 [2411890][E](Custom_C): 01 19 <-targetPosition + 351163 [2412037][E](Custom_C): 01 27 06 <-Power Tab Data + 351164 [2412042][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351165 [2412064][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351166 [2412096][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351167 [2412119][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351168 [2412150][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351169 [2412173][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351170 [2412206][E](PTable): 85 rpm | | 24 | 84 | | 105 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351171 [2412227][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 145 | 149 | 154 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351172 [2412259][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 151 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351173 [2412282][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351174 [2412314][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351175 [2412335][E](PTable): Power Table Reset + 351176 [2412345][E](ERG_Mode): Proportional: 68.000000, Integral: -1.600000, Derivative: 2.400000 + 351177 [2412363][E](PTable): Success! + 351178 [2412892][E](Custom_C): 01 19 <-targetPosition + 351179 [2413066][E](PTable): Success! + 351180 [2413768][E](PTable): Success! + 351181 [2413877][E](FTMS_SERVER): 05 82 00 -> ERG Mode Target: 130 Current: 332 Incline: 153.949997 + 351182 [2413881][E](Custom_C): 01 19 <-targetPosition + 351183 [2413888][E](Custom_C): 01 28 <-targetWatts + 351184 [2414472][E](PTable): Success! + 351185 [2414473][E](PTable): Clean Power Table + 351186 [2414473][E](PTable): Averaged Entry: watts=343.200012, cad=91.199997, targetPosition=1536.00006, (6)(11) + 351187 [2414485][E](PTable): cellValue: (149) wattDelta: (6.521730) cadDelta: (1.086955) allNeighborsPassed: (1) + 351188 [2414495][E](PTable): rightValue: (151.024002) leftValue: (146.975998) bottomValue: (150.104004) topValue: (147.895996) New averaged targetPosition: (149.000000) count: (4) + 351189 [2414506][E](PTable): Existing entry averaged (6)(11)(149), readings(11) + 351190 [2414882][E](Custom_C): 01 19 <-targetPosition + 351191 [2415031][E](Custom_C): 01 27 06 <-Power Tab Data + 351192 [2415036][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351193 [2415058][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351194 [2415090][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351195 [2415111][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351196 [2415143][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351197 [2415165][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351198 [2415197][E](PTable): 85 rpm | | 24 | 84 | | 105 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351199 [2415229][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 145 | 149 | 154 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351200 [2415251][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 151 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351201 [2415283][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351202 [2415305][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351203 [2415336][E](PTable): Power Table Reset + 351204 [2415337][E](PTable): Lookup debug 60 X1 150 X2 85 Y1 95 Y2 0 + 351205 [2415338][E](PTable): Lookup used neighbors L 80 R 108 R1 102 + 351206 [2415349][E](PTable): Lookup used neighbors U 105 D 102 R2 103 + 351207 [2415349][E](PTable): Lookup used actual 103 R3 103 + 351208 [2415360][E](PTable): Lookup result: 130w 92cad 10200 + 351209 [2415360][E](ERG_Mode): SetPoint changed:130w PowerTable Result: 10200 + 351210 [2415371][E](ERG_Mode): Capping ERG seek time to 5 seconds + 351211 [2415719][E](PTable): Success! + 351212 [2415896][E](Custom_C): 01 2a <-hMin + 351213 [2415939][E](Custom_C): 01 19 <-targetPosition + 351214 [2415997][E](Custom_C): 01 2b <-hMax + 351215 [2416424][E](PTable): Success! + 351216 [2416908][E](Custom_C): 01 19 <-targetPosition + 351217 [2417127][E](PTable): Success! + 351218 [2417830][E](PTable): Success! + 351219 [2417831][E](PTable): Clean Power Table + 351220 [2417831][E](PTable): Averaged Entry: watts=296.399994, cad=86.800003, targetPosition=1478.00003, (5)(10) + 351221 [2417836][E](PTable): cellValue: (152) wattDelta: (7.142862) cadDelta: (1.190477) allNeighborsPassed: (1) + 351222 [2417847][E](PTable): rightValue: (143.096008) leftValue: (144.104004) bottomValue: (145.112015) topValue: (142.087997) New averaged targetPosition: (143.600006) count: (4) + 351223 [2417868][E](PTable): Left failed at: (145) Target pos: (143.600006) Avg pos: (144) + 351224 [2417869][E](PTable): All test failed left (5)(9)(145), readings (11) + 351225 [2417879][E](PTable): WEIGHTED DOWNVOTING: Target Value: (143), NeighborValue: (145) + 351226 [2417890][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 351227 [2417890][E](PTable): PT failed (5)(9)(145), readings (11) + 351228 [2417901][E](PTable): Bottom failed at: (145) Target pos: (143.600006) Avg pos: (144) + 351229 [2417902][E](PTable): Current Position moved down is valid! Current position: 143.600006 + 351230 [2417913][E](PTable): Existing entry averaged (6)(10)(144), readings(11) + 351231 [2417924][E](Custom_C): 01 19 <-targetPosition + 351232 [2418444][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351233 [2418466][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351234 [2418498][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351235 [2418520][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351236 [2418552][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351237 [2418573][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351238 [2418606][E](PTable): 85 rpm | | 24 | 84 | | 105 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351239 [2418628][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 154 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351240 [2418661][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 133 | 141 | 142 | 145 | 151 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351241 [2418682][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 128 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351242 [2418716][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351243 [2418736][E](PTable): Power Table Reset + 351244 [2418737][E](ERG_Mode): Proportional: -520.000000, Integral: -19.000000, Derivative: 5.000000 + 351245 [2418766][E](PTable): Success! + 351246 [2418888][E](Custom_C): 01 19 <-targetPosition + 351247 [2419469][E](PTable): Success! + 351248 [2419900][E](Custom_C): 01 19 <-targetPosition + 351249 [2420174][E](PTable): Success! + 351250 [2420878][E](PTable): Success! + 351251 [2420879][E](PTable): Clean Power Table + 351252 [2420879][E](PTable): Averaged Entry: watts=238.000000, cad=87.599998, targetPosition=1348.00003, (6)(8) + 351253 [2420891][E](PTable): cellValue: (137) wattDelta: (13.636382) cadDelta: (2.272730) allNeighborsPassed: (1) + 351254 [2420903][E](PTable): rightValue: (132.453339) leftValue: (132.746674) bottomValue: (131.544006) topValue: (133.656006) New averaged targetPosition: (132.600006) count: (4) + 351255 [2420949][E](PTable): Bottom failed at: (133) Target pos: (132.600006) Avg pos: (132) + 351256 [2420950][E](PTable): Current Position moved down is valid! Current position: 132.600006 + 351257 [2420961][E](PTable): Existing entry averaged (7)(8)(132), readings(2) + 351258 [2420981][E](Custom_C): 01 2a <-hMin + 351259 [2421002][E](Custom_C): 01 19 <-targetPosition + 351260 [2421048][E](Custom_C): 01 27 01 <-Power Tab Data + 351261 [2421093][E](Custom_C): 01 2b <-hMax + 351262 [2421149][E](Custom_C): 01 27 02 <-Power Tab Data + 351263 [2421195][E](Custom_C): 01 27 03 <-Power Tab Data + 351264 [2421239][E](Custom_C): 01 27 04 <-Power Tab Data + 351265 [2421276][E](Custom_C): 01 27 05 <-Power Tab Data + 351266 [2421330][E](Custom_C): 01 27 06 <-Power Tab Data + 351267 [2421363][E](Custom_C): 01 27 07 <-Power Tab Data + 351268 [2421409][E](Custom_C): 01 27 08 <-Power Tab Data + 351269 [2421453][E](Custom_C): 01 27 09 <-Power Tab Data + 351270 [2421584][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351271 [2421606][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351272 [2421638][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351273 [2421659][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351274 [2421692][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351275 [2421713][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351276 [2421745][E](PTable): 85 rpm | | 24 | 84 | | 105 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351277 [2421766][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 154 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351278 [2421799][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 151 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351279 [2421821][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351280 [2421853][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351281 [2421874][E](PTable): Power Table Reset + 351282 [2421903][E](Custom_C): 01 19 <-targetPosition + 351283 [2422262][E](Custom_C): 01 25 <-Firmware Version + 351284 [2422270][E](PTable): Success! + 351285 [2422881][E](Custom_C): 01 19 <-targetPosition + 351286 [2422971][E](PTable): Success! + 351287 [2423672][E](PTable): Success! + 351288 [2423882][E](Custom_C): 01 19 <-targetPosition + 351289 [2424374][E](PTable): Success! + 351290 [2424376][E](PTable): Clean Power Table + 351291 [2424376][E](PTable): Averaged Entry: watts=193.600006, cad=86.400002, targetPosition=1275.99998, (5)(6) + 351292 [2424389][E](PTable): cellValue: (124) wattDelta: (8.333337) cadDelta: (1.388889) allNeighborsPassed: (1) + 351293 [2424390][E](PTable): rightValue: (125.632004) leftValue: (122.367996) bottomValue: (125.008003) topValue: (122.991997) New averaged targetPosition: (124.000000) count: (4) + 351294 [2424411][E](PTable): Existing entry averaged (5)(6)(124), readings(11) + 351295 [2424895][E](Custom_C): 01 19 <-targetPosition + 351296 [2424966][E](Custom_C): 01 27 05 <-Power Tab Data + 351297 [2424972][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351298 [2424994][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351299 [2425026][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351300 [2425048][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351301 [2425081][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351302 [2425103][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351303 [2425135][E](PTable): 85 rpm | | 24 | 84 | | 105 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351304 [2425156][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 154 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351305 [2425188][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 151 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351306 [2425211][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351307 [2425242][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351308 [2425263][E](PTable): Power Table Reset + 351309 [2425274][E](ERG_Mode): Proportional: -200.000000, Integral: -11.000000, Derivative: 4.200000 + 351310 [2425293][E](PTable): Success! + 351311 [2425896][E](Custom_C): 01 2a <-hMin + 351312 [2425929][E](Custom_C): 01 19 <-targetPosition + 351313 [2425952][E](Custom_C): 01 2b <-hMax + 351314 [2425997][E](PTable): Success! + 351315 [2426020][E](Custom_C): 01 25 <-Firmware Version + 351316 [2426698][E](PTable): Success! + 351317 [2426886][E](Custom_C): 01 19 <-targetPosition + 351318 [2427399][E](PTable): Success! + 351319 [2427400][E](PTable): Clean Power Table + 351320 [2427400][E](PTable): Averaged Entry: watts=151.199997, cad=86.199997, targetPosition=1238.00003, (5)(5) + 351321 [2427412][E](PTable): cellValue: (111) wattDelta: (2.343750) cadDelta: (0.390625) allNeighborsPassed: (0) + 351322 [2427423][E](PTable): rightValue: (111.512001) leftValue: (110.487999) bottomValue: (114.071991) topValue: (0.000000) New averaged targetPosition: (112.023994) count: (3) + 351323 [2427436][E](PTable): Existing entry averaged (5)(5)(111), readings(8) + 351324 [2427887][E](Custom_C): 01 19 <-targetPosition + 351325 [2427950][E](Custom_C): 01 27 05 <-Power Tab Data + 351326 [2427955][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351327 [2427978][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351328 [2428010][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351329 [2428035][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351330 [2428067][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351331 [2428088][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351332 [2428120][E](PTable): 85 rpm | | 24 | 84 | | 105 | 111 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351333 [2428142][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 154 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351334 [2428174][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 151 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351335 [2428196][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351336 [2428227][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351337 [2428249][E](PTable): Power Table Reset + 351338 [2428511][E](PTable): Success! + 351339 [2428878][E](Custom_C): 01 19 <-targetPosition + 351340 [2429213][E](PTable): Success! + 351341 [2429214][E](PTable): Using detected travel limits during homing + 351342 [2429890][E](Custom_C): 01 19 <-targetPosition + 351343 [2429914][E](PTable): Success! + 351344 [2430619][E](PTable): Success! + 351345 [2430620][E](PTable): Clean Power Table + 351346 [2430620][E](PTable): Averaged Entry: watts=142.800003, cad=83.400002, targetPosition=1220.00000, (5)(5) + 351347 [2430632][E](PTable): cellValue: (111) wattDelta: (2.727273) cadDelta: (0.454545) allNeighborsPassed: (0) + 351348 [2430643][E](PTable): rightValue: (108.360001) leftValue: (113.639999) bottomValue: (107.480003) topValue: (0.000000) New averaged targetPosition: (109.826668) count: (3) + 351349 [2430654][E](PTable): Existing entry averaged (5)(5)(110), readings(9) + 351350 [2430880][E](Custom_C): 01 2a <-hMin + 351351 [2430925][E](Custom_C): 01 19 <-targetPosition + 351352 [2430947][E](Custom_C): 01 2b <-hMax + 351353 [2431191][E](Custom_C): 01 27 05 <-Power Tab Data + 351354 [2431197][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351355 [2431220][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351356 [2431253][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351357 [2431274][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351358 [2431306][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351359 [2431328][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351360 [2431360][E](PTable): 85 rpm | | 24 | 84 | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351361 [2431382][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 154 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351362 [2431414][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 151 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351363 [2431436][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351364 [2431467][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351365 [2431691][E](PTable): Writing File: /PowerTable.txt + 351366 [2431892][E](Custom_C): 01 19 <-targetPosition + 351367 [2432067][E](PTable): Power table saved successfully with 92 readings + 351368 [2432068][E](PTable): Power Table Reset + 351369 [2432068][E](ERG_Mode): Proportional: -8.000000, Integral: -4.600000, Derivative: -1.800000 + 351370 [2432397][E](PTable): Success! + 351371 [2432905][E](Custom_C): 01 19 <-targetPosition + 351372 [2433102][E](PTable): Success! + 351373 [2433805][E](PTable): Success! + 351374 [2433895][E](Custom_C): 01 19 <-targetPosition + 351375 [2434508][E](PTable): Success! + 351376 [2434509][E](PTable): Clean Power Table + 351377 [2434509][E](PTable): Averaged Entry: watts=126.000000, cad=81.000000, targetPosition=1225.99998, (4)(4) + 351378 [2434520][E](PTable): cellValue: (108) wattDelta: (2.054795) cadDelta: (0.342466) allNeighborsPassed: (0) + 351379 [2434531][E](PTable): rightValue: (0.000000) leftValue: (105.080002) bottomValue: (110.919998) topValue: (0.000000) New averaged targetPosition: (108.000000) count: (2) + 351380 [2434543][E](PTable): Existing entry averaged (4)(4)(108), readings(11) + 351381 [2434886][E](Custom_C): 01 19 <-targetPosition + 351382 [2435075][E](Custom_C): 01 27 04 <-Power Tab Data + 351383 [2435080][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351384 [2435103][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351385 [2435136][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351386 [2435157][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351387 [2435189][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351388 [2435211][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351389 [2435243][E](PTable): 85 rpm | | 24 | 84 | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351390 [2435265][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 154 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351391 [2435298][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 151 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351392 [2435319][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351393 [2435351][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351394 [2435372][E](PTable): Power Table Reset + 351395 [2435399][E](PTable): Success! + 351396 [2435913][E](Custom_C): 01 27 00 <-Power Tab Data + 351397 [2435966][E](Custom_C): 01 2a <-hMin + 351398 [2435987][E](Custom_C): 01 19 <-targetPosition + 351399 [2436089][E](Custom_C): 01 27 01 <-Power Tab Data + 351400 [2436103][E](PTable): Success! + 351401 [2436111][E](Custom_C): 01 2b <-hMax + 351402 [2436203][E](Custom_C): 01 27 02 <-Power Tab Data + 351403 [2436270][E](Custom_C): 01 27 03 <-Power Tab Data + 351404 [2436304][E](Custom_C): 01 27 04 <-Power Tab Data + 351405 [2436394][E](Custom_C): 01 27 05 <-Power Tab Data + 351406 [2436450][E](Custom_C): 01 27 06 <-Power Tab Data + 351407 [2436484][E](Custom_C): 01 27 07 <-Power Tab Data + 351408 [2436528][E](Custom_C): 01 27 08 <-Power Tab Data + 351409 [2436573][E](Custom_C): 01 27 09 <-Power Tab Data + 351410 [2436807][E](PTable): Success! + 351411 [2436888][E](Custom_C): 01 19 <-targetPosition + 351412 [2437510][E](PTable): Success! + 351413 [2437511][E](PTable): Clean Power Table + 351414 [2437511][E](PTable): Averaged Entry: watts=131.600006, cad=82.400002, targetPosition=1228.00003, (4)(4) + 351415 [2437523][E](PTable): cellValue: (108) wattDelta: (2.027027) cadDelta: (0.337838) allNeighborsPassed: (0) + 351416 [2437533][E](PTable): rightValue: (0.000000) leftValue: (102.277328) bottomValue: (115.104004) topValue: (0.000000) New averaged targetPosition: (108.690666) count: (2) + 351417 [2437544][E](PTable): Existing entry averaged (4)(4)(108), readings(11) + 351418 [2437878][E](Custom_C): 01 19 <-targetPosition + 351419 [2438101][E](Custom_C): 01 27 04 <-Power Tab Data + 351420 [2438106][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351421 [2438129][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351422 [2438160][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351423 [2438183][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351424 [2438216][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351425 [2438237][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351426 [2438269][E](PTable): 85 rpm | | 24 | 84 | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351427 [2438292][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 154 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351428 [2438325][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 151 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351429 [2438347][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351430 [2438369][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351431 [2438400][E](PTable): Power Table Reset + 351432 [2438401][E](ERG_Mode): Proportional: -16.000000, Integral: -3.200000, Derivative: -2.200000 + 351433 [2438653][E](PTable): Success! + 351434 [2438912][E](Custom_C): 01 19 <-targetPosition + 351435 [2439355][E](PTable): Success! + 351436 [2439880][E](Custom_C): 01 19 <-targetPosition + 351437 [2440058][E](PTable): Success! + 351438 [2440762][E](PTable): Success! + 351439 [2440763][E](PTable): Clean Power Table + 351440 [2440763][E](PTable): Averaged Entry: watts=116.800003, cad=80.800003, targetPosition=1231.99997, (4)(4) + 351441 [2440775][E](PTable): cellValue: (108) wattDelta: (1.973685) cadDelta: (0.328947) allNeighborsPassed: (0) + 351442 [2440786][E](PTable): rightValue: (0.000000) leftValue: (109.621330) bottomValue: (110.432007) topValue: (0.000000) New averaged targetPosition: (110.026672) count: (2) + 351443 [2440797][E](PTable): Existing entry averaged (4)(4)(108), readings(11) + 351444 [2440882][E](Custom_C): 01 2a <-hMin + 351445 [2440914][E](Custom_C): 01 19 <-targetPosition + 351446 [2440983][E](Custom_C): 01 2b <-hMax + 351447 [2441360][E](Custom_C): 01 27 04 <-Power Tab Data + 351448 [2441365][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351449 [2441387][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351450 [2441420][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351451 [2441444][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351452 [2441476][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351453 [2441499][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351454 [2441521][E](PTable): 85 rpm | | 24 | 84 | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351455 [2441555][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 154 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351456 [2441577][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 151 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351457 [2441609][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351458 [2441631][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351459 [2441663][E](PTable): Power Table Reset + 351460 [2441680][E](PTable): Success! + 351461 [2441886][E](Custom_C): 01 19 <-targetPosition + 351462 [2442276][E](Custom_C): 01 25 <-Firmware Version + 351463 [2442381][E](PTable): Success! + 351464 [2442895][E](Custom_C): 01 19 <-targetPosition + 351465 [2443087][E](PTable): Success! + 351466 [2443707][E](FTMS_SERVER): 05 77 01 -> ERG Mode Target: 375 Current: 148 Incline: 123.275993 + 351467 [2443716][E](Custom_C): 01 28 <-targetWatts + 351468 [2443789][E](PTable): Success! + 351469 [2443790][E](PTable): Clean Power Table + 351470 [2443790][E](PTable): Averaged Entry: watts=150.399994, cad=79.599998, targetPosition=1234.00002, (4)(5) + 351471 [2443804][E](PTable): cellValue: (120) wattDelta: (8.823525) cadDelta: (1.470588) allNeighborsPassed: (1) + 351472 [2443806][E](PTable): rightValue: (120.045334) leftValue: (119.954666) bottomValue: (119.727997) topValue: (120.272003) New averaged targetPosition: (120.000000) count: (4) + 351473 [2443827][E](PTable): Existing entry averaged (4)(5)(120), readings(11) + 351474 [2443884][E](Custom_C): 01 19 <-targetPosition + 351475 [2444339][E](Custom_C): 01 27 04 <-Power Tab Data + 351476 [2444345][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351477 [2444367][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351478 [2444399][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351479 [2444421][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351480 [2444453][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351481 [2444475][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351482 [2444507][E](PTable): 85 rpm | | 24 | 84 | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351483 [2444529][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 154 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351484 [2444560][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 151 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351485 [2444582][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351486 [2444615][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351487 [2444636][E](PTable): Power Table Reset + 351488 [2444647][E](PTable): Lookup debug 360 X1 420 X2 75 Y1 85 Y2 3 + 351489 [2444648][E](PTable): Lookup used neighbors L 171 R 184 R1 174 + 351490 [2444659][E](PTable): Lookup used neighbors U 190 D 172 R2 179 + 351491 [2444659][E](PTable): Lookup used actual 181 R3 181 + 351492 [2444659][E](PTable): Lookup result: 375w 81cad 17800 + 351493 [2444670][E](ERG_Mode): SetPoint changed:375w PowerTable Result: 17800 + 351494 [2444670][E](ERG_Mode): Capping ERG seek time to 5 seconds + 351495 [2444898][E](Custom_C): 01 19 <-targetPosition + 351496 [2445012][E](PTable): Success! + 351497 [2445013][E](ERG_Mode): Proportional: 876.000000, Integral: 20.900000, Derivative: 21.300001 + 351498 [2445717][E](PTable): Success! + 351499 [2445887][E](Custom_C): 01 2a <-hMin + 351500 [2445921][E](Custom_C): 01 19 <-targetPosition + 351501 [2445978][E](Custom_C): 01 2b <-hMax + 351502 [2446024][E](Custom_C): 01 25 <-Firmware Version + 351503 [2446419][E](PTable): Success! + 351504 [2446900][E](Custom_C): 01 19 <-targetPosition + 351505 [2447124][E](PTable): Success! + 351506 [2447124][E](PTable): Clean Power Table + 351507 [2447125][E](PTable): Averaged Entry: watts=166.399994, cad=87.400002, targetPosition=1303.99994, (5)(6) + 351508 [2447137][E](PTable): cellValue: (124) wattDelta: (4.687504) cadDelta: (0.781251) allNeighborsPassed: (1) + 351509 [2447148][E](PTable): rightValue: (121.098671) leftValue: (126.901329) bottomValue: (127.071999) topValue: (120.928001) New averaged targetPosition: (124.000000) count: (4) + 351510 [2447159][E](PTable): Existing entry averaged (5)(6)(124), readings(11) + 351511 [2447669][E](Custom_C): 01 27 05 <-Power Tab Data + 351512 [2447675][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351513 [2447699][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351514 [2447731][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351515 [2447753][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351516 [2447785][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351517 [2447808][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351518 [2447841][E](PTable): 85 rpm | | 24 | 84 | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351519 [2447862][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 154 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351520 [2447893][E](Custom_C): 01 19 <-targetPosition + 351521 [2447901][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 151 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351522 [2447924][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351523 [2447956][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351524 [2447976][E](PTable): Power Table Reset + 351525 [2447995][E](PTable): Success! + 351526 [2448698][E](PTable): Success! + 351527 [2448880][E](Custom_C): 01 19 <-targetPosition + 351528 [2449400][E](PTable): Success! + 351529 [2449881][E](Custom_C): 01 19 <-targetPosition + 351530 [2450104][E](PTable): Success! + 351531 [2450105][E](PTable): Clean Power Table + 351532 [2450105][E](PTable): Averaged Entry: watts=287.200012, cad=94.800003, targetPosition=1416.00006, (7)(10) + 351533 [2450117][E](PTable): cellValue: (142) wattDelta: (75.001144) cadDelta: (12.500191) allNeighborsPassed: (0) + 351534 [2450127][E](PTable): rightValue: (141.029343) leftValue: (0.000000) bottomValue: (0.000000) topValue: (141.216019) New averaged targetPosition: (141.122681) count: (2) + 351535 [2450139][E](PTable): Left failed at: (141) Target pos: (141.122681) Avg pos: (141) + 351536 [2450149][E](PTable): Was not in range failed left (7)(9)(141), readings (11) + 351537 [2450150][E](PTable): WEIGHTED DOWNVOTING: Target Value: (141), NeighborValue: (141) + 351538 [2450160][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 351539 [2450171][E](PTable): PT failed (7)(9)(141), readings (11) + 351540 [2450172][E](PTable): Bottom failed at: (141) Target pos: (141.122681) Avg pos: (141) + 351541 [2450183][E](PTable): Was not in range failed bottom (8)(10)(141), readings (8) + 351542 [2450183][E](PTable): WEIGHTED DOWNVOTING: Target Value: (141), NeighborValue: (141) + 351543 [2450193][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 351544 [2450204][E](PTable): PT failed (8)(10)(141), readings (8) + 351545 [2450206][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351546 [2450228][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 351547 [2450260][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351548 [2450282][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351549 [2450313][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351550 [2450345][E](PTable): 80 rpm | | 58 | | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 351551 [2450368][E](PTable): 85 rpm | | 24 | | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351552 [2450390][E](PTable): 90 rpm | | | | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 154 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 351553 [2450422][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 151 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351554 [2450444][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 351555 [2450476][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 351556 [2450497][E](PTable): Power Table Reset + 351557 [2450508][E](ERG_Mode): Proportional: 380.000000, Integral: 15.500000, Derivative: 1.200000 + 351558 [2450831][E](PTable): Success! + 351559 [2450921][E](Custom_C): 01 27 00 <-Power Tab Data + 351560 [2450961][E](Custom_C): 01 2a <-hMin + 351561 [2451040][E](Custom_C): 01 19 <-targetPosition + 351562 [2451077][E](Custom_C): 01 27 01 <-Power Tab Data + 351563 [2451130][E](Custom_C): 01 2b <-hMax + 351564 [2451210][E](Custom_C): 01 27 02 <-Power Tab Data + 351565 [2451244][E](Custom_C): 01 27 03 <-Power Tab Data + 351566 [2451300][E](Custom_C): 01 27 04 <-Power Tab Data + 351567 [2451334][E](Custom_C): 01 27 05 <-Power Tab Data + 351568 [2451424][E](Custom_C): 01 27 06 <-Power Tab Data + 351569 [2451468][E](Custom_C): 01 27 07 <-Power Tab Data + 351570 [2451513][E](Custom_C): 01 27 08 <-Power Tab Data + 351571 [2451534][E](PTable): Success! + 351572 [2451569][E](Custom_C): 01 27 09 <-Power Tab Data + 351573 [2451918][E](Custom_C): 01 19 <-targetPosition + 351574 [2452236][E](PTable): Success! + 351575 [2452885][E](Custom_C): 01 19 <-targetPosition + 351576 [2452939][E](PTable): Success! + 351577 [2452940][E](PTable): Clean Power Table + 351578 [2452940][E](PTable): Averaged Entry: watts=298.000000, cad=98.599998, targetPosition=1478.00003, (8)(10) + 351579 [2452951][E](PTable): cellValue: (141) wattDelta: (4.411763) cadDelta: (0.735294) allNeighborsPassed: (0) + 351580 [2452962][E](PTable): rightValue: (0.000000) leftValue: (141.453339) bottomValue: (139.095993) topValue: (0.000000) New averaged targetPosition: (140.274658) count: (2) + 351581 [2452974][E](PTable): Left failed at: (140) Target pos: (140.274658) Avg pos: (140) + 351582 [2452984][E](PTable): Was not in range failed left (8)(9)(140), readings (1) + 351583 [2452985][E](PTable): WEIGHTED DOWNVOTING: Target Value: (140), NeighborValue: (140) + 351584 [2452995][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 351585 [2453005][E](PTable): PT failed (8)(9)(140), readings (1) + 351586 [2453007][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351587 [2453031][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 351588 [2453064][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351589 [2453085][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351590 [2453117][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351591 [2453139][E](PTable): 80 rpm | | 58 | | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 351592 [2453171][E](PTable): 85 rpm | | 24 | | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351593 [2453192][E](PTable): 90 rpm | | | | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 154 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 351594 [2453225][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 151 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351595 [2453247][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 351596 [2453280][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 351597 [2453301][E](PTable): Power Table Reset + 351598 [2453645][E](PTable): Success! + 351599 [2453897][E](Custom_C): 01 19 <-targetPosition + 351600 [2454351][E](PTable): Success! + 351601 [2454888][E](Custom_C): 01 19 <-targetPosition + 351602 [2455055][E](PTable): Success! + 351603 [2455758][E](PTable): Success! + 351604 [2455759][E](PTable): Clean Power Table + 351605 [2455759][E](PTable): Averaged Entry: watts=316.399994, cad=96.000000, targetPosition=1531.99997, (7)(11) + 351606 [2455770][E](PTable): cellValue: (145) wattDelta: (3.658538) cadDelta: (0.609756) allNeighborsPassed: (0) + 351607 [2455781][E](PTable): rightValue: (0.000000) leftValue: (148.717331) bottomValue: (146.639999) topValue: (0.000000) New averaged targetPosition: (147.678665) count: (2) + 351608 [2455796][E](PTable): Existing entry averaged (7)(11)(145), readings(11) + 351609 [2455900][E](Custom_C): 01 2a <-hMin + 351610 [2455922][E](Custom_C): 01 19 <-targetPosition + 351611 [2455955][E](Custom_C): 01 2b <-hMax + 351612 [2456330][E](Custom_C): 01 27 07 <-Power Tab Data + 351613 [2456337][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351614 [2456358][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351615 [2456391][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351616 [2456414][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351617 [2456446][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351618 [2456468][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351619 [2456502][E](PTable): 85 rpm | | 24 | 84 | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351620 [2456523][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 154 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351621 [2456555][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 151 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351622 [2456577][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351623 [2456609][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351624 [2456630][E](PTable): Power Table Reset + 351625 [2456630][E](ERG_Mode): Proportional: 124.000000, Integral: 9.100000, Derivative: -3.000000 + 351626 [2456890][E](Custom_C): 01 19 <-targetPosition + 351627 [2456958][E](PTable): Success! + 351628 [2457662][E](PTable): Success! + 351629 [2457880][E](Custom_C): 01 19 <-targetPosition + 351630 [2458364][E](PTable): Success! + 351631 [2458881][E](Custom_C): 01 19 <-targetPosition + 351632 [2459068][E](PTable): Success! + 351633 [2459069][E](PTable): Clean Power Table + 351634 [2459069][E](PTable): Averaged Entry: watts=365.600006, cad=94.000000, targetPosition=1566.00006, (7)(12) + 351635 [2459082][E](PTable): cellValue: (151) wattDelta: (5.357137) cadDelta: (0.892856) allNeighborsPassed: (0) + 351636 [2459093][E](PTable): rightValue: (152.045334) leftValue: (149.954666) bottomValue: (149.880005) topValue: (0.000000) New averaged targetPosition: (150.626663) count: (3) + 351637 [2459104][E](PTable): Existing entry averaged (7)(12)(150), readings(11) + 351638 [2459631][E](Custom_C): 01 27 07 <-Power Tab Data + 351639 [2459637][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351640 [2459659][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351641 [2459691][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351642 [2459714][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351643 [2459746][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351644 [2459768][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351645 [2459801][E](PTable): 85 rpm | | 24 | 84 | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351646 [2459822][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 154 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351647 [2459854][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351648 [2459876][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351649 [2459908][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351650 [2459950][E](PTable): Power Table Reset + 351651 [2459967][E](PTable): Success! + 351652 [2460668][E](PTable): Success! + 351653 [2460896][E](Custom_C): 01 2a <-hMin + 351654 [2460940][E](Custom_C): 01 19 <-targetPosition + 351655 [2460962][E](Custom_C): 01 2b <-hMax + 351656 [2461369][E](PTable): Success! + 351657 [2461885][E](Custom_C): 01 19 <-targetPosition + 351658 [2462074][E](PTable): Success! + 351659 [2462075][E](PTable): Clean Power Table + 351660 [2462075][E](PTable): Averaged Entry: watts=386.000000, cad=94.800003, targetPosition=1561.99997, (7)(13) + 351661 [2462087][E](PTable): Keep old targetPosition: (156.199997) + 351662 [2462087][E](PTable): Bottom failed at: (156) Target pos: (156.199997) Avg pos: (156) + 351663 [2462098][E](PTable): Was not in range failed bottom (8)(13)(156), readings (8) + 351664 [2462108][E](PTable): WEIGHTED DOWNVOTING: Target Value: (156), NeighborValue: (156) + 351665 [2462109][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 351666 [2462119][E](PTable): PT failed (8)(13)(156), readings (8) + 351667 [2462121][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351668 [2462154][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 351669 [2462177][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351670 [2462209][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351671 [2462231][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351672 [2462263][E](PTable): 80 rpm | | 58 | | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 351673 [2462304][E](PTable): 85 rpm | | 24 | | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351674 [2462326][E](PTable): 90 rpm | | | | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 154 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 351675 [2462349][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351676 [2462382][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 351677 [2462403][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 351678 [2462434][E](PTable): Power Table Reset + 351679 [2462435][E](ERG_Mode): Proportional: 36.000000, Integral: 3.600000, Derivative: -0.600000 + 351680 [2462779][E](PTable): Success! + 351681 [2462898][E](Custom_C): 01 19 <-targetPosition + 351682 [2463484][E](PTable): Success! + 351683 [2463910][E](Custom_C): 01 19 <-targetPosition + 351684 [2464185][E](PTable): Success! + 351685 [2464877][E](Custom_C): 01 19 <-targetPosition + 351686 [2464892][E](PTable): Success! + 351687 [2464892][E](PTable): Clean Power Table + 351688 [2464893][E](PTable): Averaged Entry: watts=362.399994, cad=93.800003, targetPosition=1561.99997, (7)(12) + 351689 [2464904][E](PTable): cellValue: (150) wattDelta: (4.838712) cadDelta: (0.806452) allNeighborsPassed: (0) + 351690 [2464916][E](PTable): rightValue: (150.496002) leftValue: (149.503998) bottomValue: (148.512009) topValue: (0.000000) New averaged targetPosition: (149.504013) count: (3) + 351691 [2464928][E](PTable): Bottom failed at: (149) Target pos: (149.504013) Avg pos: (149) + 351692 [2464938][E](PTable): Was not in range failed bottom (8)(12)(149), readings (8) + 351693 [2464940][E](PTable): WEIGHTED DOWNVOTING: Target Value: (149), NeighborValue: (149) + 351694 [2464950][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 351695 [2464950][E](PTable): PT failed (8)(12)(149), readings (8) + 351696 [2464962][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351697 [2464984][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 351698 [2465016][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351699 [2465041][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351700 [2465073][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351701 [2465097][E](PTable): 80 rpm | | 58 | | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 351702 [2465119][E](PTable): 85 rpm | | 24 | | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351703 [2465151][E](PTable): 90 rpm | | | | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 154 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 351704 [2465174][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 351705 [2465208][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 351706 [2465229][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 351707 [2465260][E](PTable): Power Table Reset + 351708 [2465595][E](PTable): Success! + 351709 [2465904][E](Custom_C): 01 27 00 <-Power Tab Data + 351710 [2465970][E](Custom_C): 01 2a <-hMin + 351711 [2466059][E](Custom_C): 01 19 <-targetPosition + 351712 [2466149][E](Custom_C): 01 27 01 <-Power Tab Data + 351713 [2466216][E](Custom_C): 01 2b <-hMax + 351714 [2466274][E](Custom_C): 01 27 02 <-Power Tab Data + 351715 [2466300][E](PTable): Success! + 351716 [2466332][E](Custom_C): 01 27 03 <-Power Tab Data + 351717 [2466364][E](Custom_C): 01 27 04 <-Power Tab Data + 351718 [2466408][E](Custom_C): 01 27 05 <-Power Tab Data + 351719 [2466465][E](Custom_C): 01 27 06 <-Power Tab Data + 351720 [2466509][E](Custom_C): 01 27 07 <-Power Tab Data + 351721 [2466556][E](Custom_C): 01 27 08 <-Power Tab Data + 351722 [2466588][E](Custom_C): 01 27 09 <-Power Tab Data + 351723 [2466632][E](Custom_C): 01 25 <-Firmware Version + 351724 [2466880][E](Custom_C): 01 19 <-targetPosition + 351725 [2467003][E](PTable): Success! + 351726 [2467704][E](PTable): Success! + 351727 [2467705][E](PTable): Clean Power Table + 351728 [2467706][E](PTable): Averaged Entry: watts=348.399994, cad=92.199997, targetPosition=1588.00003, (6)(12) + 351729 [2467717][E](PTable): cellValue: (154) wattDelta: (6.249996) cadDelta: (1.041666) allNeighborsPassed: (1) + 351730 [2467728][E](PTable): rightValue: (152.143997) leftValue: (155.856003) bottomValue: (156.112000) topValue: (151.888000) New averaged targetPosition: (154.000000) count: (4) + 351731 [2467739][E](PTable): Existing entry averaged (6)(12)(154), readings(5) + 351732 [2467904][E](Custom_C): 01 19 <-targetPosition + 351733 [2468260][E](Custom_C): 01 27 06 <-Power Tab Data + 351734 [2468265][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351735 [2468289][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351736 [2468321][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351737 [2468343][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351738 [2468375][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351739 [2468397][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351740 [2468429][E](PTable): 85 rpm | | 24 | 84 | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351741 [2468451][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 154 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351742 [2468485][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351743 [2468507][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351744 [2468539][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351745 [2468560][E](PTable): Power Table Reset + 351746 [2468560][E](ERG_Mode): Proportional: 76.000000, Integral: 7.900000, Derivative: -0.600000 + 351747 [2468776][E](PTable): Success! + 351748 [2468777][E](PTable): Using detected travel limits during homing + 351749 [2468886][E](Custom_C): 01 19 <-targetPosition + 351750 [2469480][E](PTable): Success! + 351751 [2469895][E](Custom_C): 01 19 <-targetPosition + 351752 [2470185][E](PTable): Success! + 351753 [2470886][E](PTable): Success! + 351754 [2470887][E](PTable): Clean Power Table + 351755 [2470887][E](PTable): Averaged Entry: watts=372.799988, cad=89.599998, targetPosition=1600.00000, (6)(12) + 351756 [2470899][E](Custom_C): 01 2a <-hMin + 351757 [2470901][E](PTable): cellValue: (154) wattDelta: (5.000000) cadDelta: (0.833333) allNeighborsPassed: (0) + 351758 [2470913][E](PTable): rightValue: (156.559998) leftValue: (151.440002) bottomValue: (153.520004) topValue: (0.000000) New averaged targetPosition: (153.840012) count: (3) + 351759 [2470924][E](PTable): Existing entry averaged (6)(12)(153), readings(6) + 351760 [2470934][E](Custom_C): 01 19 <-targetPosition + 351761 [2471020][E](Custom_C): 01 2b <-hMax + 351762 [2471484][E](Custom_C): 01 27 06 <-Power Tab Data + 351763 [2471492][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351764 [2471514][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351765 [2471548][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351766 [2471570][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351767 [2471595][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351768 [2471627][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351769 [2471649][E](PTable): 85 rpm | | 24 | 84 | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351770 [2471682][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 153 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351771 [2471703][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351772 [2471735][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351773 [2471759][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351774 [2471790][E](PTable): Power Table Reset + 351775 [2471809][E](PTable): Success! + 351776 [2471898][E](Custom_C): 01 19 <-targetPosition + 351777 [2472512][E](PTable): Success! + 351778 [2472899][E](Custom_C): 01 19 <-targetPosition + 351779 [2473217][E](PTable): Success! + 351780 [2473831][E](FTMS_SERVER): 05 82 00 -> ERG Mode Target: 130 Current: 350 Incline: 162.203003 + 351781 [2473838][E](Custom_C): 01 28 <-targetWatts + 351782 [2473879][E](Custom_C): 01 19 <-targetPosition + 351783 [2473919][E](PTable): Success! + 351784 [2473920][E](PTable): Clean Power Table + 351785 [2473920][E](PTable): Averaged Entry: watts=353.200012, cad=88.599998, targetPosition=1608.00003, (6)(12) + 351786 [2473932][E](PTable): cellValue: (153) wattDelta: (3.846152) cadDelta: (0.641025) allNeighborsPassed: (0) + 351787 [2473942][E](PTable): rightValue: (151.231995) leftValue: (154.767990) bottomValue: (150.815994) topValue: (0.000000) New averaged targetPosition: (152.271988) count: (3) + 351788 [2473955][E](PTable): Existing entry averaged (6)(12)(152), readings(7) + 351789 [2474469][E](Custom_C): 01 27 06 <-Power Tab Data + 351790 [2474474][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351791 [2474496][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351792 [2474528][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351793 [2474550][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351794 [2474583][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351795 [2474604][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351796 [2474637][E](PTable): 85 rpm | | 24 | 84 | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351797 [2474660][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351798 [2474693][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351799 [2474714][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351800 [2474746][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351801 [2474767][E](PTable): Power Table Reset + 351802 [2474768][E](PTable): Lookup debug 60 X1 150 X2 85 Y1 95 Y2 0 + 351803 [2474779][E](PTable): Lookup used neighbors L 80 R 108 R1 102 + 351804 [2474779][E](PTable): Lookup used neighbors U 105 D 102 R2 104 + 351805 [2474790][E](PTable): Lookup used actual 103 R3 103 + 351806 [2474790][E](PTable): Lookup result: 130w 88cad 10200 + 351807 [2474801][E](ERG_Mode): SetPoint changed:130w PowerTable Result: 10200 + 351808 [2474801][E](ERG_Mode): Capping ERG seek time to 5 seconds + 351809 [2474879][E](Custom_C): 01 19 <-targetPosition + 351810 [2475144][E](PTable): Success! + 351811 [2475145][E](ERG_Mode): Proportional: -736.000000, Integral: -12.400001, Derivative: -19.300001 + 351812 [2475849][E](PTable): Success! + 351813 [2475880][E](Custom_C): 01 2a <-hMin + 351814 [2475924][E](Custom_C): 01 19 <-targetPosition + 351815 [2475960][E](Custom_C): 01 2b <-hMax + 351816 [2476550][E](PTable): Success! + 351817 [2476903][E](Custom_C): 01 19 <-targetPosition + 351818 [2477251][E](PTable): Success! + 351819 [2477252][E](PTable): Clean Power Table + 351820 [2477252][E](PTable): Averaged Entry: watts=289.600006, cad=81.800003, targetPosition=1553.99994, (4)(10) + 351821 [2477263][E](PTable): cellValue: (153) wattDelta: (12.500031) cadDelta: (2.083339) allNeighborsPassed: (1) + 351822 [2477274][E](PTable): rightValue: (152.167999) leftValue: (153.832001) bottomValue: (153.863998) topValue: (152.136002) New averaged targetPosition: (153.000000) count: (4) + 351823 [2477285][E](PTable): Existing entry averaged (4)(10)(153), readings(11) + 351824 [2477802][E](Custom_C): 01 27 04 <-Power Tab Data + 351825 [2477807][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351826 [2477829][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351827 [2477861][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351828 [2477882][E](Custom_C): 01 19 <-targetPosition + 351829 [2477896][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351830 [2477919][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351831 [2477950][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351832 [2477972][E](PTable): 85 rpm | | 24 | 84 | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351833 [2478009][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351834 [2478031][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351835 [2478063][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351836 [2478085][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351837 [2478107][E](PTable): Power Table Reset + 351838 [2478135][E](PTable): Success! + 351839 [2478838][E](PTable): Success! + 351840 [2478884][E](Custom_C): 01 19 <-targetPosition + 351841 [2479544][E](PTable): Success! + 351842 [2479896][E](Custom_C): 01 19 <-targetPosition + 351843 [2480246][E](PTable): Success! + 351844 [2480247][E](PTable): Clean Power Table + 351845 [2480247][E](PTable): Averaged Entry: watts=212.800003, cad=75.199997, targetPosition=1460.00000, (3)(7) + 351846 [2480259][E](PTable): Keep old targetPosition: (146.000000) + 351847 [2480260][E](PTable): Existing entry averaged (3)(7)(146), readings(11) + 351848 [2480778][E](Custom_C): 01 27 03 <-Power Tab Data + 351849 [2480784][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351850 [2480805][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351851 [2480837][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351852 [2480859][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351853 [2480894][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351854 [2480916][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 141 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351855 [2480978][E](PTable): 85 rpm | | 24 | 84 | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351856 [2481000][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351857 [2481033][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351858 [2481073][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351859 [2481095][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351860 [2481139][E](PTable): Power Table Reset + 351861 [2481140][E](ERG_Mode): Proportional: -376.000000, Integral: -15.400001, Derivative: -1.400000 + 351862 [2481217][E](Custom_C): 01 27 01 <-Power Tab Data + 351863 [2481316][E](Custom_C): 01 2b <-hMax + 351864 [2481372][E](Custom_C): 01 27 02 <-Power Tab Data + 351865 [2481387][E](PTable): Success! + 351866 [2481461][E](Custom_C): 01 27 03 <-Power Tab Data + 351867 [2481530][E](Custom_C): 01 27 04 <-Power Tab Data + 351868 [2481574][E](Custom_C): 01 27 05 <-Power Tab Data + 351869 [2481642][E](Custom_C): 01 27 06 <-Power Tab Data + 351870 [2481686][E](Custom_C): 01 27 07 <-Power Tab Data + 351871 [2481731][E](Custom_C): 01 27 08 <-Power Tab Data + 351872 [2481776][E](Custom_C): 01 27 09 <-Power Tab Data + 351873 [2481944][E](Custom_C): 01 19 <-targetPosition + 351874 [2482089][E](PTable): Success! + 351875 [2482281][E](Custom_C): 01 25 <-Firmware Version + 351876 [2482790][E](PTable): Success! + 351877 [2482889][E](Custom_C): 01 19 <-targetPosition + 351878 [2483517][E](PTable): Success! + 351879 [2483517][E](PTable): Clean Power Table + 351880 [2483518][E](PTable): Averaged Entry: watts=200.399994, cad=78.000000, targetPosition=1393.99994, (4)(7) + 351881 [2483530][E](PTable): cellValue: (141) wattDelta: (18.749929) cadDelta: (3.124988) allNeighborsPassed: (1) + 351882 [2483541][E](PTable): rightValue: (137.287979) leftValue: (138.311996) bottomValue: (137.159988) topValue: (138.439987) New averaged targetPosition: (137.799988) count: (4) + 351883 [2483553][E](PTable): Existing entry averaged (4)(7)(139), readings(1) + 351884 [2483879][E](Custom_C): 01 19 <-targetPosition + 351885 [2484074][E](Custom_C): 01 27 04 <-Power Tab Data + 351886 [2484080][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351887 [2484103][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351888 [2484135][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351889 [2484158][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351890 [2484190][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 138 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351891 [2484211][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 132 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351892 [2484244][E](PTable): 85 rpm | | 24 | 84 | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351893 [2484266][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351894 [2484298][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351895 [2484320][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351896 [2484355][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351897 [2484375][E](PTable): Power Table Reset + 351898 [2484392][E](PTable): Success! + 351899 [2484915][E](Custom_C): 01 19 <-targetPosition + 351900 [2485096][E](PTable): Success! + 351901 [2485798][E](PTable): Success! + 351902 [2485884][E](Custom_C): 01 2a <-hMin + 351903 [2485948][E](Custom_C): 01 19 <-targetPosition + 351904 [2486016][E](Custom_C): 01 2b <-hMax + 351905 [2486061][E](Custom_C): 01 25 <-Firmware Version + 351906 [2486499][E](PTable): Success! + 351907 [2486500][E](PTable): Clean Power Table + 351908 [2486500][E](PTable): Averaged Entry: watts=190.399994, cad=80.599998, targetPosition=1313.99994, (4)(6) + 351909 [2486512][E](PTable): cellValue: (132) wattDelta: (49.999493) cadDelta: (8.333248) allNeighborsPassed: (1) + 351910 [2486523][E](PTable): rightValue: (131.007996) leftValue: (130.591980) bottomValue: (130.871994) topValue: (130.727982) New averaged targetPosition: (130.799988) count: (4) + 351911 [2486534][E](PTable): Existing entry averaged (4)(6)(131), readings(6) + 351912 [2486906][E](Custom_C): 01 19 <-targetPosition + 351913 [2487065][E](Custom_C): 01 27 04 <-Power Tab Data + 351914 [2487071][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351915 [2487093][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351916 [2487126][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351917 [2487148][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351918 [2487179][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351919 [2487201][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351920 [2487233][E](PTable): 85 rpm | | 24 | 84 | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351921 [2487255][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351922 [2487287][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351923 [2487308][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351924 [2487341][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351925 [2487362][E](PTable): Power Table Reset + 351926 [2487372][E](ERG_Mode): Proportional: -184.000000, Integral: -10.600000, Derivative: -0.200000 + 351927 [2487625][E](PTable): Success! + 351928 [2487884][E](Custom_C): 01 19 <-targetPosition + 351929 [2488330][E](PTable): Success! + 351930 [2488896][E](Custom_C): 01 19 <-targetPosition + 351931 [2489032][E](PTable): Success! + 351932 [2489734][E](PTable): Success! + 351933 [2489735][E](PTable): Clean Power Table + 351934 [2489735][E](PTable): Averaged Entry: watts=162.000000, cad=81.599998, targetPosition=1280.00000, (4)(5) + 351935 [2489746][E](PTable): cellValue: (120) wattDelta: (3.750000) cadDelta: (0.625000) allNeighborsPassed: (0) + 351936 [2489757][E](PTable): rightValue: (123.199997) leftValue: (116.800003) bottomValue: (122.559998) topValue: (0.000000) New averaged targetPosition: (120.853333) count: (3) + 351937 [2489769][E](PTable): Existing entry averaged (4)(5)(120), readings(11) + 351938 [2489897][E](Custom_C): 01 19 <-targetPosition + 351939 [2490308][E](Custom_C): 01 27 04 <-Power Tab Data + 351940 [2490314][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351941 [2490336][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351942 [2490369][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351943 [2490391][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351944 [2490423][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351945 [2490445][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351946 [2490477][E](PTable): 85 rpm | | 24 | 84 | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351947 [2490503][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 108 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351948 [2490525][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351949 [2490557][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 102 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351950 [2490578][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351951 [2490610][E](PTable): Power Table Reset + 351952 [2490628][E](PTable): Success! + 351953 [2490901][E](Custom_C): 01 2a <-hMin + 351954 [2490977][E](Custom_C): 01 19 <-targetPosition + 351955 [2491034][E](Custom_C): 01 2b <-hMax + 351956 [2491329][E](PTable): Success! + 351957 [2491889][E](Custom_C): 01 19 <-targetPosition + 351958 [2492034][E](PTable): Success! + 351959 [2492737][E](PTable): Success! + 351960 [2492738][E](PTable): Clean Power Table + 351961 [2492738][E](PTable): Averaged Entry: watts=148.399994, cad=83.000000, targetPosition=1254.00002, (5)(5) + 351962 [2492751][E](PTable): cellValue: (110) wattDelta: (1.948052) cadDelta: (0.324675) allNeighborsPassed: (0) + 351963 [2492752][E](PTable): rightValue: (0.000000) leftValue: (110.821335) bottomValue: (103.839996) topValue: (0.000000) New averaged targetPosition: (107.330666) count: (2) + 351964 [2492774][E](PTable): Bottom failed at: (108) Target pos: (107.330666) Avg pos: (107) + 351965 [2492774][E](PTable): Current Position moved down is valid! Current position: 107.330666 + 351966 [2492785][E](PTable): Existing entry averaged (6)(5)(107), readings(11) + 351967 [2492879][E](Custom_C): 01 19 <-targetPosition + 351968 [2493301][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 351969 [2493323][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 351970 [2493355][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 351971 [2493377][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 351972 [2493408][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 351973 [2493430][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 351974 [2493462][E](PTable): 85 rpm | | 24 | 84 | | 105 | 110 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 351975 [2493484][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 351976 [2493516][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 351977 [2493537][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 351978 [2493571][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 351979 [2493592][E](PTable): Power Table Reset + 351980 [2493592][E](ERG_Mode): Proportional: -88.000000, Integral: -8.200000, Derivative: -0.600000 + 351981 [2493850][E](PTable): Success! + 351982 [2493917][E](Custom_C): 01 19 <-targetPosition + 351983 [2494553][E](PTable): Success! + 351984 [2494881][E](Custom_C): 01 19 <-targetPosition + 351985 [2495256][E](PTable): Success! + 351986 [2495905][E](Custom_C): 01 27 00 <-Power Tab Data + 351987 [2495957][E](PTable): Success! + 351988 [2495958][E](PTable): Clean Power Table + 351989 [2495958][E](PTable): Averaged Entry: watts=144.800003, cad=83.000000, targetPosition=1241.99997, (5)(5) + 351990 [2495962][E](Custom_C): 01 2a <-hMin + 351991 [2495978][E](PTable): cellValue: (110) wattDelta: (2.112677) cadDelta: (0.352113) allNeighborsPassed: (0) + 351992 [2495979][E](PTable): rightValue: (0.000000) leftValue: (112.461334) bottomValue: (104.320000) topValue: (0.000000) New averaged targetPosition: (108.390671) count: (2) + 351993 [2496000][E](PTable): Existing entry averaged (5)(5)(109), readings(10) + 351994 [2496017][E](Custom_C): 01 19 <-targetPosition + 351995 [2496108][E](Custom_C): 01 27 01 <-Power Tab Data + 351996 [2496141][E](Custom_C): 01 2b <-hMax + 351997 [2496209][E](Custom_C): 01 27 02 <-Power Tab Data + 351998 [2496289][E](Custom_C): 01 27 03 <-Power Tab Data + 351999 [2496335][E](Custom_C): 01 27 04 <-Power Tab Data + 352000 [2496390][E](Custom_C): 01 27 05 <-Power Tab Data + 352001 [2496469][E](Custom_C): 01 27 06 <-Power Tab Data + 352002 [2496513][E](Custom_C): 01 27 07 <-Power Tab Data + 352003 [2496569][E](Custom_C): 01 27 08 <-Power Tab Data + 352004 [2496603][E](Custom_C): 01 27 09 <-Power Tab Data + 352005 [2496625][E](Custom_C): 01 27 05 <-Power Tab Data + 352006 [2496630][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352007 [2496653][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352008 [2496686][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352009 [2496707][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352010 [2496739][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352011 [2496761][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352012 [2496793][E](PTable): 85 rpm | | 24 | 84 | | 105 | 109 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352013 [2496815][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352014 [2496847][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352015 [2496869][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352016 [2496916][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352017 [2496937][E](PTable): Power Table Reset + 352018 [2497260][E](PTable): Success! + 352019 [2497896][E](Custom_C): 01 19 <-targetPosition + 352020 [2497965][E](PTable): Success! + 352021 [2498668][E](PTable): Success! + 352022 [2498931][E](Custom_C): 01 19 <-targetPosition + 352023 [2499369][E](PTable): Success! + 352024 [2499370][E](PTable): Clean Power Table + 352025 [2499370][E](PTable): Averaged Entry: watts=132.800003, cad=83.000000, targetPosition=1230.00000, (5)(4) + 352026 [2499381][E](PTable): cellValue: (105) wattDelta: (1.666667) cadDelta: (0.277778) allNeighborsPassed: (0) + 352027 [2499393][E](PTable): rightValue: (0.000000) leftValue: (97.320000) bottomValue: (97.800003) topValue: (0.000000) New averaged targetPosition: (97.559998) count: (2) + 352028 [2499404][E](PTable): Bottom failed at: (103) Target pos: (97.559998) Avg pos: (100) + 352029 [2499407][E](PTable): All test failed bottom (4)(4)(108), readings (11) + 352030 [2499417][E](PTable): WEIGHTED DOWNVOTING: Target Value: (97), NeighborValue: (103) + 352031 [2499428][E](PTable): WEIGHTED DOWNVOTING: Delta: (6), Penalty: (1) + 352032 [2499428][E](PTable): PT failed (6)(4)(103), readings (10) + 352033 [2499440][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352034 [2499463][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352035 [2499495][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352036 [2499517][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352037 [2499539][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352038 [2499571][E](PTable): 80 rpm | | 58 | | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352039 [2499604][E](PTable): 85 rpm | | 24 | | | 105 | 109 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352040 [2499626][E](PTable): 90 rpm | | | | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352041 [2499648][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352042 [2499680][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 352043 [2499714][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352044 [2499735][E](PTable): Power Table Reset + 352045 [2499735][E](ERG_Mode): Proportional: -8.000000, Integral: -5.800000, Derivative: -0.600000 + 352046 [2499899][E](Custom_C): 01 19 <-targetPosition + 352047 [2500071][E](PTable): Success! + 352048 [2500773][E](PTable): Success! + 352049 [2500889][E](Custom_C): 01 2a <-hMin + 352050 [2500935][E](Custom_C): 01 19 <-targetPosition + 352051 [2501001][E](Custom_C): 01 2b <-hMax + 352052 [2501478][E](PTable): Success! + 352053 [2501912][E](Custom_C): 01 19 <-targetPosition + 352054 [2502180][E](PTable): Success! + 352055 [2502181][E](PTable): Clean Power Table + 352056 [2502181][E](PTable): Averaged Entry: watts=136.000000, cad=83.599998, targetPosition=1230.00000, (5)(5) + 352057 [2502193][E](PTable): cellValue: (109) wattDelta: (2.142857) cadDelta: (0.357143) allNeighborsPassed: (0) + 352058 [2502204][E](PTable): rightValue: (102.466667) leftValue: (115.533333) bottomValue: (105.079994) topValue: (0.000000) New averaged targetPosition: (107.693329) count: (3) + 352059 [2502215][E](PTable): Bottom failed at: (107) Target pos: (107.693329) Avg pos: (107) + 352060 [2502226][E](PTable): Was not in range failed bottom (6)(5)(107), readings (11) + 352061 [2502226][E](PTable): WEIGHTED DOWNVOTING: Target Value: (107), NeighborValue: (107) + 352062 [2502236][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 352063 [2502247][E](PTable): PT failed (6)(5)(107), readings (11) + 352064 [2502249][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352065 [2502297][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352066 [2502318][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352067 [2502351][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352068 [2502372][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352069 [2502404][E](PTable): 80 rpm | | 58 | | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352070 [2502426][E](PTable): 85 rpm | | 24 | | | 105 | 109 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352071 [2502458][E](PTable): 90 rpm | | | | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352072 [2502481][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352073 [2502503][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 352074 [2502535][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352075 [2502566][E](PTable): Power Table Reset + 352076 [2502884][E](Custom_C): 01 19 <-targetPosition + 352077 [2502887][E](PTable): Success! + 352078 [2503589][E](PTable): Success! + 352079 [2503906][E](Custom_C): 01 19 <-targetPosition + 352080 [2504294][E](PTable): Success! + 352081 [2504894][E](Custom_C): 01 19 <-targetPosition + 352082 [2504996][E](PTable): Success! + 352083 [2504997][E](PTable): Clean Power Table + 352084 [2504997][E](PTable): Averaged Entry: watts=161.199997, cad=85.599998, targetPosition=1214.00002, (5)(5) + 352085 [2505009][E](PTable): cellValue: (109) wattDelta: (2.419354) cadDelta: (0.403226) allNeighborsPassed: (0) + 352086 [2505020][E](PTable): rightValue: (113.629333) leftValue: (104.370667) bottomValue: (110.487999) topValue: (0.000000) New averaged targetPosition: (109.496002) count: (3) + 352087 [2505032][E](PTable): Existing entry averaged (5)(5)(109), readings(11) + 352088 [2505557][E](Custom_C): 01 27 05 <-Power Tab Data + 352089 [2505563][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352090 [2505585][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352091 [2505616][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352092 [2505638][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352093 [2505670][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352094 [2505692][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352095 [2505724][E](PTable): 85 rpm | | 24 | 84 | | 105 | 109 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352096 [2505745][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352097 [2505777][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352098 [2505799][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352099 [2505831][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352100 [2505852][E](PTable): Power Table Reset + 352101 [2505863][E](ERG_Mode): Proportional: -320.000000, Integral: -14.000000, Derivative: -7.600000 + 352102 [2505884][E](Custom_C): 01 2a <-hMin + 352103 [2505929][E](Custom_C): 01 19 <-targetPosition + 352104 [2505996][E](Custom_C): 01 2b <-hMax + 352105 [2506043][E](Custom_C): 01 25 <-Firmware Version + 352106 [2506145][E](PTable): Success! + 352107 [2506846][E](PTable): Success! + 352108 [2506896][E](Custom_C): 01 19 <-targetPosition + 352109 [2507549][E](PTable): Success! + 352110 [2507899][E](Custom_C): 01 19 <-targetPosition + 352111 [2508253][E](PTable): Success! + 352112 [2508254][E](PTable): Clean Power Table + 352113 [2508254][E](PTable): Averaged Entry: watts=128.800003, cad=84.400002, targetPosition=1210.00000, (5)(4) + 352114 [2508267][E](PTable): cellValue: (105) wattDelta: (1.875000) cadDelta: (0.312500) allNeighborsPassed: (0) + 352115 [2508268][E](PTable): rightValue: (0.000000) leftValue: (100.306664) bottomValue: (103.080002) topValue: (0.000000) New averaged targetPosition: (101.693329) count: (2) + 352116 [2508289][E](PTable): Bottom failed at: (103) Target pos: (101.693329) Avg pos: (102) + 352117 [2508300][E](PTable): All test failed bottom (4)(4)(108), readings (11) + 352118 [2508300][E](PTable): WEIGHTED DOWNVOTING: Target Value: (101), NeighborValue: (103) + 352119 [2508311][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 352120 [2508312][E](PTable): PT failed (6)(4)(103), readings (10) + 352121 [2508324][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352122 [2508345][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352123 [2508377][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352124 [2508399][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352125 [2508432][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352126 [2508453][E](PTable): 80 rpm | | 58 | | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352127 [2508485][E](PTable): 85 rpm | | 24 | | | 105 | 109 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352128 [2508507][E](PTable): 90 rpm | | | | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352129 [2508541][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352130 [2508564][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 352131 [2508595][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352132 [2508616][E](PTable): Power Table Reset + 352133 [2508617][E](PTable): Using detected travel limits during homing + 352134 [2508898][E](Custom_C): 01 19 <-targetPosition + 352135 [2508955][E](PTable): Success! + 352136 [2509660][E](PTable): Success! + 352137 [2509889][E](Custom_C): 01 19 <-targetPosition + 352138 [2510369][E](PTable): Success! + 352139 [2510914][E](Custom_C): 01 27 00 <-Power Tab Data + 352140 [2510946][E](Custom_C): 01 2a <-hMin + 352141 [2510991][E](Custom_C): 01 19 <-targetPosition + 352142 [2511048][E](Custom_C): 01 27 01 <-Power Tab Data + 352143 [2511072][E](PTable): Success! + 352144 [2511073][E](PTable): Clean Power Table + 352145 [2511073][E](PTable): Averaged Entry: watts=136.800003, cad=83.800003, targetPosition=1204.00002, (5)(5) + 352146 [2511085][E](PTable): cellValue: (109) wattDelta: (2.631579) cadDelta: (0.438596) allNeighborsPassed: (0) + 352147 [2511096][E](PTable): rightValue: (103.984001) leftValue: (114.015999) bottomValue: (106.264008) topValue: (0.000000) New averaged targetPosition: (108.088005) count: (3) + 352148 [2511107][E](PTable): Existing entry averaged (5)(5)(108), readings(11) + 352149 [2511115][E](Custom_C): 01 2b <-hMax + 352150 [2511183][E](Custom_C): 01 27 02 <-Power Tab Data + 352151 [2511228][E](Custom_C): 01 27 03 <-Power Tab Data + 352152 [2511273][E](Custom_C): 01 27 04 <-Power Tab Data + 352153 [2511341][E](Custom_C): 01 27 05 <-Power Tab Data + 352154 [2511387][E](Custom_C): 01 27 06 <-Power Tab Data + 352155 [2511431][E](Custom_C): 01 27 07 <-Power Tab Data + 352156 [2511475][E](Custom_C): 01 27 08 <-Power Tab Data + 352157 [2511521][E](Custom_C): 01 27 09 <-Power Tab Data + 352158 [2511690][E](Custom_C): 01 27 05 <-Power Tab Data + 352159 [2511699][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352160 [2511721][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352161 [2511754][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352162 [2511775][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352163 [2511808][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352164 [2511829][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352165 [2511861][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352166 [2511883][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352167 [2511929][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352168 [2511951][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352169 [2511983][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352170 [2512004][E](PTable): Power Table Reset + 352171 [2512005][E](ERG_Mode): Proportional: 32.000000, Integral: -5.200000, Derivative: 0.800000 + 352172 [2512371][E](PTable): Success! + 352173 [2512881][E](Custom_C): 01 19 <-targetPosition + 352174 [2513071][E](PTable): Success! + 352175 [2513774][E](PTable): Success! + 352176 [2513893][E](Custom_C): 01 19 <-targetPosition + 352177 [2514477][E](PTable): Success! + 352178 [2514478][E](PTable): Clean Power Table + 352179 [2514479][E](PTable): Averaged Entry: watts=124.000000, cad=81.400002, targetPosition=1204.00002, (4)(4) + 352180 [2514490][E](PTable): cellValue: (108) wattDelta: (2.419354) cadDelta: (0.403226) allNeighborsPassed: (0) + 352181 [2514501][E](PTable): rightValue: (0.000000) leftValue: (106.346664) bottomValue: (111.472000) topValue: (0.000000) New averaged targetPosition: (108.909332) count: (2) + 352182 [2514513][E](PTable): Existing entry averaged (4)(4)(108), readings(11) + 352183 [2514884][E](Custom_C): 01 19 <-targetPosition + 352184 [2515089][E](Custom_C): 01 27 04 <-Power Tab Data + 352185 [2515094][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352186 [2515116][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352187 [2515149][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352188 [2515170][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352189 [2515203][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352190 [2515225][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352191 [2515257][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352192 [2515280][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352193 [2515313][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352194 [2515334][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352195 [2515366][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352196 [2515387][E](PTable): Power Table Reset + 352197 [2515405][E](PTable): Success! + 352198 [2515929][E](Custom_C): 01 2a <-hMin + 352199 [2515963][E](Custom_C): 01 19 <-targetPosition + 352200 [2516008][E](Custom_C): 01 2b <-hMax + 352201 [2516107][E](PTable): Success! + 352202 [2516810][E](PTable): Success! + 352203 [2516897][E](Custom_C): 01 19 <-targetPosition + 352204 [2517514][E](PTable): Success! + 352205 [2517515][E](PTable): Clean Power Table + 352206 [2517515][E](PTable): Averaged Entry: watts=140.399994, cad=84.599998, targetPosition=1198.00003, (5)(5) + 352207 [2517527][E](PTable): cellValue: (108) wattDelta: (2.542372) cadDelta: (0.423729) allNeighborsPassed: (1) + 352208 [2517538][E](PTable): rightValue: (104.223999) leftValue: (111.776001) bottomValue: (107.056000) topValue: (108.944000) New averaged targetPosition: (108.000000) count: (4) + 352209 [2517550][E](PTable): Existing entry averaged (5)(5)(108), readings(11) + 352210 [2517898][E](Custom_C): 01 19 <-targetPosition + 352211 [2518058][E](Custom_C): 01 27 05 <-Power Tab Data + 352212 [2518063][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352213 [2518086][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352214 [2518118][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352215 [2518139][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352216 [2518172][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352217 [2518193][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352218 [2518225][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352219 [2518248][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352220 [2518280][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352221 [2518302][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352222 [2518334][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352223 [2518355][E](PTable): Power Table Reset + 352224 [2518366][E](ERG_Mode): Proportional: 32.000000, Integral: -5.000000, Derivative: 0.600000 + 352225 [2518620][E](PTable): Success! + 352226 [2518889][E](Custom_C): 01 19 <-targetPosition + 352227 [2519321][E](PTable): Success! + 352228 [2519879][E](Custom_C): 01 19 <-targetPosition + 352229 [2520026][E](PTable): Success! + 352230 [2520729][E](PTable): Success! + 352231 [2520730][E](PTable): Clean Power Table + 352232 [2520730][E](PTable): Averaged Entry: watts=120.000000, cad=81.199997, targetPosition=1195.99998, (4)(4) + 352233 [2520742][E](PTable): cellValue: (108) wattDelta: (2.586207) cadDelta: (0.431035) allNeighborsPassed: (0) + 352234 [2520753][E](PTable): rightValue: (108.000000) leftValue: (108.000000) bottomValue: (110.783997) topValue: (0.000000) New averaged targetPosition: (108.928001) count: (3) + 352235 [2520765][E](PTable): Existing entry averaged (4)(4)(108), readings(11) + 352236 [2520891][E](Custom_C): 01 2a <-hMin + 352237 [2520958][E](Custom_C): 01 19 <-targetPosition + 352238 [2521003][E](Custom_C): 01 2b <-hMax + 352239 [2521291][E](Custom_C): 01 27 04 <-Power Tab Data + 352240 [2521297][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352241 [2521323][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352242 [2521345][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352243 [2521377][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352244 [2521399][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352245 [2521431][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352246 [2521453][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352247 [2521485][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352248 [2521508][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352249 [2521541][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352250 [2521565][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352251 [2521596][E](PTable): Power Table Reset + 352252 [2521615][E](PTable): Success! + 352253 [2521881][E](Custom_C): 01 19 <-targetPosition + 352254 [2522297][E](Custom_C): 01 25 <-Firmware Version + 352255 [2522320][E](PTable): Success! + 352256 [2522894][E](Custom_C): 01 19 <-targetPosition + 352257 [2523024][E](PTable): Success! + 352258 [2523725][E](PTable): Success! + 352259 [2523726][E](PTable): Clean Power Table + 352260 [2523726][E](PTable): Averaged Entry: watts=122.800003, cad=81.400002, targetPosition=1201.99997, (4)(4) + 352261 [2523738][E](PTable): cellValue: (108) wattDelta: (2.459017) cadDelta: (0.409836) allNeighborsPassed: (0) + 352262 [2523749][E](PTable): rightValue: (0.000000) leftValue: (106.861336) bottomValue: (111.416000) topValue: (0.000000) New averaged targetPosition: (109.138672) count: (2) + 352263 [2523760][E](PTable): Existing entry averaged (4)(4)(108), readings(11) + 352264 [2523884][E](Custom_C): 01 19 <-targetPosition + 352265 [2524298][E](Custom_C): 01 27 04 <-Power Tab Data + 352266 [2524304][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352267 [2524326][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352268 [2524358][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352269 [2524379][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352270 [2524411][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352271 [2524433][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352272 [2524465][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352273 [2524487][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352274 [2524519][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352275 [2524541][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352276 [2524573][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352277 [2524596][E](PTable): Power Table Reset + 352278 [2524597][E](ERG_Mode): Proportional: -16.000000, Integral: 0.000000, Derivative: -2.000000 + 352279 [2524860][E](PTable): Success! + 352280 [2524900][E](Custom_C): 01 19 <-targetPosition + 352281 [2525565][E](PTable): Success! + 352282 [2525910][E](Custom_C): 01 27 00 <-Power Tab Data + 352283 [2525976][E](Custom_C): 01 2a <-hMin + 352284 [2526020][E](Custom_C): 01 19 <-targetPosition + 352285 [2526101][E](Custom_C): 01 27 01 <-Power Tab Data + 352286 [2526156][E](Custom_C): 01 2b <-hMax + 352287 [2526236][E](Custom_C): 01 27 02 <-Power Tab Data + 352288 [2526270][E](PTable): Success! + 352289 [2526304][E](Custom_C): 01 27 03 <-Power Tab Data + 352290 [2526372][E](Custom_C): 01 27 04 <-Power Tab Data + 352291 [2526416][E](Custom_C): 01 27 05 <-Power Tab Data + 352292 [2526484][E](Custom_C): 01 27 06 <-Power Tab Data + 352293 [2526528][E](Custom_C): 01 27 07 <-Power Tab Data + 352294 [2526596][E](Custom_C): 01 27 08 <-Power Tab Data + 352295 [2526640][E](Custom_C): 01 27 09 <-Power Tab Data + 352296 [2526696][E](Custom_C): 01 25 <-Firmware Version + 352297 [2526887][E](Custom_C): 01 19 <-targetPosition + 352298 [2527041][E](PTable): Success! + 352299 [2527043][E](PTable): Clean Power Table + 352300 [2527043][E](PTable): Averaged Entry: watts=112.400002, cad=81.800003, targetPosition=1218.00003, (4)(4) + 352301 [2527055][E](PTable): cellValue: (108) wattDelta: (2.173913) cadDelta: (0.362319) allNeighborsPassed: (0) + 352302 [2527058][E](PTable): rightValue: (0.000000) leftValue: (111.496002) bottomValue: (112.968010) topValue: (0.000000) New averaged targetPosition: (112.232010) count: (2) + 352303 [2527080][E](PTable): Existing entry averaged (4)(4)(108), readings(11) + 352304 [2527601][E](Custom_C): 01 27 04 <-Power Tab Data + 352305 [2527607][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352306 [2527629][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352307 [2527662][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352308 [2527684][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352309 [2527718][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352310 [2527740][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352311 [2527772][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352312 [2527794][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352313 [2527826][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352314 [2527847][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352315 [2527879][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352316 [2527900][E](PTable): Power Table Reset + 352317 [2527913][E](Custom_C): 01 19 <-targetPosition + 352318 [2527924][E](PTable): Success! + 352319 [2528628][E](PTable): Success! + 352320 [2528879][E](Custom_C): 01 19 <-targetPosition + 352321 [2529329][E](PTable): Success! + 352322 [2529891][E](Custom_C): 01 19 <-targetPosition + 352323 [2530034][E](PTable): Success! + 352324 [2530035][E](PTable): Clean Power Table + 352325 [2530035][E](PTable): Averaged Entry: watts=130.000000, cad=82.400002, targetPosition=1230.00000, (4)(4) + 352326 [2530046][E](PTable): cellValue: (108) wattDelta: (2.000000) cadDelta: (0.333333) allNeighborsPassed: (0) + 352327 [2530057][E](PTable): rightValue: (0.000000) leftValue: (103.000000) bottomValue: (115.200005) topValue: (0.000000) New averaged targetPosition: (109.100006) count: (2) + 352328 [2530068][E](PTable): Existing entry averaged (4)(4)(108), readings(11) + 352329 [2530575][E](Custom_C): 01 27 04 <-Power Tab Data + 352330 [2530581][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352331 [2530602][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352332 [2530634][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352333 [2530656][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352334 [2530689][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352335 [2530710][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352336 [2530743][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352337 [2530765][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352338 [2530797][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352339 [2530818][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352340 [2530851][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352341 [2530872][E](PTable): Power Table Reset + 352342 [2530882][E](Custom_C): 01 2a <-hMin + 352343 [2530886][E](ERG_Mode): Proportional: -8.000000, Integral: 2.800000, Derivative: -0.400000 + 352344 [2530940][E](Custom_C): 01 19 <-targetPosition + 352345 [2531016][E](Custom_C): 01 2b <-hMax + 352346 [2531140][E](PTable): Success! + 352347 [2531844][E](PTable): Success! + 352348 [2531893][E](Custom_C): 01 19 <-targetPosition + 352349 [2532549][E](PTable): Success! + 352350 [2532884][E](Custom_C): 01 19 <-targetPosition + 352351 [2533254][E](PTable): Success! + 352352 [2533254][E](PTable): Clean Power Table + 352353 [2533255][E](PTable): Averaged Entry: watts=128.399994, cad=79.800003, targetPosition=1230.00000, (4)(4) + 352354 [2533266][E](PTable): cellValue: (108) wattDelta: (2.000000) cadDelta: (0.333333) allNeighborsPassed: (0) + 352355 [2533277][E](PTable): rightValue: (0.000000) leftValue: (103.800003) bottomValue: (107.400009) topValue: (0.000000) New averaged targetPosition: (105.600006) count: (2) + 352356 [2533288][E](PTable): Bottom failed at: (105) Target pos: (105.600006) Avg pos: (105) + 352357 [2533300][E](PTable): Was not in range failed bottom (5)(4)(105), readings (11) + 352358 [2533301][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (105) + 352359 [2533312][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 352360 [2533312][E](PTable): PT failed (5)(4)(105), readings (11) + 352361 [2533324][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352362 [2533347][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352363 [2533379][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352364 [2533403][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352365 [2533425][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352366 [2533457][E](PTable): 80 rpm | | 58 | | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352367 [2533479][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352368 [2533512][E](PTable): 90 rpm | | | | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352369 [2533534][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352370 [2533566][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 352371 [2533589][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352372 [2533620][E](PTable): Power Table Reset + 352373 [2533895][E](Custom_C): 01 19 <-targetPosition + 352374 [2533955][E](PTable): Success! + 352375 [2534657][E](PTable): Success! + 352376 [2534897][E](Custom_C): 01 19 <-targetPosition + 352377 [2535360][E](PTable): Success! + 352378 [2535898][E](Custom_C): 01 2a <-hMin + 352379 [2535943][E](Custom_C): 01 19 <-targetPosition + 352380 [2536011][E](Custom_C): 01 2b <-hMax + 352381 [2536066][E](PTable): Success! + 352382 [2536067][E](PTable): Clean Power Table + 352383 [2536067][E](PTable): Averaged Entry: watts=127.199997, cad=78.199997, targetPosition=1234.00002, (4)(4) + 352384 [2536078][E](PTable): cellValue: (108) wattDelta: (1.948052) cadDelta: (0.324675) allNeighborsPassed: (0) + 352385 [2536089][E](PTable): rightValue: (0.000000) leftValue: (104.304001) bottomValue: (102.455994) topValue: (0.000000) New averaged targetPosition: (103.379997) count: (2) + 352386 [2536100][E](PTable): Bottom failed at: (105) Target pos: (103.379997) Avg pos: (104) + 352387 [2536111][E](PTable): All test failed bottom (3)(4)(113), readings (11) + 352388 [2536111][E](PTable): WEIGHTED DOWNVOTING: Target Value: (103), NeighborValue: (105) + 352389 [2536122][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 352390 [2536132][E](PTable): PT failed (5)(4)(105), readings (11) + 352391 [2536134][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352392 [2536155][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352393 [2536191][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352394 [2536212][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352395 [2536244][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352396 [2536266][E](PTable): 80 rpm | | 58 | | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352397 [2536298][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352398 [2536320][E](PTable): 90 rpm | | | | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352399 [2536351][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352400 [2536373][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 352401 [2536405][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352402 [2536436][E](PTable): Power Table Reset + 352403 [2536436][E](ERG_Mode): Proportional: 40.000000, Integral: 4.200000, Derivative: 1.800000 + 352404 [2536771][E](PTable): Success! + 352405 [2536911][E](Custom_C): 01 19 <-targetPosition + 352406 [2537475][E](PTable): Success! + 352407 [2537878][E](Custom_C): 01 19 <-targetPosition + 352408 [2538176][E](PTable): Success! + 352409 [2538881][E](PTable): Success! + 352410 [2538882][E](PTable): Clean Power Table + 352411 [2538882][E](PTable): Averaged Entry: watts=134.000000, cad=78.199997, targetPosition=1230.00000, (4)(4) + 352412 [2538894][E](Custom_C): 01 19 <-targetPosition + 352413 [2538897][E](PTable): cellValue: (108) wattDelta: (2.000000) cadDelta: (0.333333) allNeighborsPassed: (0) + 352414 [2538908][E](PTable): rightValue: (0.000000) leftValue: (101.000000) bottomValue: (102.599991) topValue: (0.000000) New averaged targetPosition: (101.799995) count: (2) + 352415 [2538919][E](PTable): Bottom failed at: (105) Target pos: (101.799995) Avg pos: (103) + 352416 [2538933][E](PTable): All test failed bottom (3)(4)(113), readings (11) + 352417 [2538934][E](PTable): WEIGHTED DOWNVOTING: Target Value: (101), NeighborValue: (105) + 352418 [2538944][E](PTable): WEIGHTED DOWNVOTING: Delta: (4), Penalty: (0) + 352419 [2538944][E](PTable): PT failed (5)(4)(105), readings (11) + 352420 [2538957][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352421 [2538979][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352422 [2539011][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352423 [2539036][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352424 [2539058][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352425 [2539089][E](PTable): 80 rpm | | 58 | | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352426 [2539111][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352427 [2539144][E](PTable): 90 rpm | | | | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352428 [2539165][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352429 [2539197][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 352430 [2539218][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352431 [2539249][E](PTable): Power Table Reset + 352432 [2539584][E](PTable): Success! + 352433 [2539903][E](Custom_C): 01 19 <-targetPosition + 352434 [2540285][E](PTable): Success! + 352435 [2540906][E](Custom_C): 01 27 00 <-Power Tab Data + 352436 [2540938][E](Custom_C): 01 2a <-hMin + 352437 [2540994][E](PTable): Success! + 352438 [2541017][E](Custom_C): 01 19 <-targetPosition + 352439 [2541063][E](Custom_C): 01 27 01 <-Power Tab Data + 352440 [2541119][E](Custom_C): 01 2b <-hMax + 352441 [2541176][E](Custom_C): 01 27 02 <-Power Tab Data + 352442 [2541266][E](Custom_C): 01 27 03 <-Power Tab Data + 352443 [2541311][E](Custom_C): 01 27 04 <-Power Tab Data + 352444 [2541355][E](Custom_C): 01 27 05 <-Power Tab Data + 352445 [2541434][E](Custom_C): 01 27 06 <-Power Tab Data + 352446 [2541493][E](Custom_C): 01 27 07 <-Power Tab Data + 352447 [2541536][E](Custom_C): 01 27 08 <-Power Tab Data + 352448 [2541591][E](Custom_C): 01 27 09 <-Power Tab Data + 352449 [2541699][E](PTable): Success! + 352450 [2541700][E](PTable): Clean Power Table + 352451 [2541701][E](PTable): Averaged Entry: watts=142.000000, cad=79.800003, targetPosition=1225.99998, (4)(5) + 352452 [2541712][E](PTable): cellValue: (120) wattDelta: (11.538468) cadDelta: (1.923078) allNeighborsPassed: (1) + 352453 [2541723][E](PTable): rightValue: (119.306664) leftValue: (120.693336) bottomValue: (119.896004) topValue: (120.103996) New averaged targetPosition: (120.000000) count: (4) + 352454 [2541734][E](PTable): Existing entry averaged (4)(5)(120), readings(11) + 352455 [2541884][E](Custom_C): 01 19 <-targetPosition + 352456 [2542271][E](Custom_C): 01 27 04 <-Power Tab Data + 352457 [2542277][E](Custom_C): 01 25 <-Firmware Version + 352458 [2542280][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352459 [2542302][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352460 [2542334][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352461 [2542356][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352462 [2542388][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352463 [2542409][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352464 [2542442][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352465 [2542464][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352466 [2542496][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352467 [2542517][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352468 [2542551][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352469 [2542572][E](PTable): Power Table Reset + 352470 [2542885][E](Custom_C): 01 19 <-targetPosition + 352471 [2542933][E](PTable): Success! + 352472 [2542934][E](ERG_Mode): Proportional: -48.000000, Integral: -1.200000, Derivative: 0.600000 + 352473 [2543636][E](PTable): Success! + 352474 [2543897][E](Custom_C): 01 19 <-targetPosition + 352475 [2544341][E](PTable): Success! + 352476 [2544899][E](Custom_C): 01 19 <-targetPosition + 352477 [2545044][E](PTable): Success! + 352478 [2545045][E](PTable): Clean Power Table + 352479 [2545045][E](PTable): Averaged Entry: watts=140.800003, cad=80.000000, targetPosition=1214.00002, (4)(5) + 352480 [2545056][E](PTable): cellValue: (120) wattDelta: (21.428549) cadDelta: (3.571425) allNeighborsPassed: (1) + 352481 [2545070][E](PTable): rightValue: (119.570663) leftValue: (120.429337) bottomValue: (120.000000) topValue: (120.000000) New averaged targetPosition: (120.000000) count: (4) + 352482 [2545083][E](PTable): Existing entry averaged (4)(5)(120), readings(11) + 352483 [2545594][E](Custom_C): 01 27 04 <-Power Tab Data + 352484 [2545599][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352485 [2545621][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352486 [2545653][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352487 [2545674][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352488 [2545707][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352489 [2545729][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352490 [2545761][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352491 [2545782][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352492 [2545815][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352493 [2545837][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352494 [2545869][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352495 [2545890][E](Custom_C): 01 2a <-hMin + 352496 [2545931][E](PTable): Success! + 352497 [2545956][E](Custom_C): 01 19 <-targetPosition + 352498 [2546024][E](Custom_C): 01 2b <-hMax + 352499 [2546097][E](Custom_C): 01 25 <-Firmware Version + 352500 [2546632][E](PTable): Success! + 352501 [2546878][E](Custom_C): 01 19 <-targetPosition + 352502 [2547334][E](PTable): Success! + 352503 [2547335][E](PTable): Using detected travel limits during homing + 352504 [2547891][E](Custom_C): 01 19 <-targetPosition + 352505 [2548036][E](PTable): Success! + 352506 [2548038][E](PTable): Clean Power Table + 352507 [2548038][E](PTable): Averaged Entry: watts=141.600006, cad=81.800003, targetPosition=1204.00002, (4)(5) + 352508 [2548050][E](PTable): cellValue: (120) wattDelta: (74.999718) cadDelta: (12.499952) allNeighborsPassed: (1) + 352509 [2548061][E](PTable): rightValue: (119.888000) leftValue: (120.112000) bottomValue: (120.143997) topValue: (119.856003) New averaged targetPosition: (120.000000) count: (4) + 352510 [2548072][E](PTable): Existing entry averaged (4)(5)(120), readings(11) + 352511 [2548579][E](Custom_C): 01 27 04 <-Power Tab Data + 352512 [2548585][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352513 [2548607][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352514 [2548639][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352515 [2548661][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352516 [2548694][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352517 [2548715][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352518 [2548748][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352519 [2548770][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352520 [2548801][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352521 [2548823][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352522 [2548855][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352523 [2548876][E](PTable): Power Table Reset + 352524 [2548887][E](Custom_C): 01 19 <-targetPosition + 352525 [2548890][E](ERG_Mode): Proportional: -72.000000, Integral: -6.800000, Derivative: -0.800000 + 352526 [2549149][E](PTable): Success! + 352527 [2549853][E](PTable): Success! + 352528 [2549893][E](Custom_C): 01 19 <-targetPosition + 352529 [2550555][E](PTable): Success! + 352530 [2550883][E](Custom_C): 01 2a <-hMin + 352531 [2550951][E](Custom_C): 01 19 <-targetPosition + 352532 [2550995][E](Custom_C): 01 2b <-hMax + 352533 [2551260][E](PTable): Success! + 352534 [2551261][E](PTable): Clean Power Table + 352535 [2551261][E](PTable): Averaged Entry: watts=133.600006, cad=82.800003, targetPosition=1195.99998, (5)(4) + 352536 [2551272][E](PTable): cellValue: (105) wattDelta: (2.054795) cadDelta: (0.342466) allNeighborsPassed: (0) + 352537 [2551283][E](PTable): rightValue: (0.000000) leftValue: (98.381332) bottomValue: (98.576012) topValue: (0.000000) New averaged targetPosition: (98.478668) count: (2) + 352538 [2551295][E](PTable): Bottom failed at: (103) Target pos: (98.478668) Avg pos: (100) + 352539 [2551306][E](PTable): All test failed bottom (4)(4)(108), readings (11) + 352540 [2551306][E](PTable): WEIGHTED DOWNVOTING: Target Value: (98), NeighborValue: (103) + 352541 [2551316][E](PTable): WEIGHTED DOWNVOTING: Delta: (5), Penalty: (1) + 352542 [2551317][E](PTable): PT failed (6)(4)(103), readings (9) + 352543 [2551329][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352544 [2551351][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352545 [2551385][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352546 [2551406][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352547 [2551440][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352548 [2551461][E](PTable): 80 rpm | | 58 | | | 108 | 120 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352549 [2551493][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352550 [2551515][E](PTable): 90 rpm | | | | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352551 [2551539][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352552 [2551571][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 352553 [2551593][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352554 [2551624][E](PTable): Power Table Reset + 352555 [2551896][E](Custom_C): 01 19 <-targetPosition + 352556 [2551964][E](PTable): Success! + 352557 [2552669][E](PTable): Success! + 352558 [2552909][E](Custom_C): 01 19 <-targetPosition + 352559 [2553370][E](PTable): Success! + 352560 [2553898][E](Custom_C): 01 19 <-targetPosition + 352561 [2554075][E](PTable): Success! + 352562 [2554076][E](PTable): Clean Power Table + 352563 [2554076][E](PTable): Averaged Entry: watts=149.199997, cad=82.199997, targetPosition=1190.00000, (4)(5) + 352564 [2554088][E](PTable): cellValue: (120) wattDelta: (30.000000) cadDelta: (5.000000) allNeighborsPassed: (1) + 352565 [2554100][E](PTable): rightValue: (117.973335) leftValue: (118.026665) bottomValue: (118.440002) topValue: (117.559998) New averaged targetPosition: (118.000000) count: (4) + 352566 [2554111][E](PTable): Existing entry averaged (4)(5)(119), readings(11) + 352567 [2554635][E](Custom_C): 01 27 04 <-Power Tab Data + 352568 [2554643][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352569 [2554664][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352570 [2554696][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352571 [2554718][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352572 [2554751][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352573 [2554772][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 119 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352574 [2554804][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352575 [2554826][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352576 [2554859][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352577 [2554881][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352578 [2554928][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352579 [2554949][E](PTable): Power Table Reset + 352580 [2554950][E](ERG_Mode): Proportional: -256.000000, Integral: -12.400001, Derivative: -5.600000 + 352581 [2555181][E](PTable): Success! + 352582 [2555884][E](PTable): Success! + 352583 [2555913][E](Custom_C): 01 27 00 <-Power Tab Data + 352584 [2555969][E](Custom_C): 01 2a <-hMin + 352585 [2556013][E](Custom_C): 01 19 <-targetPosition + 352586 [2556070][E](Custom_C): 01 27 01 <-Power Tab Data + 352587 [2556103][E](Custom_C): 01 2b <-hMax + 352588 [2556184][E](Custom_C): 01 27 02 <-Power Tab Data + 352589 [2556234][E](Custom_C): 01 27 03 <-Power Tab Data + 352590 [2556307][E](Custom_C): 01 27 04 <-Power Tab Data + 352591 [2556340][E](Custom_C): 01 27 05 <-Power Tab Data + 352592 [2556408][E](Custom_C): 01 27 06 <-Power Tab Data + 352593 [2556509][E](Custom_C): 01 27 07 <-Power Tab Data + 352594 [2556585][E](PTable): Success! + 352595 [2556589][E](Custom_C): 01 27 08 <-Power Tab Data + 352596 [2556704][E](Custom_C): 01 27 09 <-Power Tab Data + 352597 [2556891][E](Custom_C): 01 19 <-targetPosition + 352598 [2557347][E](PTable): Success! + 352599 [2557348][E](PTable): Clean Power Table + 352600 [2557348][E](PTable): Averaged Entry: watts=124.000000, cad=84.800003, targetPosition=1190.00000, (5)(4) + 352601 [2557361][E](PTable): cellValue: (105) wattDelta: (2.142857) cadDelta: (0.357143) allNeighborsPassed: (0) + 352602 [2557366][E](PTable): rightValue: (0.000000) leftValue: (103.133331) bottomValue: (104.440010) topValue: (0.000000) New averaged targetPosition: (103.786667) count: (2) + 352603 [2557388][E](PTable): Bottom failed at: (103) Target pos: (103.786667) Avg pos: (103) + 352604 [2557389][E](PTable): Was not in range failed bottom (6)(4)(103), readings (9) + 352605 [2557399][E](PTable): WEIGHTED DOWNVOTING: Target Value: (103), NeighborValue: (103) + 352606 [2557410][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 352607 [2557410][E](PTable): PT failed (6)(4)(103), readings (9) + 352608 [2557422][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352609 [2557444][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352610 [2557478][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352611 [2557499][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352612 [2557532][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352613 [2557553][E](PTable): 80 rpm | | 58 | | | 108 | 119 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352614 [2557586][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352615 [2557608][E](PTable): 90 rpm | | | | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352616 [2557639][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352617 [2557661][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 352618 [2557694][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352619 [2557715][E](PTable): Power Table Reset + 352620 [2557903][E](Custom_C): 01 19 <-targetPosition + 352621 [2558049][E](PTable): Success! + 352622 [2558750][E](PTable): Success! + 352623 [2558894][E](Custom_C): 01 19 <-targetPosition + 352624 [2559452][E](PTable): Success! + 352625 [2559884][E](Custom_C): 01 19 <-targetPosition + 352626 [2560154][E](PTable): Success! + 352627 [2560155][E](PTable): Clean Power Table + 352628 [2560155][E](PTable): Averaged Entry: watts=128.000000, cad=83.800003, targetPosition=1190.00000, (5)(4) + 352629 [2560166][E](PTable): cellValue: (105) wattDelta: (2.142857) cadDelta: (0.357143) allNeighborsPassed: (0) + 352630 [2560177][E](PTable): rightValue: (0.000000) leftValue: (101.266663) bottomValue: (101.640007) topValue: (0.000000) New averaged targetPosition: (101.453339) count: (2) + 352631 [2560188][E](PTable): Bottom failed at: (103) Target pos: (101.453339) Avg pos: (102) + 352632 [2560199][E](PTable): All test failed bottom (4)(4)(108), readings (11) + 352633 [2560200][E](PTable): WEIGHTED DOWNVOTING: Target Value: (101), NeighborValue: (103) + 352634 [2560210][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 352635 [2560221][E](PTable): PT failed (6)(4)(103), readings (9) + 352636 [2560224][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352637 [2560246][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352638 [2560278][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352639 [2560299][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352640 [2560334][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352641 [2560356][E](PTable): 80 rpm | | 58 | | | 108 | 119 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352642 [2560388][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352643 [2560409][E](PTable): 90 rpm | | | | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352644 [2560442][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352645 [2560464][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 352646 [2560495][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352647 [2560516][E](PTable): Power Table Reset + 352648 [2560517][E](ERG_Mode): Proportional: 40.000000, Integral: -3.600000, Derivative: 0.800000 + 352649 [2560856][E](PTable): Success! + 352650 [2560896][E](Custom_C): 01 2a <-hMin + 352651 [2560945][E](Custom_C): 01 19 <-targetPosition + 352652 [2561009][E](Custom_C): 01 2b <-hMax + 352653 [2561563][E](PTable): Success! + 352654 [2561911][E](Custom_C): 01 19 <-targetPosition + 352655 [2562268][E](Custom_C): 01 25 <-Firmware Version + 352656 [2562274][E](PTable): Success! + 352657 [2562921][E](Custom_C): 01 19 <-targetPosition + 352658 [2562975][E](PTable): Success! + 352659 [2562976][E](PTable): Clean Power Table + 352660 [2562976][E](PTable): Averaged Entry: watts=122.000000, cad=82.800003, targetPosition=1195.99998, (5)(4) + 352661 [2562989][E](PTable): cellValue: (105) wattDelta: (2.054795) cadDelta: (0.342466) allNeighborsPassed: (0) + 352662 [2562991][E](PTable): rightValue: (0.000000) leftValue: (104.026665) bottomValue: (98.576012) topValue: (0.000000) New averaged targetPosition: (101.301338) count: (2) + 352663 [2563012][E](PTable): Bottom failed at: (103) Target pos: (101.301338) Avg pos: (102) + 352664 [2563014][E](PTable): All test failed bottom (4)(4)(108), readings (11) + 352665 [2563024][E](PTable): WEIGHTED DOWNVOTING: Target Value: (101), NeighborValue: (103) + 352666 [2563035][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 352667 [2563036][E](PTable): PT failed (6)(4)(103), readings (9) + 352668 [2563048][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352669 [2563070][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352670 [2563093][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352671 [2563125][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352672 [2563148][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352673 [2563179][E](PTable): 80 rpm | | 58 | | | 108 | 119 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352674 [2563204][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352675 [2563236][E](PTable): 90 rpm | | | | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352676 [2563259][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352677 [2563290][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 352678 [2563314][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352679 [2563335][E](PTable): Power Table Reset + 352680 [2563680][E](PTable): Success! + 352681 [2563877][E](Custom_C): 01 19 <-targetPosition + 352682 [2564382][E](PTable): Success! + 352683 [2564901][E](Custom_C): 01 19 <-targetPosition + 352684 [2565084][E](PTable): Success! + 352685 [2565786][E](PTable): Success! + 352686 [2565787][E](PTable): Clean Power Table + 352687 [2565787][E](PTable): Averaged Entry: watts=130.399994, cad=83.199997, targetPosition=1198.00003, (5)(4) + 352688 [2565799][E](PTable): cellValue: (105) wattDelta: (2.027027) cadDelta: (0.337838) allNeighborsPassed: (0) + 352689 [2565810][E](PTable): rightValue: (0.000000) leftValue: (99.869339) bottomValue: (99.671989) topValue: (0.000000) New averaged targetPosition: (99.770660) count: (2) + 352690 [2565821][E](PTable): Bottom failed at: (103) Target pos: (99.770660) Avg pos: (101) + 352691 [2565831][E](PTable): All test failed bottom (4)(4)(108), readings (11) + 352692 [2565832][E](PTable): WEIGHTED DOWNVOTING: Target Value: (99), NeighborValue: (103) + 352693 [2565842][E](PTable): WEIGHTED DOWNVOTING: Delta: (4), Penalty: (0) + 352694 [2565843][E](PTable): PT failed (6)(4)(103), readings (9) + 352695 [2565856][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352696 [2565878][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352697 [2565927][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352698 [2565948][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352699 [2565984][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352700 [2566017][E](PTable): 80 rpm | | 58 | | | 108 | 119 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352701 [2566037][E](Custom_C): 01 2b <-hMax + 352702 [2566051][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352703 [2566073][E](PTable): 90 rpm | | | | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352704 [2566095][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352705 [2566146][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 352706 [2566167][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352707 [2566198][E](PTable): Power Table Reset + 352708 [2566199][E](ERG_Mode): Proportional: -24.000000, Integral: -3.400000, Derivative: 0.200000 + 352709 [2566491][E](PTable): Success! + 352710 [2566881][E](Custom_C): 01 19 <-targetPosition + 352711 [2567195][E](PTable): Success! + 352712 [2567893][E](Custom_C): 01 19 <-targetPosition + 352713 [2567897][E](PTable): Success! + 352714 [2568601][E](PTable): Success! + 352715 [2568602][E](PTable): Clean Power Table + 352716 [2568603][E](PTable): Averaged Entry: watts=128.800003, cad=83.400002, targetPosition=1190.00000, (5)(4) + 352717 [2568615][E](PTable): cellValue: (105) wattDelta: (2.142857) cadDelta: (0.357143) allNeighborsPassed: (0) + 352718 [2568628][E](PTable): rightValue: (0.000000) leftValue: (100.893333) bottomValue: (100.520004) topValue: (0.000000) New averaged targetPosition: (100.706665) count: (2) + 352719 [2568640][E](PTable): Bottom failed at: (103) Target pos: (100.706665) Avg pos: (101) + 352720 [2568650][E](PTable): All test failed bottom (4)(4)(108), readings (11) + 352721 [2568651][E](PTable): WEIGHTED DOWNVOTING: Target Value: (100), NeighborValue: (103) + 352722 [2568661][E](PTable): WEIGHTED DOWNVOTING: Delta: (3), Penalty: (0) + 352723 [2568661][E](PTable): PT failed (6)(4)(103), readings (9) + 352724 [2568674][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352725 [2568696][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352726 [2568730][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352727 [2568752][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352728 [2568784][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352729 [2568805][E](PTable): 80 rpm | | 58 | | | 108 | 119 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352730 [2568839][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352731 [2568861][E](PTable): 90 rpm | | | | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352732 [2568894][E](Custom_C): 01 19 <-targetPosition + 352733 [2568898][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352734 [2568920][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 352735 [2568952][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352736 [2568973][E](PTable): Power Table Reset + 352737 [2569304][E](PTable): Success! + 352738 [2569897][E](Custom_C): 01 19 <-targetPosition + 352739 [2570005][E](PTable): Success! + 352740 [2570708][E](PTable): Success! + 352741 [2570921][E](Custom_C): 01 27 00 <-Power Tab Data + 352742 [2570952][E](Custom_C): 01 2a <-hMin + 352743 [2571021][E](Custom_C): 01 19 <-targetPosition + 352744 [2571090][E](Custom_C): 01 27 01 <-Power Tab Data + 352745 [2571132][E](Custom_C): 01 2b <-hMax + 352746 [2571190][E](Custom_C): 01 27 02 <-Power Tab Data + 352747 [2571235][E](Custom_C): 01 27 03 <-Power Tab Data + 352748 [2571280][E](Custom_C): 01 27 04 <-Power Tab Data + 352749 [2571348][E](Custom_C): 01 27 05 <-Power Tab Data + 352750 [2571393][E](Custom_C): 01 27 06 <-Power Tab Data + 352751 [2571412][E](PTable): Success! + 352752 [2571413][E](PTable): Clean Power Table + 352753 [2571413][E](PTable): Averaged Entry: watts=128.399994, cad=82.199997, targetPosition=1200.00000, (4)(4) + 352754 [2571424][E](PTable): cellValue: (108) wattDelta: (2.500000) cadDelta: (0.416667) allNeighborsPassed: (0) + 352755 [2571439][E](PTable): rightValue: (0.000000) leftValue: (104.639999) bottomValue: (113.279991) topValue: (0.000000) New averaged targetPosition: (108.959991) count: (2) + 352756 [2571484][E](PTable): Existing entry averaged (4)(4)(108), readings(11) + 352757 [2571551][E](Custom_C): 01 27 08 <-Power Tab Data + 352758 [2571595][E](Custom_C): 01 27 09 <-Power Tab Data + 352759 [2571899][E](Custom_C): 01 19 <-targetPosition + 352760 [2572015][E](Custom_C): 01 27 04 <-Power Tab Data + 352761 [2572024][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352762 [2572046][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352763 [2572078][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352764 [2572099][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352765 [2572132][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352766 [2572154][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 119 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352767 [2572185][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352768 [2572207][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352769 [2572239][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352770 [2572261][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352771 [2572293][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352772 [2572314][E](PTable): Power Table Reset + 352773 [2572315][E](ERG_Mode): Proportional: 16.000000, Integral: -1.400000, Derivative: 0.800000 + 352774 [2572696][E](PTable): Success! + 352775 [2572888][E](Custom_C): 01 19 <-targetPosition + 352776 [2573399][E](PTable): Success! + 352777 [2573901][E](Custom_C): 01 19 <-targetPosition + 352778 [2574101][E](PTable): Success! + 352779 [2574806][E](PTable): Success! + 352780 [2574807][E](PTable): Clean Power Table + 352781 [2574807][E](PTable): Averaged Entry: watts=123.599998, cad=81.800003, targetPosition=1200.00000, (4)(4) + 352782 [2574819][E](PTable): cellValue: (108) wattDelta: (2.500000) cadDelta: (0.416667) allNeighborsPassed: (0) + 352783 [2574830][E](PTable): rightValue: (0.000000) leftValue: (106.559998) bottomValue: (112.320007) topValue: (0.000000) New averaged targetPosition: (109.440002) count: (2) + 352784 [2574841][E](PTable): Existing entry averaged (4)(4)(108), readings(11) + 352785 [2574916][E](Custom_C): 01 19 <-targetPosition + 352786 [2575388][E](Custom_C): 01 27 04 <-Power Tab Data + 352787 [2575393][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352788 [2575415][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352789 [2575448][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352790 [2575469][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352791 [2575501][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352792 [2575523][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 119 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352793 [2575555][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352794 [2575577][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352795 [2575609][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352796 [2575633][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352797 [2575665][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352798 [2575687][E](PTable): Power Table Reset + 352799 [2575706][E](PTable): Success! + 352800 [2575881][E](Custom_C): 01 2a <-hMin + 352801 [2575949][E](Custom_C): 01 19 <-targetPosition + 352802 [2575998][E](Custom_C): 01 2b <-hMax + 352803 [2576408][E](PTable): Success! + 352804 [2576893][E](Custom_C): 01 19 <-targetPosition + 352805 [2577109][E](PTable): Success! + 352806 [2577813][E](PTable): Success! + 352807 [2577814][E](PTable): Clean Power Table + 352808 [2577814][E](PTable): Averaged Entry: watts=122.800003, cad=81.599998, targetPosition=1205.99998, (4)(4) + 352809 [2577826][E](PTable): cellValue: (108) wattDelta: (2.380953) cadDelta: (0.396825) allNeighborsPassed: (0) + 352810 [2577836][E](PTable): rightValue: (0.000000) leftValue: (106.823997) bottomValue: (112.031998) topValue: (0.000000) New averaged targetPosition: (109.427994) count: (2) + 352811 [2577848][E](PTable): Existing entry averaged (4)(4)(108), readings(11) + 352812 [2577884][E](Custom_C): 01 19 <-targetPosition + 352813 [2578371][E](Custom_C): 01 27 04 <-Power Tab Data + 352814 [2578377][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352815 [2578400][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352816 [2578432][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352817 [2578453][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352818 [2578486][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352819 [2578508][E](PTable): 80 rpm | 36 | 58 | 88 | | 108 | 119 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352820 [2578539][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352821 [2578561][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352822 [2578594][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352823 [2578615][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352824 [2578647][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352825 [2578668][E](PTable): Power Table Reset + 352826 [2578679][E](ERG_Mode): Proportional: 8.000000, Integral: 2.200000, Derivative: -0.800000 + 352827 [2578880][E](PTable): Success! + 352828 [2578897][E](Custom_C): 01 19 <-targetPosition + 352829 [2579580][E](PTable): Success! + 352830 [2579911][E](Custom_C): 01 19 <-targetPosition + 352831 [2580284][E](PTable): Success! + 352832 [2580898][E](Custom_C): 01 2a <-hMin + 352833 [2580977][E](Custom_C): 01 19 <-targetPosition + 352834 [2580985][E](PTable): Success! + 352835 [2580987][E](PTable): Clean Power Table + 352836 [2580987][E](PTable): Averaged Entry: watts=130.800003, cad=81.000000, targetPosition=1210.00000, (4)(4) + 352837 [2580999][E](PTable): cellValue: (108) wattDelta: (2.307692) cadDelta: (0.384615) allNeighborsPassed: (0) + 352838 [2581015][E](Custom_C): 01 2b <-hMax + 352839 [2581023][E](PTable): rightValue: (0.000000) leftValue: (103.320000) bottomValue: (110.599998) topValue: (0.000000) New averaged targetPosition: (106.959999) count: (2) + 352840 [2581036][E](PTable): Existing entry averaged (4)(4)(107), readings(11) + 352841 [2581575][E](Custom_C): 01 27 04 <-Power Tab Data + 352842 [2581581][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352843 [2581602][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352844 [2581634][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352845 [2581656][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352846 [2581689][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352847 [2581710][E](PTable): 80 rpm | 36 | 58 | 88 | | 107 | 119 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352848 [2581742][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352849 [2581764][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352850 [2581796][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352851 [2581818][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352852 [2581842][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352853 [2581873][E](PTable): Power Table Reset + 352854 [2581887][E](Custom_C): 01 19 <-targetPosition + 352855 [2581896][E](PTable): Success! + 352856 [2582293][E](Custom_C): 01 25 <-Firmware Version + 352857 [2582601][E](PTable): Success! + 352858 [2582900][E](Custom_C): 01 19 <-targetPosition + 352859 [2583304][E](PTable): Success! + 352860 [2583890][E](Custom_C): 01 19 <-targetPosition + 352861 [2584006][E](PTable): Success! + 352862 [2584007][E](PTable): Clean Power Table + 352863 [2584007][E](PTable): Averaged Entry: watts=132.399994, cad=81.000000, targetPosition=1210.00000, (4)(4) + 352864 [2584018][E](PTable): cellValue: (107) wattDelta: (2.142857) cadDelta: (0.357143) allNeighborsPassed: (0) + 352865 [2584029][E](PTable): rightValue: (0.000000) leftValue: (101.213333) bottomValue: (109.800003) topValue: (0.000000) New averaged targetPosition: (105.506668) count: (2) + 352866 [2584040][E](PTable): Bottom failed at: (105) Target pos: (105.506668) Avg pos: (105) + 352867 [2584051][E](PTable): Was not in range failed bottom (5)(4)(105), readings (11) + 352868 [2584051][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (105) + 352869 [2584062][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 352870 [2584072][E](PTable): PT failed (5)(4)(105), readings (11) + 352871 [2584074][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352872 [2584106][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352873 [2584127][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352874 [2584159][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352875 [2584181][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352876 [2584214][E](PTable): 80 rpm | | 58 | | | 107 | 119 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352877 [2584236][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352878 [2584258][E](PTable): 90 rpm | | | | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352879 [2584290][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352880 [2584313][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 352881 [2584344][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352882 [2584365][E](PTable): Power Table Reset + 352883 [2584376][E](ERG_Mode): Proportional: 24.000000, Integral: 2.200000, Derivative: 0.600000 + 352884 [2584709][E](PTable): Success! + 352885 [2584881][E](Custom_C): 01 19 <-targetPosition + 352886 [2585414][E](PTable): Success! + 352887 [2585415][E](PTable): Using detected travel limits during homing + 352888 [2585905][E](Custom_C): 01 27 00 <-Power Tab Data + 352889 [2585961][E](Custom_C): 01 2a <-hMin + 352890 [2586016][E](Custom_C): 01 19 <-targetPosition + 352891 [2586063][E](Custom_C): 01 27 01 <-Power Tab Data + 352892 [2586095][E](Custom_C): 01 2b <-hMax + 352893 [2586119][E](PTable): Success! + 352894 [2586154][E](Custom_C): 01 27 02 <-Power Tab Data + 352895 [2586210][E](Custom_C): 01 27 03 <-Power Tab Data + 352896 [2586266][E](Custom_C): 01 27 04 <-Power Tab Data + 352897 [2586310][E](Custom_C): 01 27 05 <-Power Tab Data + 352898 [2586389][E](Custom_C): 01 27 06 <-Power Tab Data + 352899 [2586446][E](Custom_C): 01 27 07 <-Power Tab Data + 352900 [2586502][E](Custom_C): 01 27 08 <-Power Tab Data + 352901 [2586569][E](Custom_C): 01 27 09 <-Power Tab Data + 352902 [2586613][E](Custom_C): 01 25 <-Firmware Version + 352903 [2586831][E](PTable): Success! + 352904 [2586832][E](PTable): Clean Power Table + 352905 [2586832][E](PTable): Averaged Entry: watts=129.600006, cad=81.199997, targetPosition=1210.00000, (4)(4) + 352906 [2586843][E](PTable): cellValue: (107) wattDelta: (2.142857) cadDelta: (0.357143) allNeighborsPassed: (0) + 352907 [2586857][E](PTable): rightValue: (0.000000) leftValue: (102.519997) bottomValue: (110.359993) topValue: (0.000000) New averaged targetPosition: (106.439995) count: (2) + 352908 [2586872][E](PTable): Existing entry averaged (4)(4)(106), readings(11) + 352909 [2586884][E](Custom_C): 01 19 <-targetPosition + 352910 [2587406][E](Custom_C): 01 27 04 <-Power Tab Data + 352911 [2587413][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352912 [2587435][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352913 [2587467][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352914 [2587492][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352915 [2587514][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352916 [2587546][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 119 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352917 [2587568][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352918 [2587600][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352919 [2587623][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352920 [2587654][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352921 [2587677][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352922 [2587708][E](PTable): Power Table Reset + 352923 [2587726][E](PTable): Success! + 352924 [2587921][E](Custom_C): 01 19 <-targetPosition + 352925 [2588428][E](PTable): Success! + 352926 [2588931][E](Custom_C): 01 19 <-targetPosition + 352927 [2589131][E](PTable): Success! + 352928 [2589835][E](PTable): Success! + 352929 [2589836][E](PTable): Clean Power Table + 352930 [2589836][E](PTable): Averaged Entry: watts=133.600006, cad=82.599998, targetPosition=1210.00000, (5)(4) + 352931 [2589847][E](PTable): cellValue: (105) wattDelta: (1.875000) cadDelta: (0.312500) allNeighborsPassed: (0) + 352932 [2589858][E](PTable): rightValue: (0.000000) leftValue: (97.746666) bottomValue: (97.319992) topValue: (0.000000) New averaged targetPosition: (97.533325) count: (2) + 352933 [2589869][E](PTable): Bottom failed at: (103) Target pos: (97.533325) Avg pos: (100) + 352934 [2589880][E](PTable): All test failed bottom (4)(4)(106), readings (11) + 352935 [2589880][E](PTable): WEIGHTED DOWNVOTING: Target Value: (97), NeighborValue: (103) + 352936 [2589891][E](PTable): WEIGHTED DOWNVOTING: Delta: (6), Penalty: (1) + 352937 [2589902][E](Custom_C): 01 19 <-targetPosition + 352938 [2589904][E](PTable): PT failed (6)(4)(103), readings (8) + 352939 [2589907][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352940 [2589929][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352941 [2589962][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352942 [2589984][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352943 [2590016][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352944 [2590037][E](PTable): 80 rpm | | 58 | | | 106 | 119 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352945 [2590069][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352946 [2590091][E](PTable): 90 rpm | | | | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352947 [2590123][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 352948 [2590146][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 352949 [2590178][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 352950 [2590199][E](PTable): Power Table Reset + 352951 [2590209][E](ERG_Mode): Proportional: -8.000000, Integral: 0.200000, Derivative: -0.400000 + 352952 [2590538][E](PTable): Success! + 352953 [2590888][E](Custom_C): 01 2a <-hMin + 352954 [2590932][E](Custom_C): 01 19 <-targetPosition + 352955 [2591000][E](Custom_C): 01 2b <-hMax + 352956 [2591242][E](PTable): Success! + 352957 [2591901][E](Custom_C): 01 19 <-targetPosition + 352958 [2591944][E](PTable): Success! + 352959 [2592645][E](PTable): Success! + 352960 [2592646][E](PTable): Clean Power Table + 352961 [2592646][E](PTable): Averaged Entry: watts=132.000000, cad=82.000000, targetPosition=1204.00002, (4)(4) + 352962 [2592657][E](PTable): cellValue: (106) wattDelta: (2.083333) cadDelta: (0.347222) allNeighborsPassed: (0) + 352963 [2592669][E](PTable): rightValue: (0.000000) leftValue: (100.239998) bottomValue: (111.760002) topValue: (0.000000) New averaged targetPosition: (106.000000) count: (2) + 352964 [2592680][E](PTable): Existing entry averaged (4)(4)(106), readings(11) + 352965 [2592891][E](Custom_C): 01 19 <-targetPosition + 352966 [2593221][E](Custom_C): 01 27 04 <-Power Tab Data + 352967 [2593227][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 352968 [2593251][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 352969 [2593283][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 352970 [2593307][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 352971 [2593329][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 352972 [2593362][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 119 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 352973 [2593383][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 124 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 352974 [2593416][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 352975 [2593437][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 352976 [2593470][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 352977 [2593492][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 352978 [2593524][E](PTable): Power Table Reset + 352979 [2593539][E](FTMS_SERVER): 05 36 01 -> ERG Mode Target: 310 Current: 128 Incline: 120.895996 + 352980 [2593546][E](Custom_C): 01 28 <-targetWatts + 352981 [2593547][E](PTable): Success! + 352982 [2593548][E](PTable): Lookup debug 270 X1 330 X2 75 Y1 85 Y2 -nan + 352983 [2593559][E](PTable): Lookup used neighbors L 150 R 158 R1 155 + 352984 [2593560][E](PTable): Lookup used neighbors U 164 D 152 R2 157 + 352985 [2593560][E](PTable): Lookup used actual 153 R3 153 + 352986 [2593571][E](PTable): Lookup result: 310w 81cad 15400 + 352987 [2593572][E](ERG_Mode): SetPoint changed:310w PowerTable Result: 15400 + 352988 [2593881][E](Custom_C): 01 19 <-targetPosition + 352989 [2593906][E](PTable): Success! + 352990 [2594606][E](PTable): Success! + 352991 [2594893][E](Custom_C): 01 19 <-targetPosition + 352992 [2595308][E](PTable): Power Table Reset + 352993 [2595309][E](ERG_Mode): Proportional: 744.000000, Integral: 24.600000, Derivative: 1.200000 + 352994 [2595884][E](Custom_C): 01 2a <-hMin + 352995 [2595928][E](Custom_C): 01 19 <-targetPosition + 352996 [2595996][E](Custom_C): 01 2b <-hMax + 352997 [2596011][E](PTable): Success! + 352998 [2596714][E](PTable): Success! + 352999 [2596918][E](Custom_C): 01 19 <-targetPosition + 353000 [2597418][E](PTable): Success! + 353001 [2597897][E](Custom_C): 01 19 <-targetPosition + 353002 [2598120][E](PTable): Success! + 353003 [2598120][E](PTable): Clean Power Table + 353004 [2598121][E](PTable): Averaged Entry: watts=188.000000, cad=84.599998, targetPosition=1463.99994, (5)(6) + 353005 [2598132][E](PTable): cellValue: (124) wattDelta: (1.339286) cadDelta: (0.223214) allNeighborsPassed: (0) + 353006 [2598143][E](PTable): rightValue: (0.000000) leftValue: (118.026672) bottomValue: (122.207993) topValue: (0.000000) New averaged targetPosition: (120.117332) count: (2) + 353007 [2598154][E](PTable): Existing entry averaged (5)(6)(123), readings(11) + 353008 [2598687][E](Custom_C): 01 27 05 <-Power Tab Data + 353009 [2598693][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353010 [2598714][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353011 [2598747][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 353012 [2598769][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 353013 [2598801][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 353014 [2598822][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 119 | 131 | 139 | 145 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 353015 [2598854][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 123 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 353016 [2598876][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353017 [2598926][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353018 [2598949][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353019 [2598971][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353020 [2599003][E](PTable): Power Table Reset + 353021 [2599020][E](PTable): Success! + 353022 [2599725][E](PTable): Success! + 353023 [2599888][E](Custom_C): 01 19 <-targetPosition + 353024 [2600430][E](PTable): Success! + 353025 [2600431][E](ERG_Mode): Proportional: 256.000000, Integral: 12.400001, Derivative: -0.400000 + 353026 [2600936][E](Custom_C): 01 27 00 <-Power Tab Data + 353027 [2600967][E](Custom_C): 01 2a <-hMin + 353028 [2601013][E](Custom_C): 01 19 <-targetPosition + 353029 [2601070][E](Custom_C): 01 27 01 <-Power Tab Data + 353030 [2601103][E](Custom_C): 01 2b <-hMax + 353031 [2601132][E](PTable): Success! + 353032 [2601133][E](PTable): Clean Power Table + 353033 [2601133][E](PTable): Averaged Entry: watts=245.600006, cad=80.599998, targetPosition=1533.99994, (4)(8) + 353034 [2601144][E](PTable): cellValue: (145) wattDelta: (3.571431) cadDelta: (0.595239) allNeighborsPassed: (0) + 353035 [2601156][E](PTable): rightValue: (0.000000) leftValue: (143.432007) bottomValue: (146.007996) topValue: (0.000000) New averaged targetPosition: (144.720001) count: (2) + 353036 [2601203][E](PTable): Existing entry averaged (4)(8)(144), readings(8) + 353037 [2601250][E](Custom_C): 01 27 03 <-Power Tab Data + 353038 [2601296][E](Custom_C): 01 27 04 <-Power Tab Data + 353039 [2601363][E](Custom_C): 01 27 05 <-Power Tab Data + 353040 [2601431][E](Custom_C): 01 27 06 <-Power Tab Data + 353041 [2601475][E](Custom_C): 01 27 07 <-Power Tab Data + 353042 [2601543][E](Custom_C): 01 27 08 <-Power Tab Data + 353043 [2601588][E](Custom_C): 01 27 09 <-Power Tab Data + 353044 [2601828][E](Custom_C): 01 27 04 <-Power Tab Data + 353045 [2601834][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353046 [2601856][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353047 [2601890][E](Custom_C): 01 19 <-targetPosition + 353048 [2601894][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 353049 [2601916][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 353050 [2601948][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 353051 [2601969][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 119 | 131 | 139 | 144 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 353052 [2602002][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 123 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 353053 [2602025][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353054 [2602058][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353055 [2602079][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353056 [2602114][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353057 [2602134][E](PTable): Power Table Reset + 353058 [2602274][E](Custom_C): 01 25 <-Firmware Version + 353059 [2602504][E](PTable): Success! + 353060 [2602881][E](Custom_C): 01 19 <-targetPosition + 353061 [2603208][E](PTable): Success! + 353062 [2603893][E](Custom_C): 01 19 <-targetPosition + 353063 [2603914][E](PTable): Success! + 353064 [2604616][E](PTable): Success! + 353065 [2604617][E](PTable): Clean Power Table + 353066 [2604617][E](PTable): Averaged Entry: watts=310.000000, cad=81.199997, targetPosition=1570.00000, (4)(10) + 353067 [2604628][E](PTable): cellValue: (153) wattDelta: (7.500000) cadDelta: (1.250000) allNeighborsPassed: (1) + 353068 [2604639][E](PTable): rightValue: (154.333328) leftValue: (151.666672) bottomValue: (153.959991) topValue: (152.040009) New averaged targetPosition: (153.000000) count: (4) + 353069 [2604650][E](PTable): Existing entry averaged (4)(10)(153), readings(11) + 353070 [2604917][E](Custom_C): 01 19 <-targetPosition + 353071 [2605185][E](Custom_C): 01 27 04 <-Power Tab Data + 353072 [2605190][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353073 [2605212][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353074 [2605244][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 191 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 353075 [2605266][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 353076 [2605299][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 353077 [2605320][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 119 | 131 | 139 | 144 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 353078 [2605352][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 123 | 133 | 143 | 145 | 152 | | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 353079 [2605374][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353080 [2605406][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353081 [2605428][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353082 [2605460][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353083 [2605480][E](PTable): Power Table Reset + 353084 [2605491][E](ERG_Mode): Proportional: 48.000000, Integral: 6.600000, Derivative: 1.200000 + 353085 [2605509][E](PTable): Success! + 353086 [2605907][E](Custom_C): 01 2a <-hMin + 353087 [2605963][E](Custom_C): 01 19 <-targetPosition + 353088 [2606053][E](Custom_C): 01 2b <-hMax + 353089 [2606099][E](Custom_C): 01 25 <-Firmware Version + 353090 [2606210][E](PTable): Success! + 353091 [2606897][E](Custom_C): 01 19 <-targetPosition + 353092 [2606915][E](PTable): Success! + 353093 [2607616][E](PTable): Success! + 353094 [2607617][E](PTable): Clean Power Table + 353095 [2607617][E](PTable): Averaged Entry: watts=321.200012, cad=82.599998, targetPosition=1563.99994, (5)(11) + 353096 [2607628][E](PTable): Keep old targetPosition: (156.399994) + 353097 [2607629][E](PTable): New entry recorded (5)(11)(156) + 353098 [2607898][E](Custom_C): 01 19 <-targetPosition + 353099 [2608159][E](Custom_C): 01 27 05 <-Power Tab Data + 353100 [2608165][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353101 [2608187][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353102 [2608219][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 353103 [2608240][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 353104 [2608273][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 353105 [2608298][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 119 | 131 | 139 | 144 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 353106 [2608320][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 123 | 133 | 143 | 145 | 152 | 156 | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 353107 [2608352][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353108 [2608374][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353109 [2608405][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353110 [2608427][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353111 [2608458][E](PTable): Power Table Reset + 353112 [2608655][E](PTable): Success! + 353113 [2608888][E](Custom_C): 01 19 <-targetPosition + 353114 [2609356][E](PTable): Success! + 353115 [2609878][E](Custom_C): 01 19 <-targetPosition + 353116 [2610057][E](PTable): Success! + 353117 [2610760][E](PTable): Success! + 353118 [2610760][E](PTable): Clean Power Table + 353119 [2610760][E](PTable): Averaged Entry: watts=311.600006, cad=83.000000, targetPosition=1560.00000, (5)(10) + 353120 [2610772][E](PTable): cellValue: (152) wattDelta: (7.500000) cadDelta: (1.250000) allNeighborsPassed: (0) + 353121 [2610783][E](PTable): rightValue: (0.000000) leftValue: (150.453339) bottomValue: (150.399994) topValue: (0.000000) New averaged targetPosition: (150.426666) count: (2) + 353122 [2610794][E](PTable): Existing entry averaged (5)(10)(151), readings(4) + 353123 [2610891][E](Custom_C): 01 2a <-hMin + 353124 [2610936][E](Custom_C): 01 19 <-targetPosition + 353125 [2610980][E](Custom_C): 01 2b <-hMax + 353126 [2611342][E](Custom_C): 01 27 05 <-Power Tab Data + 353127 [2611348][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353128 [2611370][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353129 [2611401][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 353130 [2611424][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 353131 [2611456][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 353132 [2611478][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 119 | 131 | 139 | 144 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 353133 [2611510][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 123 | 133 | 143 | 145 | 151 | 156 | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 353134 [2611533][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353135 [2611565][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353136 [2611587][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353137 [2611619][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353138 [2611640][E](PTable): Power Table Reset + 353139 [2611641][E](ERG_Mode): Proportional: -88.000000, Integral: 0.400000, Derivative: -1.200000 + 353140 [2611668][E](PTable): Success! + 353141 [2611904][E](Custom_C): 01 19 <-targetPosition + 353142 [2612373][E](PTable): Success! + 353143 [2612893][E](Custom_C): 01 19 <-targetPosition + 353144 [2613074][E](PTable): Success! + 353145 [2613779][E](PTable): Success! + 353146 [2613780][E](PTable): Clean Power Table + 353147 [2613780][E](PTable): Averaged Entry: watts=306.000000, cad=84.199997, targetPosition=1560.00000, (5)(10) + 353148 [2613791][E](PTable): cellValue: (151) wattDelta: (6.000000) cadDelta: (1.000000) allNeighborsPassed: (0) + 353149 [2613802][E](PTable): rightValue: (0.000000) leftValue: (150.000000) bottomValue: (150.199997) topValue: (0.000000) New averaged targetPosition: (150.100006) count: (2) + 353150 [2613813][E](PTable): Existing entry averaged (5)(10)(150), readings(5) + 353151 [2613917][E](Custom_C): 01 19 <-targetPosition + 353152 [2614339][E](Custom_C): 01 27 05 <-Power Tab Data + 353153 [2614345][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353154 [2614367][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353155 [2614402][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 353156 [2614424][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 353157 [2614455][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 353158 [2614477][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 119 | 131 | 139 | 144 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 353159 [2614510][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 123 | 133 | 143 | 145 | 150 | 156 | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 353160 [2614531][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353161 [2614563][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353162 [2614585][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353163 [2614617][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353164 [2614638][E](PTable): Power Table Reset + 353165 [2614866][E](PTable): Success! + 353166 [2614896][E](Custom_C): 01 19 <-targetPosition + 353167 [2615570][E](PTable): Success! + 353168 [2615909][E](Custom_C): 01 27 00 <-Power Tab Data + 353169 [2615978][E](Custom_C): 01 2a <-hMin + 353170 [2616020][E](Custom_C): 01 19 <-targetPosition + 353171 [2616100][E](Custom_C): 01 27 01 <-Power Tab Data + 353172 [2616132][E](Custom_C): 01 2b <-hMax + 353173 [2616190][E](Custom_C): 01 27 02 <-Power Tab Data + 353174 [2616235][E](Custom_C): 01 27 03 <-Power Tab Data + 353175 [2616274][E](PTable): Success! + 353176 [2616280][E](Custom_C): 01 27 04 <-Power Tab Data + 353177 [2616350][E](Custom_C): 01 27 05 <-Power Tab Data + 353178 [2616394][E](Custom_C): 01 27 06 <-Power Tab Data + 353179 [2616450][E](Custom_C): 01 27 07 <-Power Tab Data + 353180 [2616505][E](Custom_C): 01 27 08 <-Power Tab Data + 353181 [2616552][E](Custom_C): 01 27 09 <-Power Tab Data + 353182 [2616898][E](Custom_C): 01 19 <-targetPosition + 353183 [2617045][E](PTable): Success! + 353184 [2617046][E](PTable): Clean Power Table + 353185 [2617047][E](PTable): Averaged Entry: watts=302.000000, cad=83.400002, targetPosition=1568.00003, (5)(10) + 353186 [2617060][E](PTable): cellValue: (150) wattDelta: (4.411763) cadDelta: (0.735294) allNeighborsPassed: (0) + 353187 [2617067][E](PTable): rightValue: (0.000000) leftValue: (149.546661) bottomValue: (147.824005) topValue: (0.000000) New averaged targetPosition: (148.685333) count: (2) + 353188 [2617089][E](PTable): Existing entry averaged (5)(10)(149), readings(6) + 353189 [2617608][E](Custom_C): 01 27 05 <-Power Tab Data + 353190 [2617614][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353191 [2617636][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353192 [2617668][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 353193 [2617690][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 353194 [2617722][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 353195 [2617743][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 119 | 131 | 139 | 144 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 353196 [2617775][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 123 | 133 | 143 | 145 | 149 | 156 | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 353197 [2617798][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353198 [2617830][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353199 [2617852][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353200 [2617885][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353201 [2617905][E](PTable): Power Table Reset + 353202 [2617916][E](Custom_C): 01 19 <-targetPosition + 353203 [2617919][E](ERG_Mode): Proportional: -120.000000, Integral: 2.800000, Derivative: -4.000000 + 353204 [2617937][E](PTable): Success! + 353205 [2618639][E](PTable): Success! + 353206 [2618900][E](Custom_C): 01 19 <-targetPosition + 353207 [2619344][E](PTable): Success! + 353208 [2619879][E](Custom_C): 01 19 <-targetPosition + 353209 [2620047][E](PTable): Success! + 353210 [2620048][E](PTable): Clean Power Table + 353211 [2620048][E](PTable): Averaged Entry: watts=335.200012, cad=85.599998, targetPosition=1566.00006, (5)(11) + 353212 [2620060][E](PTable): cellValue: (156) wattDelta: (49.999493) cadDelta: (8.333248) allNeighborsPassed: (1) + 353213 [2620071][E](PTable): rightValue: (156.104004) leftValue: (155.895996) bottomValue: (156.072006) topValue: (155.927994) New averaged targetPosition: (156.000000) count: (4) + 353214 [2620082][E](PTable): Existing entry averaged (5)(11)(156), readings(1) + 353215 [2620617][E](Custom_C): 01 27 05 <-Power Tab Data + 353216 [2620623][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353217 [2620648][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353218 [2620680][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 353219 [2620702][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 353220 [2620734][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 353221 [2620756][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 119 | 131 | 139 | 144 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 353222 [2620789][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 123 | 133 | 143 | 145 | 149 | 156 | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 353223 [2620811][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353224 [2620842][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353225 [2620864][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353226 [2620910][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353227 [2620931][E](PTable): Power Table Reset + 353228 [2620951][E](Custom_C): 01 19 <-targetPosition + 353229 [2621016][E](Custom_C): 01 2b <-hMax + 353230 [2621169][E](PTable): Success! + 353231 [2621873][E](PTable): Success! + 353232 [2621893][E](Custom_C): 01 19 <-targetPosition + 353233 [2622275][E](Custom_C): 01 25 <-Firmware Version + 353234 [2622574][E](PTable): Success! + 353235 [2622883][E](Custom_C): 01 19 <-targetPosition + 353236 [2623275][E](PTable): Success! + 353237 [2623276][E](PTable): Clean Power Table + 353238 [2623276][E](PTable): Averaged Entry: watts=324.000000, cad=85.599998, targetPosition=1538.00003, (5)(11) + 353239 [2623287][E](PTable): cellValue: (156) wattDelta: (13.636382) cadDelta: (2.272730) allNeighborsPassed: (1) + 353240 [2623298][E](PTable): rightValue: (151.160004) leftValue: (152.040009) bottomValue: (151.863998) topValue: (151.336014) New averaged targetPosition: (151.600006) count: (4) + 353241 [2623309][E](PTable): Existing entry averaged (5)(11)(154), readings(2) + 353242 [2623822][E](Custom_C): 01 27 05 <-Power Tab Data + 353243 [2623829][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353244 [2623851][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353245 [2623883][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 353246 [2623928][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 353247 [2623950][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 353248 [2623982][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 119 | 131 | 139 | 144 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 353249 [2624004][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 123 | 133 | 143 | 145 | 149 | 154 | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 353250 [2624027][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353251 [2624059][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353252 [2624081][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353253 [2624112][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353254 [2624133][E](PTable): Power Table Reset + 353255 [2624144][E](ERG_Mode): Proportional: 88.000000, Integral: -2.800000, Derivative: 1.200000 + 353256 [2624160][E](FTMS_SERVER): 05 82 00 -> ERG Mode Target: 130 Current: 300 Incline: 154.834000 + 353257 [2624169][E](Custom_C): 01 28 <-targetWatts + 353258 [2624172][E](PTable): Success! + 353259 [2624173][E](PTable): Lookup debug 60 X1 150 X2 80 Y1 90 Y2 -nan + 353260 [2624174][E](PTable): Lookup used neighbors L 84 R 108 R1 103 + 353261 [2624187][E](PTable): Lookup used neighbors U 106 D 103 R2 105 + 353262 [2624187][E](PTable): Lookup used actual 105 R3 105 + 353263 [2624188][E](PTable): Lookup result: 130w 84cad 10300 + 353264 [2624199][E](ERG_Mode): SetPoint changed:130w PowerTable Result: 10300 + 353265 [2624199][E](ERG_Mode): Capping ERG seek time to 5 seconds + 353266 [2624209][E](PTable): Using detected travel limits during homing + 353267 [2624520][E](PTable): Success! + 353268 [2624897][E](Custom_C): 01 19 <-targetPosition + 353269 [2625223][E](PTable): Success! + 353270 [2625897][E](Custom_C): 01 2a <-hMin + 353271 [2625926][E](PTable): Power Table Reset + 353272 [2625942][E](Custom_C): 01 19 <-targetPosition + 353273 [2626011][E](Custom_C): 01 2b <-hMax + 353274 [2626055][E](Custom_C): 01 25 <-Firmware Version + 353275 [2626629][E](PTable): Success! + 353276 [2626888][E](Custom_C): 01 19 <-targetPosition + 353277 [2627330][E](PTable): Success! + 353278 [2627878][E](Custom_C): 01 19 <-targetPosition + 353279 [2628034][E](PTable): Success! + 353280 [2628737][E](PTable): Success! + 353281 [2628738][E](PTable): Clean Power Table + 353282 [2628738][E](PTable): Averaged Entry: watts=220.000000, cad=83.599998, targetPosition=1298.00003, (5)(7) + 353283 [2628750][E](PTable): cellValue: (133) wattDelta: (9.375009) cadDelta: (1.562502) allNeighborsPassed: (1) + 353284 [2628760][E](PTable): rightValue: (127.666672) leftValue: (125.533340) bottomValue: (125.704010) topValue: (127.496010) New averaged targetPosition: (126.600006) count: (4) + 353285 [2628771][E](PTable): Existing entry averaged (5)(7)(132), readings(8) + 353286 [2628890][E](Custom_C): 01 19 <-targetPosition + 353287 [2629283][E](Custom_C): 01 27 05 <-Power Tab Data + 353288 [2629289][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353289 [2629311][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353290 [2629344][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 353291 [2629366][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 353292 [2629398][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 353293 [2629420][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 119 | 131 | 139 | 144 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 353294 [2629454][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 123 | 132 | 143 | 145 | 149 | 154 | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 353295 [2629476][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353296 [2629508][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353297 [2629529][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353298 [2629562][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353299 [2629583][E](PTable): Power Table Reset + 353300 [2629583][E](ERG_Mode): Proportional: -200.000000, Integral: -11.000000, Derivative: -0.400000 + 353301 [2629611][E](PTable): Success! + 353302 [2629908][E](Custom_C): 01 19 <-targetPosition + 353303 [2630314][E](PTable): Success! + 353304 [2630928][E](Custom_C): 01 27 00 <-Power Tab Data + 353305 [2630961][E](Custom_C): 01 2a <-hMin + 353306 [2631019][E](PTable): Success! + 353307 [2631030][E](Custom_C): 01 19 <-targetPosition + 353308 [2631086][E](Custom_C): 01 27 01 <-Power Tab Data + 353309 [2631141][E](Custom_C): 01 2b <-hMax + 353310 [2631210][E](Custom_C): 01 27 02 <-Power Tab Data + 353311 [2631265][E](Custom_C): 01 27 03 <-Power Tab Data + 353312 [2631333][E](Custom_C): 01 27 04 <-Power Tab Data + 353313 [2631389][E](Custom_C): 01 27 05 <-Power Tab Data + 353314 [2631445][E](Custom_C): 01 27 06 <-Power Tab Data + 353315 [2631490][E](Custom_C): 01 27 07 <-Power Tab Data + 353316 [2631569][E](Custom_C): 01 27 08 <-Power Tab Data + 353317 [2631648][E](Custom_C): 01 27 09 <-Power Tab Data + 353318 [2631721][E](PTable): Success! + 353319 [2631723][E](PTable): Clean Power Table + 353320 [2631723][E](PTable): Averaged Entry: watts=170.000000, cad=82.000000, targetPosition=1248.00003, (4)(6) + 353321 [2631735][E](PTable): cellValue: (131) wattDelta: (4.838712) cadDelta: (0.806452) allNeighborsPassed: (1) + 353322 [2631746][E](PTable): rightValue: (116.533340) leftValue: (120.666672) bottomValue: (121.080002) topValue: (116.120010) New averaged targetPosition: (118.600006) count: (4) + 353323 [2631757][E](PTable): Left failed at: (119) Target pos: (118.600006) Avg pos: (118) + 353324 [2631768][E](PTable): Current Position moved left was valid! Current position: 118.600006 + 353325 [2631769][E](PTable): Existing entry averaged (4)(5)(118), readings(11) + 353326 [2631883][E](Custom_C): 01 19 <-targetPosition + 353327 [2632288][E](PTable): Bottom failed at: (123) Target pos: (118.600006) Avg pos: (120) + 353328 [2632290][E](PTable): Current Position moved down is valid! Current position: 118.600006 + 353329 [2632301][E](PTable): Existing entry averaged (5)(6)(122), readings(11) + 353330 [2632444][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353331 [2632467][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353332 [2632489][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 353333 [2632521][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 353334 [2632543][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 353335 [2632575][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 353336 [2632597][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 353337 [2632630][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 107 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353338 [2632651][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353339 [2632683][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 103 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353340 [2632705][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 101 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353341 [2632736][E](PTable): Power Table Reset + 353342 [2632896][E](Custom_C): 01 19 <-targetPosition + 353343 [2633130][E](PTable): Success! + 353344 [2633834][E](PTable): Success! + 353345 [2633897][E](Custom_C): 01 19 <-targetPosition + 353346 [2634537][E](PTable): Success! + 353347 [2634898][E](Custom_C): 01 19 <-targetPosition + 353348 [2635239][E](PTable): Success! + 353349 [2635240][E](PTable): Clean Power Table + 353350 [2635240][E](PTable): Averaged Entry: watts=139.199997, cad=83.599998, targetPosition=1215.99998, (5)(5) + 353351 [2635251][E](PTable): cellValue: (108) wattDelta: (2.205883) cadDelta: (0.367647) allNeighborsPassed: (0) + 353352 [2635254][E](PTable): rightValue: (103.103996) leftValue: (112.896004) bottomValue: (104.192001) topValue: (0.000000) New averaged targetPosition: (106.730675) count: (3) + 353353 [2635275][E](PTable): Bottom failed at: (107) Target pos: (106.730675) Avg pos: (106) + 353354 [2635286][E](PTable): Current Position moved down is valid! Current position: 106.730675 + 353355 [2635287][E](PTable): Existing entry averaged (6)(5)(106), readings(11) + 353356 [2635781][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353357 [2635806][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353358 [2635828][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 353359 [2635860][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 353360 [2635881][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 353361 [2635927][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 353362 [2635949][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 353363 [2635984][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353364 [2636018][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353365 [2636060][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353366 [2636082][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353367 [2636113][E](PTable): Power Table Reset + 353368 [2636114][E](ERG_Mode): Proportional: 24.000000, Integral: -5.400000, Derivative: 2.600000 + 353369 [2636143][E](PTable): Success! + 353370 [2636845][E](PTable): Success! + 353371 [2636878][E](Custom_C): 01 19 <-targetPosition + 353372 [2637548][E](PTable): Success! + 353373 [2637890][E](Custom_C): 01 19 <-targetPosition + 353374 [2638252][E](PTable): Success! + 353375 [2638253][E](PTable): Clean Power Table + 353376 [2638253][E](PTable): Averaged Entry: watts=138.800003, cad=83.199997, targetPosition=1205.99998, (5)(5) + 353377 [2638264][E](PTable): cellValue: (108) wattDelta: (2.380953) cadDelta: (0.396825) allNeighborsPassed: (0) + 353378 [2638276][E](PTable): rightValue: (103.296005) leftValue: (112.703995) bottomValue: (103.463989) topValue: (0.000000) New averaged targetPosition: (106.487999) count: (3) + 353379 [2638287][E](PTable): Bottom failed at: (106) Target pos: (106.487999) Avg pos: (106) + 353380 [2638298][E](PTable): Was not in range failed bottom (6)(5)(106), readings (11) + 353381 [2638298][E](PTable): WEIGHTED DOWNVOTING: Target Value: (106), NeighborValue: (106) + 353382 [2638309][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 353383 [2638319][E](PTable): PT failed (6)(5)(106), readings (11) + 353384 [2638321][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353385 [2638343][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353386 [2638375][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353387 [2638397][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353388 [2638429][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353389 [2638451][E](PTable): 80 rpm | | 58 | | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353390 [2638483][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353391 [2638505][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353392 [2638537][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353393 [2638560][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 353394 [2638592][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353395 [2638612][E](PTable): Power Table Reset + 353396 [2638905][E](Custom_C): 01 19 <-targetPosition + 353397 [2638954][E](PTable): Success! + 353398 [2639656][E](PTable): Success! + 353399 [2639895][E](Custom_C): 01 19 <-targetPosition + 353400 [2640358][E](PTable): Success! + 353401 [2640883][E](Custom_C): 01 2a <-hMin + 353402 [2641007][E](Custom_C): 01 19 <-targetPosition + 353403 [2641065][E](Custom_C): 01 2b <-hMax + 353404 [2641070][E](PTable): Success! + 353405 [2641071][E](PTable): Clean Power Table + 353406 [2641071][E](PTable): Averaged Entry: watts=122.000000, cad=85.599998, targetPosition=1205.99998, (5)(4) + 353407 [2641083][E](PTable): cellValue: (105) wattDelta: (1.923077) cadDelta: (0.320513) allNeighborsPassed: (0) + 353408 [2641094][E](PTable): rightValue: (0.000000) leftValue: (103.959999) bottomValue: (106.871994) topValue: (0.000000) New averaged targetPosition: (105.416000) count: (2) + 353409 [2641106][E](PTable): Existing entry averaged (5)(4)(105), readings(11) + 353410 [2641597][E](Custom_C): 01 27 05 <-Power Tab Data + 353411 [2641602][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353412 [2641624][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353413 [2641657][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 353414 [2641679][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 353415 [2641711][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 353416 [2641734][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 353417 [2641766][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 353418 [2641788][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353419 [2641820][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353420 [2641845][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353421 [2641867][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353422 [2641898][E](Custom_C): 01 19 <-targetPosition + 353423 [2641901][E](PTable): Power Table Reset + 353424 [2641902][E](ERG_Mode): Proportional: 0.000000, Integral: -4.400000, Derivative: -0.400000 + 353425 [2642176][E](PTable): Success! + 353426 [2642279][E](Custom_C): 01 25 <-Firmware Version + 353427 [2642877][E](PTable): Success! + 353428 [2642896][E](Custom_C): 01 19 <-targetPosition + 353429 [2643579][E](PTable): Success! + 353430 [2643897][E](Custom_C): 01 19 <-targetPosition + 353431 [2644280][E](PTable): Success! + 353432 [2644281][E](PTable): Clean Power Table + 353433 [2644281][E](PTable): Averaged Entry: watts=143.199997, cad=85.599998, targetPosition=1200.00000, (5)(5) + 353434 [2644296][E](PTable): cellValue: (108) wattDelta: (2.500000) cadDelta: (0.416667) allNeighborsPassed: (0) + 353435 [2644297][E](PTable): rightValue: (105.279999) leftValue: (110.720001) bottomValue: (109.439995) topValue: (0.000000) New averaged targetPosition: (108.480003) count: (3) + 353436 [2644318][E](PTable): Existing entry averaged (5)(5)(108), readings(11) + 353437 [2644836][E](Custom_C): 01 27 05 <-Power Tab Data + 353438 [2644841][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353439 [2644863][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353440 [2644894][E](Custom_C): 01 19 <-targetPosition + 353441 [2644898][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 353442 [2644930][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 353443 [2644954][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 353444 [2644976][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 353445 [2645008][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 353446 [2645030][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353447 [2645063][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353448 [2645084][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353449 [2645116][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353450 [2645137][E](PTable): Power Table Reset + 353451 [2645167][E](PTable): Success! + 353452 [2645871][E](PTable): Success! + 353453 [2645913][E](Custom_C): 01 27 00 <-Power Tab Data + 353454 [2645957][E](Custom_C): 01 2a <-hMin + 353455 [2645991][E](Custom_C): 01 19 <-targetPosition + 353456 [2646049][E](Custom_C): 01 27 01 <-Power Tab Data + 353457 [2646081][E](Custom_C): 01 2b <-hMax + 353458 [2646149][E](Custom_C): 01 27 02 <-Power Tab Data + 353459 [2646205][E](Custom_C): 01 27 03 <-Power Tab Data + 353460 [2646251][E](Custom_C): 01 27 04 <-Power Tab Data + 353461 [2646306][E](Custom_C): 01 27 05 <-Power Tab Data + 353462 [2646339][E](Custom_C): 01 27 06 <-Power Tab Data + 353463 [2646408][E](Custom_C): 01 27 07 <-Power Tab Data + 353464 [2646455][E](Custom_C): 01 27 08 <-Power Tab Data + 353465 [2646522][E](Custom_C): 01 27 09 <-Power Tab Data + 353466 [2646578][E](Custom_C): 01 25 <-Firmware Version + 353467 [2646617][E](PTable): Success! + 353468 [2646891][E](Custom_C): 01 19 <-targetPosition + 353469 [2647318][E](PTable): Success! + 353470 [2647319][E](PTable): Clean Power Table + 353471 [2647319][E](PTable): Averaged Entry: watts=133.600006, cad=83.800003, targetPosition=1191.99997, (5)(4) + 353472 [2647331][E](PTable): cellValue: (105) wattDelta: (2.112677) cadDelta: (0.352113) allNeighborsPassed: (0) + 353473 [2647341][E](PTable): rightValue: (0.000000) leftValue: (98.562668) bottomValue: (101.592010) topValue: (0.000000) New averaged targetPosition: (100.077339) count: (2) + 353474 [2647353][E](PTable): Bottom failed at: (103) Target pos: (100.077339) Avg pos: (101) + 353475 [2647363][E](PTable): All test failed bottom (4)(4)(106), readings (11) + 353476 [2647364][E](PTable): WEIGHTED DOWNVOTING: Target Value: (100), NeighborValue: (103) + 353477 [2647374][E](PTable): WEIGHTED DOWNVOTING: Delta: (3), Penalty: (0) + 353478 [2647375][E](PTable): PT failed (6)(4)(103), readings (8) + 353479 [2647387][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353480 [2647409][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353481 [2647440][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353482 [2647463][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353483 [2647496][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353484 [2647519][E](PTable): 80 rpm | | 58 | | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353485 [2647551][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353486 [2647573][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353487 [2647605][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353488 [2647627][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 353489 [2647659][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353490 [2647682][E](PTable): Power Table Reset + 353491 [2647683][E](ERG_Mode): Proportional: -8.000000, Integral: -6.200000, Derivative: 0.800000 + 353492 [2647903][E](Custom_C): 01 19 <-targetPosition + 353493 [2648045][E](PTable): Success! + 353494 [2648749][E](PTable): Success! + 353495 [2648892][E](Custom_C): 01 19 <-targetPosition + 353496 [2649451][E](PTable): Success! + 353497 [2649883][E](Custom_C): 01 19 <-targetPosition + 353498 [2650154][E](PTable): Success! + 353499 [2650155][E](PTable): Clean Power Table + 353500 [2650155][E](PTable): Averaged Entry: watts=133.600006, cad=84.199997, targetPosition=1190.00000, (5)(4) + 353501 [2650166][E](PTable): cellValue: (105) wattDelta: (2.142857) cadDelta: (0.357143) allNeighborsPassed: (0) + 353502 [2650179][E](PTable): rightValue: (0.000000) leftValue: (98.653328) bottomValue: (102.759995) topValue: (0.000000) New averaged targetPosition: (100.706665) count: (2) + 353503 [2650190][E](PTable): Bottom failed at: (103) Target pos: (100.706665) Avg pos: (101) + 353504 [2650201][E](PTable): All test failed bottom (4)(4)(106), readings (11) + 353505 [2650203][E](PTable): WEIGHTED DOWNVOTING: Target Value: (100), NeighborValue: (103) + 353506 [2650214][E](PTable): WEIGHTED DOWNVOTING: Delta: (3), Penalty: (0) + 353507 [2650214][E](PTable): PT failed (6)(4)(103), readings (8) + 353508 [2650226][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353509 [2650248][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353510 [2650281][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353511 [2650304][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353512 [2650336][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353513 [2650358][E](PTable): 80 rpm | | 58 | | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353514 [2650380][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353515 [2650411][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353516 [2650443][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353517 [2650465][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 353518 [2650497][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353519 [2650518][E](PTable): Power Table Reset + 353520 [2650858][E](PTable): Success! + 353521 [2650895][E](Custom_C): 01 2a <-hMin + 353522 [2650939][E](Custom_C): 01 19 <-targetPosition + 353523 [2650998][E](Custom_C): 01 2b <-hMax + 353524 [2651559][E](PTable): Success! + 353525 [2651897][E](Custom_C): 01 19 <-targetPosition + 353526 [2652263][E](PTable): Success! + 353527 [2652921][E](Custom_C): 01 19 <-targetPosition + 353528 [2652965][E](PTable): Success! + 353529 [2652966][E](PTable): Clean Power Table + 353530 [2652966][E](PTable): Averaged Entry: watts=142.000000, cad=86.000000, targetPosition=1175.99998, (5)(5) + 353531 [2652978][E](PTable): cellValue: (108) wattDelta: (3.125000) cadDelta: (0.520833) allNeighborsPassed: (1) + 353532 [2652989][E](PTable): rightValue: (105.440002) leftValue: (110.559998) bottomValue: (109.919998) topValue: (106.080002) New averaged targetPosition: (108.000000) count: (4) + 353533 [2653000][E](PTable): Existing entry averaged (5)(5)(108), readings(11) + 353534 [2653519][E](Custom_C): 01 27 05 <-Power Tab Data + 353535 [2653527][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353536 [2653549][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353537 [2653582][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | 231 | 232 | 235 | | | | | | | | | | | | + 353538 [2653604][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | | | | | | 214 | 216 | | 225 | 229 | | | | | | | | | | + 353539 [2653636][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 181 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | | | 224 | 227 | | | | | | | | | | + 353540 [2653661][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 171 | 181 | 184 | 185 | | | 186 | 187 | 188 | 189 | 199 | | 209 | 213 | 215 | | 223 | 226 | | | | | | | | | | + 353541 [2653683][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | | 198 | 203 | 208 | 212 | 214 | 220 | | 225 | | | | | | | | | | + 353542 [2653715][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353543 [2653737][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353544 [2653769][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353545 [2653791][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353546 [2653824][E](PTable): Power Table Reset + 353547 [2653824][E](ERG_Mode): Proportional: -24.000000, Integral: -6.200000, Derivative: -1.000000 + 353548 [2653889][E](Custom_C): 01 19 <-targetPosition + 353549 [2654103][E](FTMS_SERVER): 05 59 01 -> ERG Mode Target: 345 Current: 132 Incline: 117.397995 + 353550 [2654112][E](Custom_C): 01 28 <-targetWatts + 353551 [2654115][E](PTable): Success! + 353552 [2654115][E](PTable): Lookup debug 330 X1 390 X2 80 Y1 90 Y2 -nan + 353553 [2654116][E](PTable): Lookup used neighbors L 154 R 172 R1 158 + 353554 [2654128][E](PTable): Lookup used neighbors U 171 D 152 R2 160 + 353555 [2654133][E](PTable): Lookup used actual 160 R3 160 + 353556 [2654133][E](PTable): Lookup result: 345w 86cad 15900 + 353557 [2654144][E](ERG_Mode): SetPoint changed:345w PowerTable Result: 15900 + 353558 [2654150][E](PTable): Success! + 353559 [2654854][E](PTable): Success! + 353560 [2654900][E](Custom_C): 01 19 <-targetPosition + 353561 [2655559][E](PTable): Power Table Reset + 353562 [2655891][E](Custom_C): 01 2a <-hMin + 353563 [2655946][E](Custom_C): 01 19 <-targetPosition + 353564 [2655980][E](Custom_C): 01 2b <-hMax + 353565 [2656263][E](PTable): Success! + 353566 [2656880][E](Custom_C): 01 19 <-targetPosition + 353567 [2656965][E](PTable): Success! + 353568 [2657666][E](PTable): Success! + 353569 [2657892][E](Custom_C): 01 19 <-targetPosition + 353570 [2658370][E](PTable): Success! + 353571 [2658371][E](PTable): Clean Power Table + 353572 [2658371][E](PTable): Averaged Entry: watts=224.800003, cad=84.400002, targetPosition=1636.00006, (5)(7) + 353573 [2658382][E](PTable): cellValue: (132) wattDelta: (0.949367) cadDelta: (0.158228) allNeighborsPassed: (0) + 353574 [2658393][E](PTable): rightValue: (0.000000) leftValue: (116.410660) bottomValue: (128.208008) topValue: (0.000000) New averaged targetPosition: (122.309334) count: (2) + 353575 [2658404][E](PTable): Left failed at: (122) Target pos: (122.309334) Avg pos: (122) + 353576 [2658415][E](PTable): Was not in range failed left (5)(6)(122), readings (11) + 353577 [2658415][E](PTable): WEIGHTED DOWNVOTING: Target Value: (122), NeighborValue: (122) + 353578 [2658426][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 353579 [2658427][E](PTable): PT failed (5)(6)(122), readings (11) + 353580 [2658438][E](PTable): Bottom failed at: (124) Target pos: (122.309334) Avg pos: (123) + 353581 [2658449][E](PTable): All test failed bottom (4)(7)(139), readings (2) + 353582 [2658449][E](PTable): WEIGHTED DOWNVOTING: Target Value: (122), NeighborValue: (124) + 353583 [2658459][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 353584 [2658460][E](PTable): PT failed (6)(7)(124), readings (9) + 353585 [2658474][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353586 [2658496][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353587 [2658528][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353588 [2658550][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353589 [2658582][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 157 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353590 [2658603][E](PTable): 80 rpm | | 58 | | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 171 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353591 [2658636][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353592 [2658657][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353593 [2658689][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353594 [2658711][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 353595 [2658743][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353596 [2658764][E](PTable): Power Table Reset + 353597 [2658884][E](Custom_C): 01 19 <-targetPosition + 353598 [2659075][E](PTable): Success! + 353599 [2659076][E](ERG_Mode): Proportional: -60.000000, Integral: 4.500000, Derivative: -6.400000 + 353600 [2659779][E](PTable): Success! + 353601 [2659896][E](Custom_C): 01 19 <-targetPosition + 353602 [2660481][E](PTable): Success! + 353603 [2660944][E](Custom_C): 01 27 00 <-Power Tab Data + 353604 [2660975][E](Custom_C): 01 2a <-hMin + 353605 [2661020][E](Custom_C): 01 19 <-targetPosition + 353606 [2661088][E](Custom_C): 01 27 01 <-Power Tab Data + 353607 [2661132][E](Custom_C): 01 2b <-hMax + 353608 [2661184][E](PTable): Success! + 353609 [2661190][E](Custom_C): 01 27 02 <-Power Tab Data + 353610 [2661215][E](PTable): Averaged Entry: watts=361.200012, cad=81.000000, targetPosition=1676.00006, (4)(12) + 353611 [2661216][E](PTable): cellValue: (171) wattDelta: (8.823545) cadDelta: (1.470591) allNeighborsPassed: (1) + 353612 [2661228][E](PTable): rightValue: (164.336014) leftValue: (164.064011) bottomValue: (164.880005) topValue: (163.520020) New averaged targetPosition: (164.200012) count: (4) + 353613 [2661239][E](PTable): Existing entry averaged (4)(12)(169), readings(3) + 353614 [2661269][E](Custom_C): 01 27 03 <-Power Tab Data + 353615 [2661325][E](Custom_C): 01 27 04 <-Power Tab Data + 353616 [2661370][E](Custom_C): 01 27 05 <-Power Tab Data + 353617 [2661460][E](Custom_C): 01 27 06 <-Power Tab Data + 353618 [2661505][E](Custom_C): 01 27 07 <-Power Tab Data + 353619 [2661550][E](Custom_C): 01 27 08 <-Power Tab Data + 353620 [2661594][E](Custom_C): 01 27 09 <-Power Tab Data + 353621 [2661823][E](Custom_C): 01 27 04 <-Power Tab Data + 353622 [2661829][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353623 [2661852][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353624 [2661884][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | | | | | 232 | | | | | | | | | | + 353625 [2661905][E](Custom_C): 01 19 <-targetPosition + 353626 [2661910][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | 213 | 214 | | | | 215 | 217 | 218 | 225 | 231 | | | | | | | | | | + 353627 [2661943][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 179 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | 216 | | 224 | 228 | | | | | | | | | | + 353628 [2661965][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 181 | 184 | 185 | | 186 | | 187 | 188 | 191 | 206 | | 209 | 214 | 215 | | 223 | 226 | | | | | | | | | | + 353629 [2661997][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | 189 | 200 | 203 | 208 | 213 | 214 | | | 225 | | | | | | | | | | + 353630 [2662020][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353631 [2662042][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353632 [2662074][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353633 [2662096][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353634 [2662129][E](PTable): Power Table Reset + 353635 [2662130][E](PTable): Using detected travel limits during homing + 353636 [2662281][E](Custom_C): 01 25 <-Firmware Version + 353637 [2662507][E](PTable): Success! + 353638 [2662887][E](Custom_C): 01 19 <-targetPosition + 353639 [2663210][E](PTable): Success! + 353640 [2663900][E](Custom_C): 01 19 <-targetPosition + 353641 [2663914][E](PTable): Success! + 353642 [2664617][E](PTable): Success! + 353643 [2664618][E](PTable): Clean Power Table + 353644 [2664618][E](PTable): Averaged Entry: watts=350.399994, cad=82.800003, targetPosition=1660.00000, (5)(12) + 353645 [2664629][E](PTable): cellValue: (160) wattDelta: (5.000000) cadDelta: (0.833333) allNeighborsPassed: (1) + 353646 [2664640][E](PTable): rightValue: (158.080002) leftValue: (161.919998) bottomValue: (157.360001) topValue: (162.639999) New averaged targetPosition: (160.000000) count: (4) + 353647 [2664651][E](PTable): Existing entry averaged (5)(12)(160), readings(10) + 353648 [2664912][E](Custom_C): 01 19 <-targetPosition + 353649 [2665184][E](Custom_C): 01 27 05 <-Power Tab Data + 353650 [2665194][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353651 [2665216][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353652 [2665238][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | | | | | 232 | | | | | | | | | | + 353653 [2665271][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | 213 | 214 | | | | 215 | 217 | 218 | 225 | 231 | | | | | | | | | | + 353654 [2665293][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 179 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | 216 | | 224 | 228 | | | | | | | | | | + 353655 [2665325][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 181 | 184 | 185 | | 186 | | 187 | 188 | 191 | 206 | | 209 | 214 | 215 | | 223 | 226 | | | | | | | | | | + 353656 [2665347][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | 189 | 200 | 203 | 208 | 213 | 214 | | | 225 | | | | | | | | | | + 353657 [2665379][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353658 [2665401][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353659 [2665433][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353660 [2665455][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353661 [2665486][E](PTable): Power Table Reset + 353662 [2665486][E](ERG_Mode): Proportional: 20.000000, Integral: -0.200000, Derivative: 2.200000 + 353663 [2665515][E](PTable): Success! + 353664 [2665936][E](Custom_C): 01 2a <-hMin + 353665 [2665992][E](Custom_C): 01 19 <-targetPosition + 353666 [2666037][E](Custom_C): 01 2b <-hMax + 353667 [2666082][E](Custom_C): 01 25 <-Firmware Version + 353668 [2666217][E](PTable): Success! + 353669 [2666893][E](Custom_C): 01 19 <-targetPosition + 353670 [2666922][E](PTable): Success! + 353671 [2667623][E](PTable): Success! + 353672 [2667624][E](PTable): Clean Power Table + 353673 [2667624][E](PTable): Averaged Entry: watts=350.399994, cad=82.800003, targetPosition=1653.99994, (5)(12) + 353674 [2667635][E](PTable): cellValue: (160) wattDelta: (5.555562) cadDelta: (0.925927) allNeighborsPassed: (1) + 353675 [2667648][E](PTable): rightValue: (158.272003) leftValue: (161.727997) bottomValue: (157.624008) topValue: (162.375992) New averaged targetPosition: (160.000000) count: (4) + 353676 [2667659][E](PTable): Existing entry averaged (5)(12)(160), readings(11) + 353677 [2667883][E](Custom_C): 01 19 <-targetPosition + 353678 [2668176][E](Custom_C): 01 27 05 <-Power Tab Data + 353679 [2668182][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353680 [2668204][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353681 [2668236][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | | | | | 232 | | | | | | | | | | + 353682 [2668258][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | 213 | 214 | | | | 215 | 217 | 218 | 225 | 231 | | | | | | | | | | + 353683 [2668290][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 179 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | 216 | | 224 | 228 | | | | | | | | | | + 353684 [2668312][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 181 | 184 | 185 | | 186 | | 187 | 188 | 191 | 206 | | 209 | 214 | 215 | | 223 | 226 | | | | | | | | | | + 353685 [2668344][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | 189 | 200 | 203 | 208 | 213 | 214 | | | 225 | | | | | | | | | | + 353686 [2668366][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353687 [2668398][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353688 [2668421][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353689 [2668452][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353690 [2668473][E](PTable): Power Table Reset + 353691 [2668733][E](PTable): Success! + 353692 [2668896][E](Custom_C): 01 19 <-targetPosition + 353693 [2669438][E](PTable): Success! + 353694 [2669908][E](Custom_C): 01 19 <-targetPosition + 353695 [2670141][E](PTable): Success! + 353696 [2670843][E](PTable): Success! + 353697 [2670844][E](PTable): Clean Power Table + 353698 [2670844][E](PTable): Averaged Entry: watts=315.200012, cad=78.400002, targetPosition=1658.00003, (4)(11) + 353699 [2670856][E](PTable): cellValue: (158) wattDelta: (3.846152) cadDelta: (0.641025) allNeighborsPassed: (1) + 353700 [2670867][E](PTable): rightValue: (154.152008) leftValue: (161.847992) bottomValue: (155.503998) topValue: (160.496002) New averaged targetPosition: (158.000000) count: (4) + 353701 [2670878][E](PTable): Existing entry averaged (4)(11)(158), readings(9) + 353702 [2670897][E](Custom_C): 01 2a <-hMin + 353703 [2670976][E](Custom_C): 01 19 <-targetPosition + 353704 [2671009][E](Custom_C): 01 2b <-hMax + 353705 [2671418][E](Custom_C): 01 27 04 <-Power Tab Data + 353706 [2671423][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353707 [2671446][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353708 [2671478][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | | | | | 232 | | | | | | | | | | + 353709 [2671499][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | 213 | 214 | | | | 215 | 217 | 218 | 225 | 231 | | | | | | | | | | + 353710 [2671532][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 179 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | 216 | | 224 | 228 | | | | | | | | | | + 353711 [2671554][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 181 | 184 | 185 | | 186 | | 187 | 188 | 191 | 206 | | 209 | 214 | 215 | | 223 | 226 | | | | | | | | | | + 353712 [2671586][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | 189 | 200 | 203 | 208 | 213 | 214 | | | 225 | | | | | | | | | | + 353713 [2671607][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353714 [2671641][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353715 [2671665][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353716 [2671686][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353717 [2671718][E](PTable): Power Table Reset + 353718 [2671718][E](ERG_Mode): Proportional: 180.000000, Integral: 8.200000, Derivative: 1.600000 + 353719 [2671751][E](PTable): Success! + 353720 [2671911][E](Custom_C): 01 19 <-targetPosition + 353721 [2672453][E](PTable): Success! + 353722 [2672900][E](Custom_C): 01 19 <-targetPosition + 353723 [2673156][E](PTable): Success! + 353724 [2673858][E](PTable): Success! + 353725 [2673859][E](PTable): Clean Power Table + 353726 [2673859][E](PTable): Averaged Entry: watts=300.399994, cad=76.199997, targetPosition=1688.00003, (3)(10) + 353727 [2673870][E](PTable): cellValue: (164) wattDelta: (6.249996) cadDelta: (1.041666) allNeighborsPassed: (1) + 353728 [2673881][E](PTable): rightValue: (164.063995) leftValue: (163.936005) bottomValue: (165.151993) topValue: (162.848007) New averaged targetPosition: (164.000000) count: (4) + 353729 [2673892][E](PTable): Existing entry averaged (3)(10)(164), readings(4) + 353730 [2673912][E](Custom_C): 01 19 <-targetPosition + 353731 [2674399][E](Custom_C): 01 27 03 <-Power Tab Data + 353732 [2674408][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353733 [2674431][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353734 [2674463][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | | | | | 232 | | | | | | | | | | + 353735 [2674484][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | 213 | 214 | | | | 215 | 217 | 218 | 225 | 231 | | | | | | | | | | + 353736 [2674517][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 179 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | 216 | | 224 | 228 | | | | | | | | | | + 353737 [2674538][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 181 | 184 | 185 | | 186 | | 187 | 188 | 191 | 206 | | 209 | 214 | 215 | | 223 | 226 | | | | | | | | | | + 353738 [2674570][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | 189 | 200 | 203 | 208 | 213 | 214 | | | 225 | | | | | | | | | | + 353739 [2674592][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353740 [2674624][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353741 [2674645][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353742 [2674677][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353743 [2674902][E](Custom_C): 01 19 <-targetPosition + 353744 [2674944][E](PTable): Writing File: /PowerTable.txt + 353745 [2675905][E](Custom_C): 01 27 00 <-Power Tab Data + 353746 [2675916][E](PTable): Power table saved successfully with 93 readings + 353747 [2675917][E](PTable): Power Table Reset + 353748 [2675961][E](Custom_C): 01 2a <-hMin + 353749 [2676028][E](Custom_C): 01 19 <-targetPosition + 353750 [2676109][E](Custom_C): 01 27 01 <-Power Tab Data + 353751 [2676144][E](Custom_C): 01 2b <-hMax + 353752 [2676221][E](Custom_C): 01 27 02 <-Power Tab Data + 353753 [2676270][E](PTable): Success! + 353754 [2676297][E](Custom_C): 01 27 03 <-Power Tab Data + 353755 [2676359][E](Custom_C): 01 27 04 <-Power Tab Data + 353756 [2676424][E](Custom_C): 01 27 05 <-Power Tab Data + 353757 [2676491][E](Custom_C): 01 27 06 <-Power Tab Data + 353758 [2676535][E](Custom_C): 01 27 07 <-Power Tab Data + 353759 [2676604][E](Custom_C): 01 27 08 <-Power Tab Data + 353760 [2676661][E](Custom_C): 01 27 09 <-Power Tab Data + 353761 [2676882][E](Custom_C): 01 19 <-targetPosition + 353762 [2676975][E](PTable): Success! + 353763 [2676976][E](ERG_Mode): Proportional: 228.000000, Integral: 11.700000, Derivative: -0.200000 + 353764 [2677679][E](PTable): Success! + 353765 [2677895][E](Custom_C): 01 19 <-targetPosition + 353766 [2678380][E](PTable): Success! + 353767 [2678381][E](PTable): Clean Power Table + 353768 [2678381][E](PTable): Averaged Entry: watts=289.200012, cad=73.599998, targetPosition=1723.99994, (3)(10) + 353769 [2678393][E](PTable): cellValue: (164) wattDelta: (3.571431) cadDelta: (0.595239) allNeighborsPassed: (1) + 353770 [2678404][E](PTable): rightValue: (160.976013) leftValue: (167.023987) bottomValue: (161.647995) topValue: (166.352005) New averaged targetPosition: (164.000000) count: (4) + 353771 [2678415][E](PTable): Existing entry averaged (3)(10)(164), readings(5) + 353772 [2678885][E](Custom_C): 01 19 <-targetPosition + 353773 [2678934][E](Custom_C): 01 27 03 <-Power Tab Data + 353774 [2678940][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353775 [2678963][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | | | | | | | | | | + 353776 [2678995][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 210 | 213 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | 227 | 229 | 230 | | | | | 232 | | | | | | | | | | + 353777 [2679017][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 200 | 203 | 206 | 207 | 208 | 209 | 211 | 213 | 214 | | | | 215 | 217 | 218 | 225 | 231 | | | | | | | | | | + 353778 [2679049][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 179 | 190 | 193 | 196 | 199 | 200 | | | | 201 | | 204 | 210 | | 216 | | 224 | 228 | | | | | | | | | | + 353779 [2679070][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 181 | 184 | 185 | | 186 | | 187 | 188 | 191 | 206 | | 209 | 214 | 215 | | 223 | 226 | | | | | | | | | | + 353780 [2679102][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 172 | 174 | 175 | | 176 | 181 | 185 | 187 | 189 | 200 | 203 | 208 | 213 | 214 | | | 225 | | | | | | | | | | + 353781 [2679124][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | | | 197 | 202 | 206 | 210 | 212 | 217 | 222 | | | | | | | | | | | + 353782 [2679156][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 186 | | 196 | 200 | 205 | 208 | | 216 | 221 | | | | | | | | | | | + 353783 [2679178][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 185 | | 194 | 199 | 203 | 207 | | | | | | | | | | | | | | + 353784 [2679209][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353785 [2679230][E](PTable): Power Table Reset + 353786 [2679491][E](PTable): Success! + 353787 [2679897][E](Custom_C): 01 19 <-targetPosition + 353788 [2680193][E](PTable): Success! + 353789 [2680887][E](Custom_C): 01 2a <-hMin + 353790 [2680896][E](PTable): Success! + 353791 [2680932][E](Custom_C): 01 19 <-targetPosition + 353792 [2681022][E](Custom_C): 01 2b <-hMax + 353793 [2681599][E](PTable): Success! + 353794 [2681600][E](PTable): Clean Power Table + 353795 [2681600][E](PTable): Averaged Entry: watts=428.799988, cad=82.000000, targetPosition=1706.00006, (4)(14) + 353796 [2681611][E](PTable): Keep old targetPosition: (170.600006) + 353797 [2681612][E](PTable): Left failed at: (181) Target pos: (170.600006) Avg pos: (175) + 353798 [2681623][E](PTable): Current Position moved left was valid! Current position: 170.600006 + 353799 [2681634][E](PTable): Existing entry averaged (4)(13)(175), readings(1) + 353800 [2681900][E](Custom_C): 01 19 <-targetPosition + 353801 [2682260][E](Custom_C): 01 25 <-Firmware Version + 353802 [2682409][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353803 [2682433][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 353804 [2682456][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | 216 | 217 | | | | | | | | | 218 | 233 | 239 | 240 | | | | | | | | | | + 353805 [2682490][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 163 | 169 | 176 | 189 | 194 | 197 | | | | | | | 199 | 201 | 202 | | 213 | | 227 | 236 | 238 | | | | | | | | | | + 353806 [2682514][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 157 | 164 | 173 | 179 | 183 | 185 | | | | | 188 | 193 | 197 | 200 | 201 | 217 | | | 222 | 234 | 236 | | | | | | | | | | + 353807 [2682537][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 175 | 177 | | 178 | 179 | 182 | 187 | 192 | 196 | 199 | 200 | 212 | | | 219 | 232 | 234 | | | | | | | | | | + 353808 [2682569][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 175 | | 176 | 181 | 185 | 190 | 194 | 198 | 199 | 208 | 212 | 217 | 218 | 229 | 232 | | | | | | | | | | + 353809 [2682593][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | 189 | 193 | 197 | 198 | 206 | 211 | 216 | 217 | 227 | 230 | | | | | | | | | | + 353810 [2682625][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 187 | 191 | 195 | | 205 | 209 | 213 | 216 | 225 | 228 | | | | | | | | | | + 353811 [2682647][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 186 | 190 | 194 | | 203 | 208 | | | 222 | 226 | | | | | | | | | | + 353812 [2682679][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353813 [2682700][E](PTable): Power Table Reset + 353814 [2682701][E](ERG_Mode): Proportional: 52.000000, Integral: -4.700000, Derivative: 5.200000 + 353815 [2682890][E](Custom_C): 01 19 <-targetPosition + 353816 [2682980][E](PTable): Success! + 353817 [2683482][E](FTMS_SERVER): 05 82 00 -> ERG Mode Target: 130 Current: 274 Incline: 170.551987 + 353818 [2683490][E](Custom_C): 01 28 <-targetWatts + 353819 [2683684][E](PTable): Success! + 353820 [2683685][E](PTable): Lookup debug 90 X1 150 X2 70 Y1 80 Y2 -28072597855658832489169139049937346553876994564836862117658371403771055066555426859690436400329759714521683831737342949146297107947636215625790622980374528 + 353821 [2683698][E](PTable): Lookup used neighbors L 109 R 125 R1 120 + 353822 [2683708][E](PTable): Lookup used neighbors U 126 D 106 R2 120 + 353823 [2683709][E](PTable): Lookup used actual 113 R3 113 + 353824 [2683719][E](PTable): Lookup result: 130w 73cad 11700 + 353825 [2683720][E](ERG_Mode): SetPoint changed:130w PowerTable Result: 11700 + 353826 [2683731][E](ERG_Mode): Capping ERG seek time to 5 seconds + 353827 [2683737][E](PTable): Success! + 353828 [2683881][E](Custom_C): 01 19 <-targetPosition + 353829 [2684442][E](PTable): Success! + 353830 [2684444][E](PTable): Clean Power Table + 353831 [2684444][E](PTable): Averaged Entry: watts=280.000000, cad=72.800003, targetPosition=1671.99997, (3)(9) + 353832 [2684455][E](PTable): cellValue: (157) wattDelta: (2.941177) cadDelta: (0.490196) allNeighborsPassed: (0) + 353833 [2684467][E](PTable): rightValue: (0.000000) leftValue: (153.600006) bottomValue: (152.512009) topValue: (161.487991) New averaged targetPosition: (155.866684) count: (3) + 353834 [2684478][E](PTable): Existing entry averaged (3)(9)(156), readings(11) + 353835 [2684892][E](Custom_C): 01 19 <-targetPosition + 353836 [2685220][E](Custom_C): 01 27 03 <-Power Tab Data + 353837 [2685227][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353838 [2685248][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 353839 [2685286][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | 216 | 217 | | | | | | | | | 218 | 233 | 239 | 240 | | | | | | | | | | + 353840 [2685308][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | | | | | | | 199 | 201 | 202 | | 213 | | 227 | 236 | 238 | | | | | | | | | | + 353841 [2685340][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 156 | 164 | 173 | 179 | 183 | 185 | | | | | 188 | 193 | 197 | 200 | 201 | 217 | | | 222 | 234 | 236 | | | | | | | | | | + 353842 [2685365][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 175 | 177 | | 178 | 179 | 182 | 187 | 192 | 196 | 199 | 200 | 212 | | | 219 | 232 | 234 | | | | | | | | | | + 353843 [2685398][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 175 | | 176 | 181 | 185 | 190 | 194 | 198 | 199 | 208 | 212 | 217 | 218 | 229 | 232 | | | | | | | | | | + 353844 [2685419][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | 189 | 193 | 197 | 198 | 206 | 211 | 216 | 217 | 227 | 230 | | | | | | | | | | + 353845 [2685452][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 187 | 191 | 195 | | 205 | 209 | 213 | 216 | 225 | 228 | | | | | | | | | | + 353846 [2685474][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 186 | 190 | 194 | | 203 | 208 | | | 222 | 226 | | | | | | | | | | + 353847 [2685505][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353848 [2685526][E](PTable): Power Table Reset + 353849 [2685746][E](PTable): Success! + 353850 [2685918][E](Custom_C): 01 2a <-hMin + 353851 [2685950][E](Custom_C): 01 19 <-targetPosition + 353852 [2686040][E](Custom_C): 01 2b <-hMax + 353853 [2686109][E](Custom_C): 01 25 <-Firmware Version + 353854 [2686448][E](PTable): Success! + 353855 [2686917][E](Custom_C): 01 19 <-targetPosition + 353856 [2687150][E](PTable): Success! + 353857 [2687850][E](PTable): Success! + 353858 [2687851][E](PTable): Clean Power Table + 353859 [2687851][E](PTable): Averaged Entry: watts=188.000000, cad=76.800003, targetPosition=1185.99998, (3)(6) + 353860 [2687862][E](PTable): Keep old targetPosition: (118.599998) + 353861 [2687863][E](PTable): Left failed at: (125) Target pos: (118.599998) Avg pos: (121) + 353862 [2687875][E](PTable): All test failed left (3)(5)(125), readings (11) + 353863 [2687875][E](PTable): WEIGHTED DOWNVOTING: Target Value: (118), NeighborValue: (125) + 353864 [2687886][E](PTable): WEIGHTED DOWNVOTING: Delta: (7), Penalty: (1) + 353865 [2687896][E](Custom_C): 01 19 <-targetPosition + 353866 [2687899][E](PTable): PT failed (3)(5)(125), readings (10) + 353867 [2687899][E](PTable): Bottom failed at: (131) Target pos: (118.599998) Avg pos: (124) + 353868 [2687911][E](PTable): All test failed bottom (2)(6)(143), readings (11) + 353869 [2687911][E](PTable): WEIGHTED DOWNVOTING: Target Value: (118), NeighborValue: (131) + 353870 [2687924][E](PTable): WEIGHTED DOWNVOTING: Delta: (13), Penalty: (2) + 353871 [2687935][E](PTable): PT failed (4)(6)(131), readings (5) + 353872 [2687937][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353873 [2687969][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353874 [2687991][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353875 [2688023][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353876 [2688046][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353877 [2688078][E](PTable): 80 rpm | | 58 | | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353878 [2688100][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353879 [2688132][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353880 [2688154][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353881 [2688186][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 353882 [2688207][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353883 [2688239][E](PTable): Power Table Reset + 353884 [2688239][E](ERG_Mode): Proportional: 80.000000, Integral: -4.000000, Derivative: 4.800000 + 353885 [2688552][E](PTable): Success! + 353886 [2688899][E](Custom_C): 01 19 <-targetPosition + 353887 [2689255][E](PTable): Success! + 353888 [2689887][E](Custom_C): 01 19 <-targetPosition + 353889 [2689956][E](PTable): Success! + 353890 [2690658][E](PTable): Success! + 353891 [2690659][E](PTable): Clean Power Table + 353892 [2690659][E](PTable): Averaged Entry: watts=110.000000, cad=80.800003, targetPosition=1164.00002, (4)(4) + 353893 [2690670][E](PTable): cellValue: (106) wattDelta: (2.884615) cadDelta: (0.480769) allNeighborsPassed: (0) + 353894 [2690681][E](PTable): rightValue: (102.533333) leftValue: (109.466667) bottomValue: (107.664009) topValue: (0.000000) New averaged targetPosition: (106.554665) count: (3) + 353895 [2690693][E](PTable): Existing entry averaged (4)(4)(106), readings(11) + 353896 [2690935][E](Custom_C): 01 27 00 <-Power Tab Data + 353897 [2690978][E](Custom_C): 01 2a <-hMin + 353898 [2691035][E](Custom_C): 01 19 <-targetPosition + 353899 [2691092][E](Custom_C): 01 27 01 <-Power Tab Data + 353900 [2691147][E](Custom_C): 01 2b <-hMax + 353901 [2691206][E](Custom_C): 01 27 02 <-Power Tab Data + 353902 [2691250][E](Custom_C): 01 27 03 <-Power Tab Data + 353903 [2691295][E](Custom_C): 01 27 04 <-Power Tab Data + 353904 [2691340][E](Custom_C): 01 27 05 <-Power Tab Data + 353905 [2691385][E](Custom_C): 01 27 06 <-Power Tab Data + 353906 [2691430][E](Custom_C): 01 27 07 <-Power Tab Data + 353907 [2691485][E](Custom_C): 01 27 08 <-Power Tab Data + 353908 [2691527][E](Custom_C): 01 27 04 <-Power Tab Data + 353909 [2691534][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353910 [2691577][E](Custom_C): 01 27 09 <-Power Tab Data + 353911 [2691581][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 353912 [2691603][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | 216 | 217 | | | | | | | | | 218 | 233 | 239 | 240 | | | | | | | | | | + 353913 [2691635][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | | | | | | | 199 | 201 | 202 | | 213 | | 227 | 236 | 238 | | | | | | | | | | + 353914 [2691657][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 156 | 164 | 173 | 179 | 183 | 185 | | | | | 188 | 193 | 197 | 200 | 201 | 217 | | | 222 | 234 | 236 | | | | | | | | | | + 353915 [2691689][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 175 | 177 | | 178 | 179 | 182 | 187 | 192 | 196 | 199 | 200 | 212 | | | 219 | 232 | 234 | | | | | | | | | | + 353916 [2691714][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 175 | | 176 | 181 | 185 | 190 | 194 | 198 | 199 | 208 | 212 | 217 | 218 | 229 | 232 | | | | | | | | | | + 353917 [2691746][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | 189 | 193 | 197 | 198 | 206 | 211 | 216 | 217 | 227 | 230 | | | | | | | | | | + 353918 [2691767][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 187 | 191 | 195 | | 205 | 209 | 213 | 216 | 225 | 228 | | | | | | | | | | + 353919 [2691799][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 186 | 190 | 194 | | 203 | 208 | | | 222 | 226 | | | | | | | | | | + 353920 [2691821][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353921 [2691852][E](PTable): Power Table Reset + 353922 [2691890][E](Custom_C): 01 19 <-targetPosition + 353923 [2692195][E](PTable): Success! + 353924 [2692880][E](Custom_C): 01 19 <-targetPosition + 353925 [2692899][E](PTable): Success! + 353926 [2693600][E](PTable): Success! + 353927 [2693915][E](Custom_C): 01 19 <-targetPosition + 353928 [2694304][E](PTable): Success! + 353929 [2694305][E](PTable): Clean Power Table + 353930 [2694305][E](PTable): Averaged Entry: watts=121.199997, cad=83.199997, targetPosition=1170.00000, (5)(4) + 353931 [2694317][E](PTable): cellValue: (105) wattDelta: (2.500000) cadDelta: (0.416667) allNeighborsPassed: (0) + 353932 [2694319][E](PTable): rightValue: (0.000000) leftValue: (104.520004) bottomValue: (100.679993) topValue: (0.000000) New averaged targetPosition: (102.599998) count: (2) + 353933 [2694340][E](PTable): Bottom failed at: (103) Target pos: (102.599998) Avg pos: (102) + 353934 [2694351][E](PTable): All test failed bottom (4)(4)(106), readings (11) + 353935 [2694351][E](PTable): WEIGHTED DOWNVOTING: Target Value: (102), NeighborValue: (103) + 353936 [2694361][E](PTable): WEIGHTED DOWNVOTING: Delta: (1), Penalty: (0) + 353937 [2694362][E](PTable): PT failed (6)(4)(103), readings (8) + 353938 [2694376][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353939 [2694398][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353940 [2694431][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353941 [2694452][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353942 [2694485][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353943 [2694507][E](PTable): 80 rpm | | 58 | | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353944 [2694539][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353945 [2694561][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353946 [2694593][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353947 [2694614][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 353948 [2694646][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353949 [2694667][E](PTable): Power Table Reset + 353950 [2694667][E](ERG_Mode): Proportional: 112.000000, Integral: 3.400000, Derivative: 2.000000 + 353951 [2694905][E](Custom_C): 01 19 <-targetPosition + 353952 [2695005][E](PTable): Success! + 353953 [2695706][E](PTable): Success! + 353954 [2695895][E](Custom_C): 01 2a <-hMin + 353955 [2695962][E](Custom_C): 01 19 <-targetPosition + 353956 [2696008][E](Custom_C): 01 2b <-hMax + 353957 [2696410][E](PTable): Success! + 353958 [2696885][E](Custom_C): 01 19 <-targetPosition + 353959 [2697114][E](PTable): Success! + 353960 [2697115][E](PTable): Clean Power Table + 353961 [2697115][E](PTable): Averaged Entry: watts=108.000000, cad=80.400002, targetPosition=1188.00003, (4)(4) + 353962 [2697126][E](PTable): cellValue: (106) wattDelta: (2.343750) cadDelta: (0.390625) allNeighborsPassed: (0) + 353963 [2697139][E](PTable): rightValue: (0.000000) leftValue: (111.120003) bottomValue: (107.024002) topValue: (0.000000) New averaged targetPosition: (109.072006) count: (2) + 353964 [2697150][E](PTable): Existing entry averaged (4)(4)(106), readings(11) + 353965 [2697897][E](Custom_C): 01 19 <-targetPosition + 353966 [2697904][E](Custom_C): 01 27 04 <-Power Tab Data + 353967 [2697908][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353968 [2697941][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 353969 [2697963][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | 216 | 217 | | | | | | | | | 218 | 233 | 239 | 240 | | | | | | | | | | + 353970 [2697995][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | | | | | | | 199 | 201 | 202 | | 213 | | 227 | 236 | 238 | | | | | | | | | | + 353971 [2698017][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 156 | 164 | 173 | 179 | 183 | 185 | | | | | 188 | 193 | 197 | 200 | 201 | 217 | | | 222 | 234 | 236 | | | | | | | | | | + 353972 [2698049][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 175 | 177 | | 178 | 179 | 182 | 187 | 192 | 196 | 199 | 200 | 212 | | | 219 | 232 | 234 | | | | | | | | | | + 353973 [2698071][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 175 | | 176 | 181 | 185 | 190 | 194 | 198 | 199 | 208 | 212 | 217 | 218 | 229 | 232 | | | | | | | | | | + 353974 [2698094][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | 189 | 193 | 197 | 198 | 206 | 211 | 216 | 217 | 227 | 230 | | | | | | | | | | + 353975 [2698125][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 187 | 191 | 195 | | 205 | 209 | 213 | 216 | 225 | 228 | | | | | | | | | | + 353976 [2698148][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 186 | 190 | 194 | | 203 | 208 | | | 222 | 226 | | | | | | | | | | + 353977 [2698180][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 353978 [2698201][E](PTable): Power Table Reset + 353979 [2698435][E](PTable): Success! + 353980 [2698910][E](Custom_C): 01 19 <-targetPosition + 353981 [2699137][E](PTable): Success! + 353982 [2699842][E](PTable): Success! + 353983 [2699922][E](Custom_C): 01 19 <-targetPosition + 353984 [2700546][E](PTable): Success! + 353985 [2700547][E](PTable): Clean Power Table + 353986 [2700548][E](PTable): Averaged Entry: watts=117.599998, cad=78.000000, targetPosition=1210.00000, (4)(4) + 353987 [2700559][E](PTable): cellValue: (106) wattDelta: (2.000000) cadDelta: (0.333333) allNeighborsPassed: (0) + 353988 [2700570][E](PTable): rightValue: (0.000000) leftValue: (107.199997) bottomValue: (100.000000) topValue: (0.000000) New averaged targetPosition: (103.599998) count: (2) + 353989 [2700581][E](PTable): Bottom failed at: (105) Target pos: (103.599998) Avg pos: (104) + 353990 [2700592][E](PTable): All test failed bottom (3)(4)(113), readings (11) + 353991 [2700592][E](PTable): WEIGHTED DOWNVOTING: Target Value: (103), NeighborValue: (105) + 353992 [2700603][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 353993 [2700603][E](PTable): PT failed (5)(4)(105), readings (11) + 353994 [2700616][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 353995 [2700639][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 353996 [2700672][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353997 [2700694][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353998 [2700729][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 353999 [2700750][E](PTable): 80 rpm | | 58 | | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354000 [2700782][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354001 [2700804][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354002 [2700837][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354003 [2700858][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 354004 [2700890][E](Custom_C): 01 2a <-hMin + 354005 [2700894][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354006 [2700915][E](PTable): Power Table Reset + 354007 [2700915][E](ERG_Mode): Proportional: 24.000000, Integral: 6.600000, Derivative: -0.600000 + 354008 [2700958][E](Custom_C): 01 19 <-targetPosition + 354009 [2701002][E](Custom_C): 01 2b <-hMax + 354010 [2701247][E](PTable): Success! + 354011 [2701880][E](Custom_C): 01 19 <-targetPosition + 354012 [2701952][E](PTable): Success! + 354013 [2702263][E](Custom_C): 01 25 <-Firmware Version + 354014 [2702655][E](PTable): Success! + 354015 [2702656][E](PTable): Using detected travel limits during homing + 354016 [2702893][E](Custom_C): 01 19 <-targetPosition + 354017 [2703358][E](PTable): Success! + 354018 [2703359][E](PTable): Clean Power Table + 354019 [2703359][E](PTable): Averaged Entry: watts=120.400002, cad=78.000000, targetPosition=1230.00000, (4)(4) + 354020 [2703370][E](PTable): cellValue: (106) wattDelta: (1.764706) cadDelta: (0.294118) allNeighborsPassed: (0) + 354021 [2703381][E](PTable): rightValue: (0.000000) leftValue: (105.773331) bottomValue: (99.199997) topValue: (0.000000) New averaged targetPosition: (102.486664) count: (2) + 354022 [2703393][E](PTable): Bottom failed at: (105) Target pos: (102.486664) Avg pos: (103) + 354023 [2703404][E](PTable): All test failed bottom (3)(4)(113), readings (11) + 354024 [2703405][E](PTable): WEIGHTED DOWNVOTING: Target Value: (102), NeighborValue: (105) + 354025 [2703415][E](PTable): WEIGHTED DOWNVOTING: Delta: (3), Penalty: (0) + 354026 [2703415][E](PTable): PT failed (5)(4)(105), readings (11) + 354027 [2703428][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354028 [2703449][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354029 [2703481][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354030 [2703503][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354031 [2703535][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354032 [2703557][E](PTable): 80 rpm | | 58 | | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354033 [2703592][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354034 [2703614][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354035 [2703646][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354036 [2703668][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 354037 [2703700][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354038 [2703721][E](PTable): Power Table Reset + 354039 [2703883][E](Custom_C): 01 19 <-targetPosition + 354040 [2704086][E](PTable): Success! + 354041 [2704789][E](PTable): Success! + 354042 [2704883][E](Custom_C): 01 19 <-targetPosition + 354043 [2705490][E](PTable): Success! + 354044 [2705899][E](Custom_C): 01 27 00 <-Power Tab Data + 354045 [2705930][E](Custom_C): 01 2a <-hMin + 354046 [2705975][E](Custom_C): 01 19 <-targetPosition + 354047 [2706032][E](Custom_C): 01 27 01 <-Power Tab Data + 354048 [2706087][E](Custom_C): 01 2b <-hMax + 354049 [2706147][E](Custom_C): 01 27 02 <-Power Tab Data + 354050 [2706192][E](PTable): Success! + 354051 [2706193][E](PTable): Clean Power Table + 354052 [2706194][E](PTable): Averaged Entry: watts=159.600006, cad=82.599998, targetPosition=1214.00002, (5)(5) + 354053 [2706206][E](PTable): cellValue: (108) wattDelta: (2.238806) cadDelta: (0.373134) allNeighborsPassed: (0) + 354054 [2706250][E](PTable): rightValue: (112.288002) leftValue: (103.711998) bottomValue: (101.567993) topValue: (0.000000) New averaged targetPosition: (105.855995) count: (3) + 354055 [2706264][E](PTable): Left failed at: (105) Target pos: (105.855995) Avg pos: (105) + 354056 [2706265][E](PTable): Was not in range failed left (5)(4)(105), readings (11) + 354057 [2706276][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (105) + 354058 [2706286][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 354059 [2706287][E](PTable): PT failed (5)(4)(105), readings (11) + 354060 [2706297][E](PTable): Bottom failed at: (106) Target pos: (105.855995) Avg pos: (105) + 354061 [2706299][E](PTable): All test failed bottom (4)(5)(118), readings (11) + 354062 [2706310][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (106) + 354063 [2706357][E](PTable): WEIGHTED DOWNVOTING: Delta: (1), Penalty: (0) + 354064 [2706357][E](PTable): PT failed (6)(5)(106), readings (11) + 354065 [2706360][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354066 [2706392][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354067 [2706448][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354068 [2706473][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354069 [2706536][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354070 [2706561][E](PTable): 80 rpm | | 58 | | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354071 [2706585][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354072 [2706649][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354073 [2706673][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354074 [2706697][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 354075 [2706754][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354076 [2706775][E](PTable): Power Table Reset + 354077 [2706786][E](ERG_Mode): Proportional: 104.000000, Integral: 2.800000, Derivative: -1.600000 + 354078 [2706820][E](Custom_C): 01 27 09 <-Power Tab Data + 354079 [2706894][E](PTable): Success! + 354080 [2706897][E](Custom_C): 01 25 <-Firmware Version + 354081 [2706942][E](Custom_C): 01 19 <-targetPosition + 354082 [2707599][E](PTable): Success! + 354083 [2707911][E](Custom_C): 01 19 <-targetPosition + 354084 [2708018][E](BLE_Client): HRM battery updated 100 + 354085 [2708303][E](PTable): Success! + 354086 [2708877][E](Custom_C): 01 19 <-targetPosition + 354087 [2709007][E](PTable): Success! + 354088 [2709008][E](PTable): Clean Power Table + 354089 [2709008][E](PTable): Averaged Entry: watts=114.400002, cad=78.599998, targetPosition=1221.99997, (4)(4) + 354090 [2709022][E](PTable): cellValue: (106) wattDelta: (1.851852) cadDelta: (0.308642) allNeighborsPassed: (0) + 354091 [2709023][E](PTable): rightValue: (0.000000) leftValue: (109.024002) bottomValue: (101.463997) topValue: (0.000000) New averaged targetPosition: (105.244003) count: (2) + 354092 [2709044][E](PTable): Bottom failed at: (105) Target pos: (105.244003) Avg pos: (105) + 354093 [2709044][E](PTable): Was not in range failed bottom (5)(4)(105), readings (11) + 354094 [2709055][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (105) + 354095 [2709066][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 354096 [2709066][E](PTable): PT failed (5)(4)(105), readings (11) + 354097 [2709079][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354098 [2709101][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354099 [2709133][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354100 [2709155][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354101 [2709186][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354102 [2709209][E](PTable): 80 rpm | | 58 | | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354103 [2709241][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354104 [2709264][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354105 [2709286][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354106 [2709318][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 354107 [2709350][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354108 [2709371][E](PTable): Power Table Reset + 354109 [2709724][E](PTable): Success! + 354110 [2709890][E](Custom_C): 01 19 <-targetPosition + 354111 [2710426][E](PTable): Success! + 354112 [2710880][E](Custom_C): 01 2a <-hMin + 354113 [2710947][E](Custom_C): 01 19 <-targetPosition + 354114 [2711015][E](Custom_C): 01 2b <-hMax + 354115 [2711131][E](PTable): Success! + 354116 [2711836][E](PTable): Success! + 354117 [2711837][E](PTable): Clean Power Table + 354118 [2711837][E](PTable): Averaged Entry: watts=135.199997, cad=77.599998, targetPosition=1234.00002, (4)(5) + 354119 [2711848][E](PTable): cellValue: (118) wattDelta: (5.555554) cadDelta: (0.925926) allNeighborsPassed: (1) + 354120 [2711859][E](PTable): rightValue: (115.335999) leftValue: (120.664001) bottomValue: (115.407997) topValue: (120.592003) New averaged targetPosition: (118.000000) count: (4) + 354121 [2711870][E](PTable): Existing entry averaged (4)(5)(118), readings(11) + 354122 [2711915][E](Custom_C): 01 19 <-targetPosition + 354123 [2712625][E](Custom_C): 01 27 04 <-Power Tab Data + 354124 [2712630][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354125 [2712653][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354126 [2712686][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | 216 | 217 | | | | | | | | | 218 | 233 | 239 | 240 | | | | | | | | | | + 354127 [2712709][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | | | | | | | 199 | 201 | 202 | | 213 | | 227 | 236 | 238 | | | | | | | | | | + 354128 [2712741][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 156 | 164 | 173 | 179 | 183 | 185 | | | | | 188 | 193 | 197 | 200 | 201 | 217 | | | 222 | 234 | 236 | | | | | | | | | | + 354129 [2712763][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 175 | 177 | | 178 | 179 | 182 | 187 | 192 | 196 | 199 | 200 | 212 | | | 219 | 232 | 234 | | | | | | | | | | + 354130 [2712785][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 175 | | 176 | 181 | 185 | 190 | 194 | 198 | 199 | 208 | 212 | 217 | 218 | 229 | 232 | | | | | | | | | | + 354131 [2712818][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | 189 | 193 | 197 | 198 | 206 | 211 | 216 | 217 | 227 | 230 | | | | | | | | | | + 354132 [2712839][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 187 | 191 | 195 | | 205 | 209 | 213 | 216 | 225 | 228 | | | | | | | | | | + 354133 [2712872][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 186 | 190 | 194 | | 203 | 208 | | | 222 | 226 | | | | | | | | | | + 354134 [2712917][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354135 [2712938][E](PTable): Power Table Reset + 354136 [2712938][E](ERG_Mode): Proportional: 24.000000, Integral: 5.400000, Derivative: 0.800000 + 354137 [2713178][E](PTable): Success! + 354138 [2713680][E](FTMS_SERVER): 05 77 01 -> ERG Mode Target: 375 Current: 130 Incline: 123.787994 + 354139 [2713692][E](Custom_C): 01 28 <-targetWatts + 354140 [2713882][E](PTable): Success! + 354141 [2713883][E](PTable): Lookup debug 360 X1 420 X2 70 Y1 80 Y2 -0 + 354142 [2713884][E](PTable): Lookup used neighbors L 179 R 185 R1 180 + 354143 [2713895][E](Custom_C): 01 19 <-targetPosition + 354144 [2713898][E](PTable): Lookup used neighbors U 194 D 175 R2 181 + 354145 [2713899][E](PTable): Lookup used actual 183 R3 183 + 354146 [2713909][E](PTable): Lookup result: 375w 77cad 18100 + 354147 [2713910][E](ERG_Mode): SetPoint changed:375w PowerTable Result: 18100 + 354148 [2713920][E](ERG_Mode): Capping ERG seek time to 5 seconds + 354149 [2713928][E](PTable): Success! + 354150 [2714628][E](PTable): Success! + 354151 [2714629][E](PTable): Clean Power Table + 354152 [2714629][E](PTable): Averaged Entry: watts=131.600006, cad=77.400002, targetPosition=1245.99998, (3)(4) + 354153 [2714642][E](PTable): cellValue: (113) wattDelta: (2.586207) cadDelta: (0.431035) allNeighborsPassed: (1) + 354154 [2714653][E](PTable): rightValue: (117.485336) leftValue: (108.514664) bottomValue: (118.568001) topValue: (107.431999) New averaged targetPosition: (113.000000) count: (4) + 354155 [2714665][E](PTable): Existing entry averaged (3)(4)(113), readings(11) + 354156 [2714907][E](Custom_C): 01 19 <-targetPosition + 354157 [2715417][E](Custom_C): 01 27 03 <-Power Tab Data + 354158 [2715424][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354159 [2715447][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354160 [2715481][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | 216 | 217 | | | | | | | | | 218 | 233 | 239 | 240 | | | | | | | | | | + 354161 [2715503][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | | | | | | | 199 | 201 | 202 | | 213 | | 227 | 236 | 238 | | | | | | | | | | + 354162 [2715535][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 156 | 164 | 173 | 179 | 183 | 185 | | | | | 188 | 193 | 197 | 200 | 201 | 217 | | | 222 | 234 | 236 | | | | | | | | | | + 354163 [2715557][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 175 | 177 | | 178 | 179 | 182 | 187 | 192 | 196 | 199 | 200 | 212 | | | 219 | 232 | 234 | | | | | | | | | | + 354164 [2715589][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 175 | | 176 | 181 | 185 | 190 | 194 | 198 | 199 | 208 | 212 | 217 | 218 | 229 | 232 | | | | | | | | | | + 354165 [2715611][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | 189 | 193 | 197 | 198 | 206 | 211 | 216 | 217 | 227 | 230 | | | | | | | | | | + 354166 [2715643][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 187 | 191 | 195 | | 205 | 209 | 213 | 216 | 225 | 228 | | | | | | | | | | + 354167 [2715666][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 186 | 190 | 194 | | 203 | 208 | | | 222 | 226 | | | | | | | | | | + 354168 [2715688][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354169 [2715721][E](PTable): Power Table Reset + 354170 [2715921][E](Custom_C): 01 2a <-hMin + 354171 [2715957][E](PTable): Success! + 354172 [2715965][E](Custom_C): 01 19 <-targetPosition + 354173 [2716055][E](Custom_C): 01 2b <-hMax + 354174 [2716659][E](PTable): Success! + 354175 [2716887][E](Custom_C): 01 19 <-targetPosition + 354176 [2717364][E](PTable): Success! + 354177 [2717900][E](Custom_C): 01 19 <-targetPosition + 354178 [2718069][E](PTable): Success! + 354179 [2718070][E](PTable): Clean Power Table + 354180 [2718070][E](PTable): Averaged Entry: watts=300.399994, cad=81.199997, targetPosition=1770.00000, (4)(10) + 354181 [2718081][E](PTable): cellValue: (153) wattDelta: (1.250000) cadDelta: (0.208333) allNeighborsPassed: (0) + 354182 [2718093][E](PTable): rightValue: (0.000000) leftValue: (152.680008) bottomValue: (158.759979) topValue: (0.000000) New averaged targetPosition: (155.720001) count: (2) + 354183 [2718104][E](PTable): Existing entry averaged (4)(10)(153), readings(11) + 354184 [2718855][E](Custom_C): 01 27 04 <-Power Tab Data + 354185 [2718860][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354186 [2718882][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354187 [2718928][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | 216 | 217 | | | | | | | | | 218 | 233 | 239 | 240 | | | | | | | | | | + 354188 [2718952][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | | | | | | | 199 | 201 | 202 | | 213 | | 227 | 236 | 238 | | | | | | | | | | + 354189 [2718974][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 156 | 164 | 173 | 179 | 183 | 185 | | | | | 188 | 193 | 197 | 200 | 201 | 217 | | | 222 | 234 | 236 | | | | | | | | | | + 354190 [2719006][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 175 | 177 | | 178 | 179 | 182 | 187 | 192 | 196 | 199 | 200 | 212 | | | 219 | 232 | 234 | | | | | | | | | | + 354191 [2719028][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 175 | | 176 | 181 | 185 | 190 | 194 | 198 | 199 | 208 | 212 | 217 | 218 | 229 | 232 | | | | | | | | | | + 354192 [2719060][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 169 | 171 | 175 | 180 | 184 | 189 | 193 | 197 | 198 | 206 | 211 | 216 | 217 | 227 | 230 | | | | | | | | | | + 354193 [2719081][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 165 | 169 | 173 | 178 | 182 | 187 | 191 | 195 | | 205 | 209 | 213 | 216 | 225 | 228 | | | | | | | | | | + 354194 [2719113][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 172 | 177 | 181 | 186 | 190 | 194 | | 203 | 208 | | | 222 | 226 | | | | | | | | | | + 354195 [2719135][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354196 [2719166][E](PTable): Power Table Reset + 354197 [2719167][E](ERG_Mode): Proportional: -988.000000, Integral: -18.800001, Derivative: -24.600000 + 354198 [2719426][E](PTable): Success! + 354199 [2719880][E](Custom_C): 01 19 <-targetPosition + 354200 [2720126][E](PTable): Success! + 354201 [2720828][E](PTable): Success! + 354202 [2720927][E](Custom_C): 01 27 00 <-Power Tab Data + 354203 [2720960][E](Custom_C): 01 2a <-hMin + 354204 [2721005][E](Custom_C): 01 19 <-targetPosition + 354205 [2721062][E](Custom_C): 01 27 01 <-Power Tab Data + 354206 [2721095][E](Custom_C): 01 2b <-hMax + 354207 [2721152][E](Custom_C): 01 27 02 <-Power Tab Data + 354208 [2721197][E](Custom_C): 01 27 03 <-Power Tab Data + 354209 [2721265][E](Custom_C): 01 27 04 <-Power Tab Data + 354210 [2721310][E](Custom_C): 01 27 05 <-Power Tab Data + 354211 [2721365][E](Custom_C): 01 27 06 <-Power Tab Data + 354212 [2721423][E](Custom_C): 01 27 07 <-Power Tab Data + 354213 [2721469][E](Custom_C): 01 27 08 <-Power Tab Data + 354214 [2721507][E](Custom_C): 01 27 09 <-Power Tab Data + 354215 [2721593][E](PTable): Success! + 354216 [2721594][E](PTable): Clean Power Table + 354217 [2721594][E](PTable): Averaged Entry: watts=452.799988, cad=87.800003, targetPosition=1763.99994, (6)(15) + 354218 [2721608][E](PTable): Keep old targetPosition: (176.399994) + 354219 [2721609][E](PTable): New entry recorded (6)(15)(176) + 354220 [2721882][E](Custom_C): 01 19 <-targetPosition + 354221 [2722030][E](Custom_C): 01 27 06 <-Power Tab Data + 354222 [2722036][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354223 [2722058][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | | | | | | 225 | 227 | 230 | 233 | 236 | 238 | 240 | 241 | 244 | | | | | | | | | | + 354224 [2722090][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | 214 | 218 | 226 | 229 | 232 | 235 | 237 | 239 | | 243 | | | | | | | | | | + 354225 [2722111][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | | | | 198 | 203 | 210 | 216 | 224 | 227 | 230 | 233 | 236 | | 240 | 242 | | | | | | | | | | + 354226 [2722143][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 156 | 164 | 173 | 179 | 183 | 185 | 186 | 192 | 193 | 196 | 201 | 208 | 215 | 220 | 225 | 226 | 227 | 228 | 232 | 236 | 239 | | | | | | | | | | + 354227 [2722165][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 175 | 177 | 178 | 188 | 191 | 195 | 199 | 206 | 211 | 215 | 219 | 221 | 223 | 225 | 228 | 231 | 234 | | | | | | | | | | + 354228 [2722197][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 177 | 183 | 188 | 192 | 197 | 203 | 206 | 211 | 216 | 217 | 218 | 219 | 224 | 229 | 232 | | | | | | | | | | + 354229 [2722219][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | 179 | 183 | 188 | 194 | 199 | 202 | 206 | 210 | 212 | 213 | 215 | 216 | 222 | 228 | | | | | | | | | | + 354230 [2722253][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 162 | 169 | 175 | 179 | 184 | 189 | 194 | 197 | 202 | 207 | 208 | 209 | 214 | | 221 | 225 | | | | | | | | | | + 354231 [2722276][E](Custom_C): 01 25 <-Firmware Version + 354232 [2722280][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 170 | 175 | 179 | 184 | 189 | 193 | 197 | 201 | 203 | 208 | 212 | | | | | | | | | | | | | + 354233 [2722313][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354234 [2722333][E](PTable): Power Table Reset + 354235 [2722351][E](PTable): Success! + 354236 [2722896][E](Custom_C): 01 19 <-targetPosition + 354237 [2723056][E](PTable): Success! + 354238 [2723757][E](PTable): Success! + 354239 [2723897][E](Custom_C): 01 19 <-targetPosition + 354240 [2724459][E](PTable): Success! + 354241 [2724460][E](PTable): Clean Power Table + 354242 [2724460][E](PTable): Averaged Entry: watts=405.600006, cad=84.199997, targetPosition=1716.00006, (5)(14) + 354243 [2724473][E](PTable): Keep old targetPosition: (171.600006) + 354244 [2724473][E](PTable): New entry recorded (5)(14)(171) + 354245 [2724942][E](Custom_C): 01 19 <-targetPosition + 354246 [2725155][E](Custom_C): 01 27 05 <-Power Tab Data + 354247 [2725161][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354248 [2725182][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354249 [2725215][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354250 [2725238][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354251 [2725271][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 156 | 164 | 173 | 179 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354252 [2725294][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354253 [2725326][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354254 [2725348][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354255 [2725381][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354256 [2725404][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354257 [2725427][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354258 [2725458][E](PTable): Power Table Reset + 354259 [2725458][E](ERG_Mode): Proportional: -36.000000, Integral: -6.900000, Derivative: 2.400000 + 354260 [2725683][E](PTable): Success! + 354261 [2725888][E](Custom_C): 01 2a <-hMin + 354262 [2725955][E](Custom_C): 01 19 <-targetPosition + 354263 [2726000][E](Custom_C): 01 2b <-hMax + 354264 [2726089][E](Custom_C): 01 25 <-Firmware Version + 354265 [2726388][E](PTable): Success! + 354266 [2726900][E](Custom_C): 01 19 <-targetPosition + 354267 [2727090][E](PTable): Success! + 354268 [2727798][E](PTable): Success! + 354269 [2727798][E](PTable): Clean Power Table + 354270 [2727799][E](PTable): Averaged Entry: watts=363.200012, cad=81.000000, targetPosition=1710.00000, (4)(12) + 354271 [2727810][E](PTable): cellValue: (169) wattDelta: (15.000000) cadDelta: (2.500000) allNeighborsPassed: (1) + 354272 [2727821][E](PTable): rightValue: (169.213333) leftValue: (168.786667) bottomValue: (169.399994) topValue: (168.600006) New averaged targetPosition: (169.000000) count: (4) + 354273 [2727832][E](PTable): Existing entry averaged (4)(12)(169), readings(4) + 354274 [2727913][E](Custom_C): 01 19 <-targetPosition + 354275 [2728538][E](Custom_C): 01 27 04 <-Power Tab Data + 354276 [2728543][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354277 [2728565][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354278 [2728598][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354279 [2728621][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354280 [2728653][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 156 | 164 | 173 | 179 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354281 [2728675][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 158 | 169 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354282 [2728708][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354283 [2728730][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354284 [2728762][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354285 [2728784][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354286 [2728806][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354287 [2728837][E](PTable): Power Table Reset + 354288 [2728903][E](Custom_C): 01 19 <-targetPosition + 354289 [2729060][E](PTable): Success! + 354290 [2729762][E](PTable): Success! + 354291 [2729892][E](Custom_C): 01 19 <-targetPosition + 354292 [2730463][E](PTable): Success! + 354293 [2730465][E](ERG_Mode): Proportional: 92.000000, Integral: 6.400000, Derivative: -3.800000 + 354294 [2730882][E](Custom_C): 01 2a <-hMin + 354295 [2730950][E](Custom_C): 01 19 <-targetPosition + 354296 [2730994][E](Custom_C): 01 2b <-hMax + 354297 [2731168][E](PTable): Success! + 354298 [2731169][E](PTable): Clean Power Table + 354299 [2731169][E](PTable): Averaged Entry: watts=333.600006, cad=78.800003, targetPosition=1733.99994, (4)(11) + 354300 [2731181][E](PTable): cellValue: (158) wattDelta: (1.948053) cadDelta: (0.324675) allNeighborsPassed: (0) + 354301 [2731193][E](PTable): rightValue: (0.000000) leftValue: (156.151993) bottomValue: (154.304016) topValue: (0.000000) New averaged targetPosition: (155.227997) count: (2) + 354302 [2731204][E](PTable): Existing entry averaged (4)(11)(157), readings(10) + 354303 [2731885][E](Custom_C): 01 27 04 <-Power Tab Data + 354304 [2731891][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354305 [2731935][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354306 [2731958][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354307 [2731981][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354308 [2732013][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 156 | 164 | 173 | 179 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354309 [2732034][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 157 | 169 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354310 [2732067][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354311 [2732088][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354312 [2732120][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354313 [2732142][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354314 [2732175][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354315 [2732195][E](PTable): Power Table Reset + 354316 [2732433][E](PTable): Success! + 354317 [2732896][E](Custom_C): 01 19 <-targetPosition + 354318 [2733136][E](PTable): Success! + 354319 [2733838][E](PTable): Success! + 354320 [2733920][E](Custom_C): 01 19 <-targetPosition + 354321 [2734543][E](PTable): Success! + 354322 [2734544][E](PTable): Clean Power Table + 354323 [2734544][E](PTable): Averaged Entry: watts=370.399994, cad=79.400002, targetPosition=1750.00000, (4)(12) + 354324 [2734556][E](PTable): cellValue: (169) wattDelta: (5.000000) cadDelta: (0.833333) allNeighborsPassed: (0) + 354325 [2734568][E](PTable): rightValue: (0.000000) leftValue: (166.919998) bottomValue: (168.279999) topValue: (169.720001) New averaged targetPosition: (168.306671) count: (3) + 354326 [2734579][E](PTable): Existing entry averaged (4)(12)(168), readings(5) + 354327 [2734887][E](Custom_C): 01 19 <-targetPosition + 354328 [2735252][E](Custom_C): 01 27 04 <-Power Tab Data + 354329 [2735258][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354330 [2735281][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354331 [2735313][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354332 [2735336][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354333 [2735368][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354334 [2735390][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354335 [2735422][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354336 [2735444][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354337 [2735476][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354338 [2735498][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354339 [2735529][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354340 [2735551][E](PTable): Power Table Reset + 354341 [2735551][E](ERG_Mode): Proportional: 124.000000, Integral: 8.700000, Derivative: 1.800000 + 354342 [2735808][E](PTable): Success! + 354343 [2735913][E](Custom_C): 01 27 00 <-Power Tab Data + 354344 [2735969][E](Custom_C): 01 2a <-hMin + 354345 [2736035][E](Custom_C): 01 19 <-targetPosition + 354346 [2736116][E](Custom_C): 01 27 01 <-Power Tab Data + 354347 [2736149][E](Custom_C): 01 2b <-hMax + 354348 [2736227][E](Custom_C): 01 27 02 <-Power Tab Data + 354349 [2736294][E](Custom_C): 01 27 03 <-Power Tab Data + 354350 [2736339][E](Custom_C): 01 27 04 <-Power Tab Data + 354351 [2736385][E](Custom_C): 01 27 05 <-Power Tab Data + 354352 [2736429][E](Custom_C): 01 27 06 <-Power Tab Data + 354353 [2736509][E](Custom_C): 01 27 07 <-Power Tab Data + 354354 [2736513][E](PTable): Success! + 354355 [2736564][E](Custom_C): 01 27 08 <-Power Tab Data + 354356 [2736609][E](Custom_C): 01 27 09 <-Power Tab Data + 354357 [2736914][E](Custom_C): 01 19 <-targetPosition + 354358 [2737216][E](PTable): Success! + 354359 [2737880][E](Custom_C): 01 19 <-targetPosition + 354360 [2737919][E](PTable): Success! + 354361 [2737920][E](PTable): Clean Power Table + 354362 [2737920][E](PTable): Averaged Entry: watts=342.799988, cad=77.000000, targetPosition=1763.99994, (3)(11) + 354363 [2737932][E](PTable): cellValue: (173) wattDelta: (8.823545) cadDelta: (1.470591) allNeighborsPassed: (0) + 354364 [2737943][E](PTable): rightValue: (174.450668) leftValue: (171.549332) bottomValue: (174.360001) topValue: (0.000000) New averaged targetPosition: (173.453323) count: (3) + 354365 [2737954][E](PTable): Existing entry averaged (3)(11)(173), readings(1) + 354366 [2738628][E](Custom_C): 01 27 03 <-Power Tab Data + 354367 [2738633][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354368 [2738656][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354369 [2738688][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354370 [2738711][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354371 [2738743][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354372 [2738765][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354373 [2738797][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354374 [2738819][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354375 [2738851][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354376 [2738873][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354377 [2738923][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354378 [2738944][E](PTable): Power Table Reset + 354379 [2739186][E](PTable): Success! + 354380 [2739882][E](Custom_C): 01 19 <-targetPosition + 354381 [2739887][E](PTable): Success! + 354382 [2740592][E](PTable): Success! + 354383 [2740593][E](ERG_Mode): Proportional: -492.000000, Integral: -6.300000, Derivative: -15.000000 + 354384 [2740895][E](Custom_C): 01 2a <-hMin + 354385 [2740940][E](Custom_C): 01 19 <-targetPosition + 354386 [2741030][E](Custom_C): 01 2b <-hMax + 354387 [2741296][E](PTable): Success! + 354388 [2741297][E](PTable): Clean Power Table + 354389 [2741298][E](PTable): Averaged Entry: watts=393.600006, cad=80.000000, targetPosition=1776.00006, (4)(13) + 354390 [2741309][E](PTable): cellValue: (175) wattDelta: (11.538434) cadDelta: (1.923072) allNeighborsPassed: (1) + 354391 [2741321][E](PTable): rightValue: (175.311996) leftValue: (174.688004) bottomValue: (175.000000) topValue: (175.000000) New averaged targetPosition: (175.000000) count: (4) + 354392 [2741333][E](PTable): Existing entry averaged (4)(13)(175), readings(2) + 354393 [2741896][E](Custom_C): 01 19 <-targetPosition + 354394 [2742015][E](Custom_C): 01 27 04 <-Power Tab Data + 354395 [2742021][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354396 [2742043][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354397 [2742075][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354398 [2742098][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354399 [2742132][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354400 [2742154][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354401 [2742189][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354402 [2742211][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354403 [2742243][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354404 [2742265][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354405 [2742311][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354406 [2742332][E](PTable): Power Table Reset + 354407 [2742563][E](PTable): Success! + 354408 [2742897][E](Custom_C): 01 19 <-targetPosition + 354409 [2743264][E](PTable): Success! + 354410 [2743265][E](PTable): Using detected travel limits during homing + 354411 [2743600][E](FTMS_SERVER): 05 82 00 -> ERG Mode Target: 130 Current: 342 Incline: 174.854996 + 354412 [2743610][E](Custom_C): 01 28 <-targetWatts + 354413 [2743887][E](Custom_C): 01 19 <-targetPosition + 354414 [2743966][E](PTable): Success! + 354415 [2743967][E](PTable): Lookup debug 90 X1 150 X2 70 Y1 80 Y2 -0 + 354416 [2743968][E](PTable): Lookup used neighbors L 109 R 125 R1 120 + 354417 [2743979][E](PTable): Lookup used neighbors U 126 D 106 R2 112 + 354418 [2743980][E](PTable): Lookup used actual 113 R3 113 + 354419 [2743980][E](PTable): Lookup result: 130w 77cad 11400 + 354420 [2743991][E](ERG_Mode): SetPoint changed:130w PowerTable Result: 11400 + 354421 [2743991][E](ERG_Mode): Capping ERG seek time to 5 seconds + 354422 [2744007][E](PTable): Success! + 354423 [2744008][E](PTable): Clean Power Table + 354424 [2744008][E](PTable): Averaged Entry: watts=362.799988, cad=78.599998, targetPosition=1738.00003, (4)(12) + 354425 [2744019][E](PTable): cellValue: (168) wattDelta: (5.172411) cadDelta: (0.862069) allNeighborsPassed: (1) + 354426 [2744031][E](PTable): rightValue: (168.541336) leftValue: (167.458664) bottomValue: (166.375992) topValue: (169.624008) New averaged targetPosition: (168.000000) count: (4) + 354427 [2744043][E](PTable): Existing entry averaged (4)(12)(168), readings(6) + 354428 [2744736][E](Custom_C): 01 27 04 <-Power Tab Data + 354429 [2744742][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354430 [2744766][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354431 [2744799][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354432 [2744821][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354433 [2744853][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 137 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354434 [2744877][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354435 [2744901][E](Custom_C): 01 19 <-targetPosition + 354436 [2744914][E](PTable): 85 rpm | | 24 | 84 | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354437 [2744936][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354438 [2744969][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354439 [2744991][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354440 [2745023][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354441 [2745043][E](PTable): Power Table Reset + 354442 [2745381][E](PTable): Success! + 354443 [2745913][E](Custom_C): 01 2a <-hMin + 354444 [2745957][E](Custom_C): 01 19 <-targetPosition + 354445 [2746036][E](Custom_C): 01 2b <-hMax + 354446 [2746069][E](Custom_C): 01 25 <-Firmware Version + 354447 [2746083][E](PTable): Power Table Reset + 354448 [2746084][E](ERG_Mode): Proportional: -464.000000, Integral: -17.600000, Derivative: 3.400000 + 354449 [2746785][E](PTable): Success! + 354450 [2746880][E](Custom_C): 01 19 <-targetPosition + 354451 [2747488][E](PTable): Success! + 354452 [2747892][E](Custom_C): 01 19 <-targetPosition + 354453 [2748189][E](PTable): Success! + 354454 [2748882][E](Custom_C): 01 19 <-targetPosition + 354455 [2748891][E](PTable): Success! + 354456 [2748892][E](PTable): Clean Power Table + 354457 [2748892][E](PTable): Averaged Entry: watts=184.800003, cad=72.000000, targetPosition=1231.99997, (2)(6) + 354458 [2748904][E](PTable): cellValue: (143) wattDelta: (1.515151) cadDelta: (0.252525) allNeighborsPassed: (0) + 354459 [2748915][E](PTable): rightValue: (106.567993) leftValue: (0.000000) bottomValue: (0.000000) topValue: (95.479996) New averaged targetPosition: (101.023994) count: (2) + 354460 [2748926][E](PTable): Left failed at: (133) Target pos: (101.023994) Avg pos: (117) + 354461 [2748937][E](PTable): Was not in range failed left (2)(5)(133), readings (11) + 354462 [2748937][E](PTable): WEIGHTED DOWNVOTING: Target Value: (101), NeighborValue: (133) + 354463 [2748948][E](PTable): WEIGHTED DOWNVOTING: Delta: (32), Penalty: (6) + 354464 [2748958][E](PTable): PT failed (2)(5)(133), readings (5) + 354465 [2748959][E](PTable): Bottom failed at: (131) Target pos: (101.023994) Avg pos: (116) + 354466 [2748971][E](PTable): Was not in range failed bottom (4)(6)(131), readings (5) + 354467 [2748971][E](PTable): WEIGHTED DOWNVOTING: Target Value: (101), NeighborValue: (131) + 354468 [2748982][E](PTable): WEIGHTED DOWNVOTING: Delta: (30), Penalty: (6) + 354469 [2748982][E](PTable): PT failed (4)(6)(131), readings (0) + 354470 [2748994][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354471 [2749016][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354472 [2749049][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354473 [2749071][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354474 [2749103][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354475 [2749124][E](PTable): 80 rpm | | 58 | | | 106 | 118 | 131 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354476 [2749158][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 354477 [2749180][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 354478 [2749212][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354479 [2749233][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 354480 [2749266][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354481 [2749287][E](PTable): Power Table Reset + 354482 [2749765][E](PTable): Success! + 354483 [2749895][E](Custom_C): 01 19 <-targetPosition + 354484 [2750467][E](PTable): Success! + 354485 [2750921][E](Custom_C): 01 27 00 <-Power Tab Data + 354486 [2750975][E](Custom_C): 01 2a <-hMin + 354487 [2751076][E](Custom_C): 01 19 <-targetPosition + 354488 [2751122][E](Custom_C): 01 27 01 <-Power Tab Data + 354489 [2751154][E](Custom_C): 01 2b <-hMax + 354490 [2751172][E](PTable): Success! + 354491 [2751173][E](ERG_Mode): Proportional: -8.000000, Integral: -6.200000, Derivative: 0.800000 + 354492 [2751214][E](Custom_C): 01 27 02 <-Power Tab Data + 354493 [2751280][E](Custom_C): 01 27 03 <-Power Tab Data + 354494 [2751325][E](Custom_C): 01 27 04 <-Power Tab Data + 354495 [2751381][E](Custom_C): 01 27 05 <-Power Tab Data + 354496 [2751448][E](Custom_C): 01 27 06 <-Power Tab Data + 354497 [2751504][E](Custom_C): 01 27 07 <-Power Tab Data + 354498 [2751550][E](Custom_C): 01 27 08 <-Power Tab Data + 354499 [2751594][E](Custom_C): 01 27 09 <-Power Tab Data + 354500 [2751897][E](Custom_C): 01 19 <-targetPosition + 354501 [2751951][E](PTable): Success! + 354502 [2751952][E](PTable): Clean Power Table + 354503 [2751952][E](PTable): Averaged Entry: watts=130.000000, cad=78.000000, targetPosition=1218.00003, (4)(4) + 354504 [2751964][E](PTable): cellValue: (106) wattDelta: (1.898734) cadDelta: (0.316456) allNeighborsPassed: (0) + 354505 [2751966][E](PTable): rightValue: (0.000000) leftValue: (100.733337) bottomValue: (99.680000) topValue: (0.000000) New averaged targetPosition: (100.206665) count: (2) + 354506 [2751988][E](PTable): Bottom failed at: (105) Target pos: (100.206665) Avg pos: (102) + 354507 [2751989][E](PTable): All test failed bottom (3)(4)(113), readings (11) + 354508 [2751999][E](PTable): WEIGHTED DOWNVOTING: Target Value: (100), NeighborValue: (105) + 354509 [2752010][E](PTable): WEIGHTED DOWNVOTING: Delta: (5), Penalty: (1) + 354510 [2752010][E](PTable): PT failed (5)(4)(105), readings (10) + 354511 [2752022][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354512 [2752044][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354513 [2752077][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354514 [2752098][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354515 [2752121][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354516 [2752154][E](PTable): 80 rpm | | 58 | | | 106 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354517 [2752176][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 354518 [2752208][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 354519 [2752231][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354520 [2752263][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 354521 [2752285][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354522 [2752316][E](PTable): Power Table Reset + 354523 [2752654][E](PTable): Success! + 354524 [2752887][E](Custom_C): 01 19 <-targetPosition + 354525 [2753358][E](PTable): Success! + 354526 [2753899][E](Custom_C): 01 19 <-targetPosition + 354527 [2754063][E](PTable): Success! + 354528 [2754766][E](PTable): Success! + 354529 [2754767][E](PTable): Clean Power Table + 354530 [2754767][E](PTable): Averaged Entry: watts=132.000000, cad=79.800003, targetPosition=1210.00000, (4)(4) + 354531 [2754778][E](PTable): cellValue: (106) wattDelta: (2.000000) cadDelta: (0.333333) allNeighborsPassed: (0) + 354532 [2754790][E](PTable): rightValue: (0.000000) leftValue: (100.000000) bottomValue: (105.400009) topValue: (0.000000) New averaged targetPosition: (102.700005) count: (2) + 354533 [2754802][E](PTable): Bottom failed at: (105) Target pos: (102.700005) Avg pos: (103) + 354534 [2754813][E](PTable): All test failed bottom (3)(4)(113), readings (11) + 354535 [2754813][E](PTable): WEIGHTED DOWNVOTING: Target Value: (102), NeighborValue: (105) + 354536 [2754824][E](PTable): WEIGHTED DOWNVOTING: Delta: (3), Penalty: (0) + 354537 [2754824][E](PTable): PT failed (5)(4)(105), readings (10) + 354538 [2754836][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354539 [2754857][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354540 [2754889][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354541 [2754912][E](Custom_C): 01 19 <-targetPosition + 354542 [2754925][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354543 [2754947][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354544 [2754979][E](PTable): 80 rpm | | 58 | | | 106 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354545 [2755001][E](PTable): 85 rpm | | 24 | | | 105 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 354546 [2755023][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 354547 [2755055][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354548 [2755087][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 354549 [2755109][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354550 [2755141][E](PTable): Power Table Reset + 354551 [2755478][E](PTable): Success! + 354552 [2755880][E](Custom_C): 01 2a <-hMin + 354553 [2755947][E](Custom_C): 01 19 <-targetPosition + 354554 [2755992][E](Custom_C): 01 2b <-hMax + 354555 [2756182][E](PTable): Success! + 354556 [2756183][E](ERG_Mode): Proportional: -16.000000, Integral: -6.400000, Derivative: 0.400000 + 354557 [2756884][E](PTable): Success! + 354558 [2756892][E](Custom_C): 01 19 <-targetPosition + 354559 [2757589][E](PTable): Success! + 354560 [2757589][E](PTable): Clean Power Table + 354561 [2757590][E](PTable): Averaged Entry: watts=132.399994, cad=81.199997, targetPosition=1205.99998, (4)(4) + 354562 [2757602][E](PTable): cellValue: (106) wattDelta: (2.054795) cadDelta: (0.342466) allNeighborsPassed: (0) + 354563 [2757613][E](PTable): rightValue: (0.000000) leftValue: (99.965340) bottomValue: (109.503990) topValue: (0.000000) New averaged targetPosition: (104.734665) count: (2) + 354564 [2757624][E](PTable): Bottom failed at: (105) Target pos: (104.734665) Avg pos: (104) + 354565 [2757635][E](PTable): Current Position moved down is valid! Current position: 104.734665 + 354566 [2757635][E](PTable): Existing entry averaged (5)(4)(104), readings(10) + 354567 [2757882][E](Custom_C): 01 19 <-targetPosition + 354568 [2758309][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354569 [2758332][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354570 [2758353][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354571 [2758386][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354572 [2758407][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354573 [2758440][E](PTable): 80 rpm | 36 | 58 | 88 | | 106 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354574 [2758462][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354575 [2758494][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354576 [2758517][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354577 [2758549][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354578 [2758574][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354579 [2758595][E](PTable): Power Table Reset + 354580 [2758848][E](PTable): Success! + 354581 [2758919][E](Custom_C): 01 19 <-targetPosition + 354582 [2759550][E](PTable): Success! + 354583 [2759884][E](Custom_C): 01 19 <-targetPosition + 354584 [2760253][E](PTable): Success! + 354585 [2760897][E](Custom_C): 01 2a <-hMin + 354586 [2760957][E](PTable): Success! + 354587 [2760958][E](PTable): Clean Power Table + 354588 [2760958][E](PTable): Averaged Entry: watts=112.400002, cad=78.599998, targetPosition=1208.00003, (4)(4) + 354589 [2760970][E](PTable): cellValue: (106) wattDelta: (2.027027) cadDelta: (0.337838) allNeighborsPassed: (0) + 354590 [2760981][E](PTable): rightValue: (0.000000) leftValue: (109.749336) bottomValue: (101.855995) topValue: (0.000000) New averaged targetPosition: (105.802666) count: (2) + 354591 [2760993][E](Custom_C): 01 19 <-targetPosition + 354592 [2760995][E](PTable): Existing entry averaged (4)(4)(105), readings(11) + 354593 [2761055][E](Custom_C): 01 2b <-hMax + 354594 [2761696][E](Custom_C): 01 27 04 <-Power Tab Data + 354595 [2761701][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354596 [2761723][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354597 [2761757][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354598 [2761779][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354599 [2761812][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 113 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354600 [2761833][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354601 [2761866][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354602 [2761887][E](Custom_C): 01 19 <-targetPosition + 354603 [2761891][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354604 [2761923][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354605 [2761945][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354606 [2761977][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354607 [2761998][E](PTable): Power Table Reset + 354608 [2761999][E](ERG_Mode): Proportional: 56.000000, Integral: 0.400000, Derivative: -0.600000 + 354609 [2762243][E](PTable): Success! + 354610 [2762316][E](Custom_C): 01 25 <-Firmware Version + 354611 [2762900][E](Custom_C): 01 19 <-targetPosition + 354612 [2762944][E](PTable): Success! + 354613 [2763649][E](PTable): Success! + 354614 [2763890][E](Custom_C): 01 19 <-targetPosition + 354615 [2764353][E](PTable): Success! + 354616 [2764354][E](PTable): Clean Power Table + 354617 [2764354][E](PTable): Averaged Entry: watts=121.199997, cad=79.400002, targetPosition=1218.00003, (4)(4) + 354618 [2764366][E](PTable): cellValue: (105) wattDelta: (1.785714) cadDelta: (0.297619) allNeighborsPassed: (0) + 354619 [2764377][E](PTable): rightValue: (0.000000) leftValue: (104.328003) bottomValue: (102.984009) topValue: (0.000000) New averaged targetPosition: (103.656006) count: (2) + 354620 [2764388][E](PTable): Bottom failed at: (104) Target pos: (103.656006) Avg pos: (103) + 354621 [2764399][E](PTable): All test failed bottom (3)(4)(113), readings (11) + 354622 [2764399][E](PTable): WEIGHTED DOWNVOTING: Target Value: (103), NeighborValue: (104) + 354623 [2764409][E](PTable): WEIGHTED DOWNVOTING: Delta: (1), Penalty: (0) + 354624 [2764410][E](PTable): PT failed (5)(4)(104), readings (11) + 354625 [2764422][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354626 [2764444][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354627 [2764476][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354628 [2764498][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354629 [2764531][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354630 [2764553][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354631 [2764584][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 354632 [2764606][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 354633 [2764638][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354634 [2764660][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 354635 [2764692][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354636 [2764713][E](PTable): Power Table Reset + 354637 [2764891][E](Custom_C): 01 19 <-targetPosition + 354638 [2765055][E](PTable): Success! + 354639 [2765758][E](PTable): Success! + 354640 [2765905][E](Custom_C): 01 27 00 <-Power Tab Data + 354641 [2765937][E](Custom_C): 01 2a <-hMin + 354642 [2766004][E](Custom_C): 01 19 <-targetPosition + 354643 [2766085][E](Custom_C): 01 27 01 <-Power Tab Data + 354644 [2766117][E](Custom_C): 01 2b <-hMax + 354645 [2766175][E](Custom_C): 01 27 02 <-Power Tab Data + 354646 [2766219][E](Custom_C): 01 27 03 <-Power Tab Data + 354647 [2766265][E](Custom_C): 01 27 04 <-Power Tab Data + 354648 [2766310][E](Custom_C): 01 27 05 <-Power Tab Data + 354649 [2766354][E](Custom_C): 01 27 06 <-Power Tab Data + 354650 [2766400][E](Custom_C): 01 27 07 <-Power Tab Data + 354651 [2766444][E](Custom_C): 01 27 08 <-Power Tab Data + 354652 [2766464][E](PTable): Success! + 354653 [2766490][E](Custom_C): 01 27 09 <-Power Tab Data + 354654 [2766522][E](Custom_C): 01 25 <-Firmware Version + 354655 [2766905][E](Custom_C): 01 19 <-targetPosition + 354656 [2767171][E](PTable): Success! + 354657 [2767173][E](PTable): Clean Power Table + 354658 [2767173][E](PTable): Averaged Entry: watts=106.400002, cad=77.599998, targetPosition=1240.00000, (4)(4) + 354659 [2767185][E](PTable): cellValue: (105) wattDelta: (1.578947) cadDelta: (0.263158) allNeighborsPassed: (0) + 354660 [2767186][E](PTable): rightValue: (0.000000) leftValue: (113.613335) bottomValue: (95.879997) topValue: (0.000000) New averaged targetPosition: (104.746666) count: (2) + 354661 [2767207][E](PTable): Bottom failed at: (104) Target pos: (104.746666) Avg pos: (104) + 354662 [2767208][E](PTable): Was not in range failed bottom (5)(4)(104), readings (11) + 354663 [2767218][E](PTable): WEIGHTED DOWNVOTING: Target Value: (104), NeighborValue: (104) + 354664 [2767228][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 354665 [2767229][E](PTable): PT failed (5)(4)(104), readings (11) + 354666 [2767241][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354667 [2767264][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354668 [2767297][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354669 [2767319][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354670 [2767351][E](PTable): 75 rpm | 48 | 64 | | | 113 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354671 [2767372][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354672 [2767405][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 354673 [2767426][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 354674 [2767458][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354675 [2767480][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 354676 [2767512][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354677 [2767533][E](PTable): Power Table Reset + 354678 [2767534][E](ERG_Mode): Proportional: 104.000000, Integral: 8.600000, Derivative: -1.200000 + 354679 [2767917][E](Custom_C): 01 19 <-targetPosition + 354680 [2767970][E](PTable): Success! + 354681 [2768675][E](PTable): Success! + 354682 [2768885][E](Custom_C): 01 19 <-targetPosition + 354683 [2769378][E](PTable): Success! + 354684 [2769897][E](Custom_C): 01 19 <-targetPosition + 354685 [2770081][E](PTable): Success! + 354686 [2770082][E](PTable): Clean Power Table + 354687 [2770082][E](PTable): Averaged Entry: watts=122.000000, cad=73.800003, targetPosition=1270.00000, (3)(4) + 354688 [2770094][E](PTable): cellValue: (113) wattDelta: (2.142857) cadDelta: (0.357143) allNeighborsPassed: (0) + 354689 [2770105][E](PTable): rightValue: (0.000000) leftValue: (112.066666) bottomValue: (109.640007) topValue: (0.000000) New averaged targetPosition: (110.853333) count: (2) + 354690 [2770116][E](PTable): Existing entry averaged (3)(4)(112), readings(11) + 354691 [2770792][E](Custom_C): 01 27 03 <-Power Tab Data + 354692 [2770798][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354693 [2770820][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354694 [2770852][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354695 [2770874][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354696 [2770906][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 112 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354697 [2770950][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354698 [2770973][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354699 [2771018][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354700 [2771040][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354701 [2771086][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354702 [2771108][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354703 [2771139][E](PTable): Power Table Reset + 354704 [2771343][E](PTable): Success! + 354705 [2771899][E](Custom_C): 01 19 <-targetPosition + 354706 [2772044][E](PTable): Success! + 354707 [2772747][E](PTable): Success! + 354708 [2772890][E](Custom_C): 01 19 <-targetPosition + 354709 [2773451][E](PTable): Success! + 354710 [2773452][E](PTable): Clean Power Table + 354711 [2773452][E](PTable): Averaged Entry: watts=156.399994, cad=76.800003, targetPosition=1251.99997, (3)(5) + 354712 [2773464][E](PTable): cellValue: (125) wattDelta: (150.002289) cadDelta: (25.000381) allNeighborsPassed: (1) + 354713 [2773475][E](PTable): rightValue: (125.042664) leftValue: (124.957336) bottomValue: (125.071999) topValue: (124.928001) New averaged targetPosition: (125.000000) count: (4) + 354714 [2773486][E](PTable): Existing entry averaged (3)(5)(125), readings(10) + 354715 [2773902][E](Custom_C): 01 19 <-targetPosition + 354716 [2774189][E](Custom_C): 01 27 03 <-Power Tab Data + 354717 [2774195][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354718 [2774217][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354719 [2774250][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354720 [2774272][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354721 [2774304][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 112 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354722 [2774326][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354723 [2774360][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354724 [2774381][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354725 [2774414][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354726 [2774436][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354727 [2774468][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354728 [2774489][E](PTable): Power Table Reset + 354729 [2774489][E](ERG_Mode): Proportional: 32.000000, Integral: -0.200000, Derivative: 0.800000 + 354730 [2774800][E](PTable): Success! + 354731 [2774893][E](Custom_C): 01 19 <-targetPosition + 354732 [2775505][E](PTable): Success! + 354733 [2775905][E](Custom_C): 01 2a <-hMin + 354734 [2775972][E](Custom_C): 01 19 <-targetPosition + 354735 [2776040][E](Custom_C): 01 2b <-hMax + 354736 [2776208][E](PTable): Success! + 354737 [2776884][E](Custom_C): 01 19 <-targetPosition + 354738 [2776910][E](PTable): Success! + 354739 [2776914][E](PTable): Clean Power Table + 354740 [2776915][E](PTable): Averaged Entry: watts=117.199997, cad=73.800003, targetPosition=1248.00003, (3)(4) + 354741 [2776927][E](PTable): cellValue: (112) wattDelta: (2.343750) cadDelta: (0.390625) allNeighborsPassed: (1) + 354742 [2776928][E](PTable): rightValue: (110.805328) leftValue: (113.194672) bottomValue: (108.928009) topValue: (115.071991) New averaged targetPosition: (112.000000) count: (4) + 354743 [2776949][E](PTable): Existing entry averaged (3)(4)(112), readings(11) + 354744 [2777641][E](Custom_C): 01 27 03 <-Power Tab Data + 354745 [2777646][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354746 [2777667][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354747 [2777699][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354748 [2777721][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354749 [2777753][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 112 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354750 [2777775][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354751 [2777807][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354752 [2777829][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354753 [2777861][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354754 [2777884][E](Custom_C): 01 19 <-targetPosition + 354755 [2777898][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354756 [2777920][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354757 [2777943][E](PTable): Power Table Reset + 354758 [2778203][E](PTable): Success! + 354759 [2778897][E](Custom_C): 01 19 <-targetPosition + 354760 [2778908][E](PTable): Success! + 354761 [2779611][E](PTable): Success! + 354762 [2779612][E](ERG_Mode): Proportional: 40.000000, Integral: 7.000000, Derivative: -0.800000 + 354763 [2779887][E](Custom_C): 01 19 <-targetPosition + 354764 [2780315][E](PTable): Success! + 354765 [2780316][E](PTable): Clean Power Table + 354766 [2780316][E](PTable): Averaged Entry: watts=115.199997, cad=73.000000, targetPosition=1261.99997, (3)(4) + 354767 [2780328][E](PTable): cellValue: (112) wattDelta: (2.112677) cadDelta: (0.352113) allNeighborsPassed: (0) + 354768 [2780339][E](PTable): rightValue: (0.000000) leftValue: (114.272003) bottomValue: (106.320000) topValue: (0.000000) New averaged targetPosition: (110.296005) count: (2) + 354769 [2780352][E](PTable): Existing entry averaged (3)(4)(111), readings(11) + 354770 [2780934][E](Custom_C): 01 27 00 <-Power Tab Data + 354771 [2780967][E](Custom_C): 01 2a <-hMin + 354772 [2781012][E](Custom_C): 01 19 <-targetPosition + 354773 [2781073][E](Custom_C): 01 27 01 <-Power Tab Data + 354774 [2781086][E](Custom_C): 01 27 03 <-Power Tab Data + 354775 [2781091][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354776 [2781113][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354777 [2781147][E](Custom_C): 01 2b <-hMax + 354778 [2781152][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354779 [2781173][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354780 [2781207][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 111 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354781 [2781265][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354782 [2781287][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354783 [2781320][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354784 [2781374][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354785 [2781396][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354786 [2781429][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354787 [2781482][E](PTable): Power Table Reset + 354788 [2781525][E](Custom_C): 01 27 05 <-Power Tab Data + 354789 [2781589][E](Custom_C): 01 27 06 <-Power Tab Data + 354790 [2781661][E](Custom_C): 01 27 07 <-Power Tab Data + 354791 [2781748][E](Custom_C): 01 27 08 <-Power Tab Data + 354792 [2781806][E](PTable): Success! + 354793 [2781812][E](Custom_C): 01 27 09 <-Power Tab Data + 354794 [2781890][E](Custom_C): 01 19 <-targetPosition + 354795 [2782272][E](Custom_C): 01 25 <-Firmware Version + 354796 [2782507][E](PTable): Success! + 354797 [2782880][E](Custom_C): 01 19 <-targetPosition + 354798 [2783212][E](PTable): Success! + 354799 [2783213][E](PTable): Using detected travel limits during homing + 354800 [2783893][E](Custom_C): 01 19 <-targetPosition + 354801 [2783917][E](PTable): Success! + 354802 [2783918][E](PTable): Clean Power Table + 354803 [2783918][E](PTable): Averaged Entry: watts=124.800003, cad=72.599998, targetPosition=1270.00000, (3)(4) + 354804 [2783930][E](PTable): cellValue: (111) wattDelta: (1.875000) cadDelta: (0.312500) allNeighborsPassed: (0) + 354805 [2783941][E](PTable): rightValue: (0.000000) leftValue: (108.440002) bottomValue: (103.319992) topValue: (0.000000) New averaged targetPosition: (105.879997) count: (2) + 354806 [2783952][E](PTable): Bottom failed at: (105) Target pos: (105.879997) Avg pos: (105) + 354807 [2783962][E](PTable): Was not in range failed bottom (4)(4)(105), readings (11) + 354808 [2783963][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (105) + 354809 [2783974][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 354810 [2783985][E](PTable): PT failed (4)(4)(105), readings (11) + 354811 [2783986][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354812 [2784008][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354813 [2784040][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354814 [2784061][E](PTable): 70 rpm | 60 | 80 | | 111 | 126 | 133 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354815 [2784094][E](PTable): 75 rpm | 48 | 64 | | | 111 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354816 [2784116][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354817 [2784148][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 354818 [2784169][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 354819 [2784201][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 354820 [2784224][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 354821 [2784256][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 354822 [2784277][E](PTable): Power Table Reset + 354823 [2784618][E](PTable): Success! + 354824 [2784882][E](Custom_C): 01 19 <-targetPosition + 354825 [2785322][E](PTable): Success! + 354826 [2785323][E](ERG_Mode): Proportional: 0.000000, Integral: 6.000000, Derivative: -0.800000 + 354827 [2785894][E](Custom_C): 01 2a <-hMin + 354828 [2785962][E](Custom_C): 01 19 <-targetPosition + 354829 [2786006][E](Custom_C): 01 2b <-hMax + 354830 [2786028][E](PTable): Success! + 354831 [2786052][E](Custom_C): 01 25 <-Firmware Version + 354832 [2786731][E](PTable): Success! + 354833 [2786732][E](PTable): Clean Power Table + 354834 [2786732][E](PTable): Averaged Entry: watts=124.800003, cad=74.000000, targetPosition=1280.00000, (3)(4) + 354835 [2786743][E](PTable): cellValue: (111) wattDelta: (1.764706) cadDelta: (0.294118) allNeighborsPassed: (0) + 354836 [2786755][E](PTable): rightValue: (0.000000) leftValue: (108.279999) bottomValue: (107.599998) topValue: (0.000000) New averaged targetPosition: (107.940002) count: (2) + 354837 [2786766][E](PTable): Existing entry averaged (3)(4)(110), readings(11) + 354838 [2786885][E](Custom_C): 01 19 <-targetPosition + 354839 [2787457][E](Custom_C): 01 27 03 <-Power Tab Data + 354840 [2787464][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354841 [2787486][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354842 [2787518][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354843 [2787540][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354844 [2787572][E](PTable): 75 rpm | 48 | 64 | 91 | 109 | 110 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354845 [2787594][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354846 [2787626][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354847 [2787648][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354848 [2787682][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354849 [2787705][E](PTable): 100 rpm | -12 | 11 | 72 | 99 | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354850 [2787726][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354851 [2787757][E](PTable): Power Table Reset + 354852 [2787897][E](Custom_C): 01 19 <-targetPosition + 354853 [2787977][E](PTable): Success! + 354854 [2788681][E](PTable): Success! + 354855 [2788933][E](Custom_C): 01 19 <-targetPosition + 354856 [2789384][E](PTable): Success! + 354857 [2789899][E](Custom_C): 01 19 <-targetPosition + 354858 [2790087][E](PTable): Success! + 354859 [2790088][E](PTable): Clean Power Table + 354860 [2790088][E](PTable): Averaged Entry: watts=118.800003, cad=73.000000, targetPosition=1281.99997, (3)(4) + 354861 [2790100][E](PTable): cellValue: (110) wattDelta: (1.648352) cadDelta: (0.274725) allNeighborsPassed: (0) + 354862 [2790112][E](PTable): rightValue: (0.000000) leftValue: (110.727997) bottomValue: (102.720001) topValue: (0.000000) New averaged targetPosition: (106.723999) count: (2) + 354863 [2790123][E](PTable): Existing entry averaged (3)(4)(109), readings(11) + 354864 [2790785][E](Custom_C): 01 27 03 <-Power Tab Data + 354865 [2790790][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354866 [2790811][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354867 [2790844][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354868 [2790866][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354869 [2790897][E](Custom_C): 01 2a <-hMin + 354870 [2790901][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354871 [2790923][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354872 [2790957][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354873 [2790981][E](Custom_C): 01 19 <-targetPosition + 354874 [2790986][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354875 [2791018][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354876 [2791053][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354877 [2791075][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354878 [2791106][E](PTable): Power Table Reset + 354879 [2791107][E](ERG_Mode): Proportional: 16.000000, Integral: 6.400000, Derivative: -0.600000 + 354880 [2791336][E](PTable): Success! + 354881 [2791902][E](Custom_C): 01 19 <-targetPosition + 354882 [2792038][E](PTable): Success! + 354883 [2792743][E](PTable): Success! + 354884 [2792892][E](Custom_C): 01 19 <-targetPosition + 354885 [2793447][E](PTable): Success! + 354886 [2793448][E](PTable): Clean Power Table + 354887 [2793449][E](PTable): Averaged Entry: watts=122.400002, cad=72.000000, targetPosition=1290.00000, (2)(4) + 354888 [2793460][E](PTable): cellValue: (126) wattDelta: (10.000000) cadDelta: (1.666667) allNeighborsPassed: (1) + 354889 [2793471][E](PTable): rightValue: (126.239998) leftValue: (125.760002) bottomValue: (127.199997) topValue: (124.800003) New averaged targetPosition: (126.000000) count: (4) + 354890 [2793481][E](PTable): Existing entry averaged (2)(4)(126), readings(2) + 354891 [2793882][E](Custom_C): 01 19 <-targetPosition + 354892 [2794156][E](Custom_C): 01 27 02 <-Power Tab Data + 354893 [2794161][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354894 [2794183][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354895 [2794216][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354896 [2794238][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354897 [2794271][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354898 [2794292][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354899 [2794325][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354900 [2794347][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354901 [2794379][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354902 [2794400][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354903 [2794433][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354904 [2794454][E](PTable): Power Table Reset + 354905 [2794691][E](PTable): Success! + 354906 [2794884][E](Custom_C): 01 19 <-targetPosition + 354907 [2795393][E](PTable): Success! + 354908 [2795919][E](Custom_C): 01 27 00 <-Power Tab Data + 354909 [2795974][E](Custom_C): 01 2a <-hMin + 354910 [2796019][E](Custom_C): 01 19 <-targetPosition + 354911 [2796076][E](Custom_C): 01 27 01 <-Power Tab Data + 354912 [2796096][E](PTable): Success! + 354913 [2796109][E](Custom_C): 01 2b <-hMax + 354914 [2796189][E](Custom_C): 01 27 02 <-Power Tab Data + 354915 [2796234][E](Custom_C): 01 27 03 <-Power Tab Data + 354916 [2796280][E](Custom_C): 01 27 04 <-Power Tab Data + 354917 [2796335][E](Custom_C): 01 27 05 <-Power Tab Data + 354918 [2796392][E](Custom_C): 01 27 06 <-Power Tab Data + 354919 [2796436][E](Custom_C): 01 27 07 <-Power Tab Data + 354920 [2796505][E](Custom_C): 01 27 08 <-Power Tab Data + 354921 [2796548][E](Custom_C): 01 27 09 <-Power Tab Data + 354922 [2796844][E](PTable): Success! + 354923 [2796845][E](PTable): Clean Power Table + 354924 [2796845][E](PTable): Averaged Entry: watts=127.599998, cad=72.000000, targetPosition=1293.99994, (2)(4) + 354925 [2796856][E](PTable): cellValue: (126) wattDelta: (8.823545) cadDelta: (1.470591) allNeighborsPassed: (1) + 354926 [2796867][E](PTable): rightValue: (126.861328) leftValue: (125.138672) bottomValue: (127.360001) topValue: (124.639999) New averaged targetPosition: (126.000000) count: (4) + 354927 [2796878][E](PTable): Existing entry averaged (2)(4)(126), readings(3) + 354928 [2796899][E](Custom_C): 01 19 <-targetPosition + 354929 [2797594][E](Custom_C): 01 27 02 <-Power Tab Data + 354930 [2797599][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354931 [2797621][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354932 [2797653][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354933 [2797675][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354934 [2797707][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354935 [2797729][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354936 [2797761][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354937 [2797783][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354938 [2797815][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354939 [2797837][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354940 [2797869][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354941 [2797890][E](Custom_C): 01 19 <-targetPosition + 354942 [2797894][E](PTable): Power Table Reset + 354943 [2797895][E](ERG_Mode): Proportional: 0.000000, Integral: 6.000000, Derivative: -0.800000 + 354944 [2798161][E](PTable): Success! + 354945 [2798866][E](PTable): Success! + 354946 [2798877][E](Custom_C): 01 19 <-targetPosition + 354947 [2799571][E](PTable): Success! + 354948 [2799890][E](Custom_C): 01 19 <-targetPosition + 354949 [2800273][E](PTable): Success! + 354950 [2800274][E](PTable): Clean Power Table + 354951 [2800274][E](PTable): Averaged Entry: watts=128.399994, cad=71.599998, targetPosition=1300.00000, (2)(4) + 354952 [2800285][E](PTable): cellValue: (126) wattDelta: (7.500000) cadDelta: (1.250000) allNeighborsPassed: (0) + 354953 [2800297][E](PTable): rightValue: (127.120003) leftValue: (124.879997) bottomValue: (127.279999) topValue: (0.000000) New averaged targetPosition: (126.426666) count: (3) + 354954 [2800308][E](PTable): Existing entry averaged (2)(4)(126), readings(4) + 354955 [2800880][E](Custom_C): 01 2a <-hMin + 354956 [2800924][E](Custom_C): 01 19 <-targetPosition + 354957 [2800980][E](Custom_C): 01 27 02 <-Power Tab Data + 354958 [2800986][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354959 [2801030][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354960 [2801052][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354961 [2801076][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354962 [2801108][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354963 [2801129][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354964 [2801161][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354965 [2801183][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354966 [2801216][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354967 [2801238][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354968 [2801270][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354969 [2801291][E](PTable): Power Table Reset + 354970 [2801550][E](PTable): Success! + 354971 [2801914][E](Custom_C): 01 19 <-targetPosition + 354972 [2802251][E](PTable): Success! + 354973 [2802274][E](Custom_C): 01 25 <-Firmware Version + 354974 [2802882][E](Custom_C): 01 19 <-targetPosition + 354975 [2802953][E](PTable): Success! + 354976 [2803657][E](PTable): Success! + 354977 [2803658][E](PTable): Clean Power Table + 354978 [2803658][E](PTable): Averaged Entry: watts=124.000000, cad=71.800003, targetPosition=1300.00000, (2)(4) + 354979 [2803669][E](PTable): cellValue: (126) wattDelta: (7.500000) cadDelta: (1.250000) allNeighborsPassed: (0) + 354980 [2803681][E](PTable): rightValue: (126.533333) leftValue: (125.466667) bottomValue: (127.440002) topValue: (0.000000) New averaged targetPosition: (126.480003) count: (3) + 354981 [2803692][E](PTable): Existing entry averaged (2)(4)(126), readings(5) + 354982 [2803894][E](Custom_C): 01 19 <-targetPosition + 354983 [2804396][E](Custom_C): 01 27 02 <-Power Tab Data + 354984 [2804402][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 354985 [2804423][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 354986 [2804457][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 354987 [2804479][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 354988 [2804511][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 354989 [2804532][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 354990 [2804564][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 354991 [2804586][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 354992 [2804618][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 354993 [2804640][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 354994 [2804672][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 354995 [2804693][E](PTable): Power Table Reset + 354996 [2804704][E](ERG_Mode): Proportional: 40.000000, Integral: 7.000000, Derivative: 0.200000 + 354997 [2804885][E](Custom_C): 01 19 <-targetPosition + 354998 [2804941][E](PTable): Success! + 354999 [2805645][E](PTable): Success! + 355000 [2805897][E](Custom_C): 01 2a <-hMin + 355001 [2805942][E](Custom_C): 01 19 <-targetPosition + 355002 [2806010][E](Custom_C): 01 2b <-hMax + 355003 [2806077][E](Custom_C): 01 25 <-Firmware Version + 355004 [2806347][E](PTable): Success! + 355005 [2806887][E](Custom_C): 01 19 <-targetPosition + 355006 [2807054][E](PTable): Success! + 355007 [2807055][E](PTable): Clean Power Table + 355008 [2807055][E](PTable): Averaged Entry: watts=120.000000, cad=71.599998, targetPosition=1306.00006, (2)(4) + 355009 [2807066][E](PTable): cellValue: (126) wattDelta: (6.521730) cadDelta: (1.086955) allNeighborsPassed: (0) + 355010 [2807077][E](PTable): rightValue: (126.000000) leftValue: (126.000000) bottomValue: (127.472000) topValue: (0.000000) New averaged targetPosition: (126.490662) count: (3) + 355011 [2807088][E](PTable): Existing entry averaged (2)(4)(126), readings(6) + 355012 [2807752][E](Custom_C): 01 27 02 <-Power Tab Data + 355013 [2807757][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355014 [2807779][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355015 [2807811][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355016 [2807834][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355017 [2807866][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355018 [2807888][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355019 [2807941][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355020 [2807963][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355021 [2807995][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355022 [2808016][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355023 [2808049][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355024 [2808070][E](PTable): Power Table Reset + 355025 [2808280][E](PTable): Success! + 355026 [2808890][E](Custom_C): 01 19 <-targetPosition + 355027 [2808985][E](PTable): Success! + 355028 [2809686][E](PTable): Success! + 355029 [2809925][E](Custom_C): 01 19 <-targetPosition + 355030 [2810389][E](PTable): Success! + 355031 [2810390][E](PTable): Clean Power Table + 355032 [2810390][E](PTable): Averaged Entry: watts=131.600006, cad=71.199997, targetPosition=1310.00000, (2)(4) + 355033 [2810404][E](PTable): cellValue: (126) wattDelta: (6.000000) cadDelta: (1.000000) allNeighborsPassed: (0) + 355034 [2810405][E](PTable): rightValue: (127.933334) leftValue: (124.066666) bottomValue: (127.199997) topValue: (0.000000) New averaged targetPosition: (126.400002) count: (3) + 355035 [2810426][E](PTable): Existing entry averaged (2)(4)(126), readings(7) + 355036 [2810906][E](Custom_C): 01 27 00 <-Power Tab Data + 355037 [2810936][E](Custom_C): 01 2a <-hMin + 355038 [2810981][E](Custom_C): 01 19 <-targetPosition + 355039 [2811062][E](Custom_C): 01 27 01 <-Power Tab Data + 355040 [2811094][E](Custom_C): 01 2b <-hMax + 355041 [2811174][E](Custom_C): 01 27 02 <-Power Tab Data + 355042 [2811200][E](Custom_C): 01 27 02 <-Power Tab Data + 355043 [2811211][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355044 [2811267][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355045 [2811288][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355046 [2811322][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355047 [2811375][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355048 [2811397][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355049 [2811421][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355050 [2811489][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355051 [2811510][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355052 [2811534][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355053 [2811567][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355054 [2811627][E](PTable): Power Table Reset + 355055 [2811628][E](ERG_Mode): Proportional: -40.000000, Integral: 5.000000, Derivative: -1.200000 + 355056 [2811693][E](Custom_C): 01 27 07 <-Power Tab Data + 355057 [2811762][E](Custom_C): 01 27 08 <-Power Tab Data + 355058 [2811831][E](Custom_C): 01 27 09 <-Power Tab Data + 355059 [2811883][E](Custom_C): 01 19 <-targetPosition + 355060 [2812000][E](PTable): Success! + 355061 [2812701][E](PTable): Success! + 355062 [2812894][E](Custom_C): 01 19 <-targetPosition + 355063 [2813403][E](PTable): Success! + 355064 [2813885][E](Custom_C): 01 19 <-targetPosition + 355065 [2814108][E](PTable): Success! + 355066 [2814109][E](PTable): Clean Power Table + 355067 [2814109][E](PTable): Averaged Entry: watts=121.599998, cad=71.000000, targetPosition=1316.00006, (2)(4) + 355068 [2814121][E](PTable): cellValue: (126) wattDelta: (5.357137) cadDelta: (0.892856) allNeighborsPassed: (0) + 355069 [2814132][E](PTable): rightValue: (126.298668) leftValue: (125.701332) bottomValue: (127.120003) topValue: (0.000000) New averaged targetPosition: (126.373329) count: (3) + 355070 [2814144][E](PTable): Existing entry averaged (2)(4)(126), readings(8) + 355071 [2814785][E](Custom_C): 01 27 02 <-Power Tab Data + 355072 [2814793][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355073 [2814815][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355074 [2814848][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355075 [2814869][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 126 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355076 [2814902][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355077 [2814923][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355078 [2814969][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355079 [2814990][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355080 [2815023][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355081 [2815045][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355082 [2815067][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355083 [2815098][E](PTable): Power Table Reset + 355084 [2815288][E](PTable): Success! + 355085 [2815887][E](Custom_C): 01 2a <-hMin + 355086 [2815954][E](Custom_C): 01 19 <-targetPosition + 355087 [2815992][E](PTable): Success! + 355088 [2815999][E](Custom_C): 01 2b <-hMax + 355089 [2816695][E](PTable): Success! + 355090 [2816696][E](ERG_Mode): Proportional: 24.000000, Integral: 6.600000, Derivative: 0.200000 + 355091 [2816899][E](Custom_C): 01 19 <-targetPosition + 355092 [2817398][E](PTable): Success! + 355093 [2817399][E](PTable): Clean Power Table + 355094 [2817399][E](PTable): Averaged Entry: watts=125.599998, cad=69.000000, targetPosition=1320.00000, (2)(4) + 355095 [2817411][E](PTable): cellValue: (126) wattDelta: (5.000000) cadDelta: (0.833333) allNeighborsPassed: (0) + 355096 [2817422][E](PTable): rightValue: (127.120003) leftValue: (124.879997) bottomValue: (124.800003) topValue: (0.000000) New averaged targetPosition: (125.599998) count: (3) + 355097 [2817433][E](PTable): Existing entry averaged (2)(4)(125), readings(9) + 355098 [2817890][E](Custom_C): 01 19 <-targetPosition + 355099 [2818132][E](Custom_C): 01 27 02 <-Power Tab Data + 355100 [2818137][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355101 [2818160][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355102 [2818192][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355103 [2818214][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 125 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355104 [2818246][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355105 [2818268][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355106 [2818300][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355107 [2818322][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355108 [2818354][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355109 [2818376][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355110 [2818408][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355111 [2818429][E](PTable): Power Table Reset + 355112 [2818657][E](PTable): Success! + 355113 [2818902][E](Custom_C): 01 19 <-targetPosition + 355114 [2819360][E](PTable): Success! + 355115 [2819892][E](Custom_C): 01 19 <-targetPosition + 355116 [2820063][E](PTable): Success! + 355117 [2820764][E](PTable): Success! + 355118 [2820765][E](PTable): Clean Power Table + 355119 [2820765][E](PTable): Averaged Entry: watts=122.800003, cad=67.599998, targetPosition=1326.00006, (2)(4) + 355120 [2820777][E](PTable): cellValue: (125) wattDelta: (3.947365) cadDelta: (0.657894) allNeighborsPassed: (0) + 355121 [2820788][E](PTable): rightValue: (125.709335) leftValue: (124.290665) bottomValue: (121.351997) topValue: (0.000000) New averaged targetPosition: (123.783997) count: (3) + 355122 [2820799][E](PTable): Existing entry averaged (2)(4)(124), readings(10) + 355123 [2820894][E](Custom_C): 01 2a <-hMin + 355124 [2820926][E](Custom_C): 01 19 <-targetPosition + 355125 [2820994][E](Custom_C): 01 2b <-hMax + 355126 [2821488][E](Custom_C): 01 27 02 <-Power Tab Data + 355127 [2821498][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355128 [2821519][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355129 [2821555][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355130 [2821578][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 124 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355131 [2821601][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355132 [2821633][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355133 [2821657][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355134 [2821689][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355135 [2821711][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355136 [2821743][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355137 [2821766][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355138 [2821787][E](PTable): Power Table Reset + 355139 [2821798][E](ERG_Mode): Proportional: -16.000000, Integral: 5.600000, Derivative: -1.200000 + 355140 [2821898][E](Custom_C): 01 19 <-targetPosition + 355141 [2822050][E](PTable): Success! + 355142 [2822277][E](Custom_C): 01 25 <-Firmware Version + 355143 [2822755][E](PTable): Success! + 355144 [2822907][E](Custom_C): 01 19 <-targetPosition + 355145 [2823457][E](PTable): Success! + 355146 [2823896][E](Custom_C): 01 19 <-targetPosition + 355147 [2824163][E](PTable): Success! + 355148 [2824164][E](PTable): Clean Power Table + 355149 [2824165][E](PTable): Averaged Entry: watts=129.600006, cad=67.199997, targetPosition=1331.99997, (1)(4) + 355150 [2824177][E](PTable): cellValue: (130) wattDelta: (9.375009) cadDelta: (1.562502) allNeighborsPassed: (0) + 355151 [2824188][E](PTable): rightValue: (131.024002) leftValue: (128.975998) bottomValue: (131.407990) topValue: (0.000000) New averaged targetPosition: (130.469330) count: (3) + 355152 [2824199][E](PTable): Existing entry averaged (1)(4)(130), readings(11) + 355153 [2824842][E](Custom_C): 01 27 01 <-Power Tab Data + 355154 [2824848][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355155 [2824870][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355156 [2824902][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355157 [2824923][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 124 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355158 [2824955][E](Custom_C): 01 19 <-targetPosition + 355159 [2824959][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355160 [2824981][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355161 [2825013][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355162 [2825037][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355163 [2825069][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355164 [2825091][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355165 [2825123][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355166 [2825144][E](PTable): Power Table Reset + 355167 [2825354][E](PTable): Success! + 355168 [2825912][E](Custom_C): 01 27 00 <-Power Tab Data + 355169 [2825944][E](Custom_C): 01 2a <-hMin + 355170 [2825989][E](Custom_C): 01 19 <-targetPosition + 355171 [2826046][E](Custom_C): 01 27 01 <-Power Tab Data + 355172 [2826061][E](PTable): Success! + 355173 [2826062][E](PTable): Using detected travel limits during homing + 355174 [2826102][E](Custom_C): 01 2b <-hMax + 355175 [2826159][E](Custom_C): 01 27 02 <-Power Tab Data + 355176 [2826215][E](Custom_C): 01 27 03 <-Power Tab Data + 355177 [2826272][E](Custom_C): 01 27 04 <-Power Tab Data + 355178 [2826317][E](Custom_C): 01 27 05 <-Power Tab Data + 355179 [2826391][E](Custom_C): 01 27 06 <-Power Tab Data + 355180 [2826453][E](Custom_C): 01 27 07 <-Power Tab Data + 355181 [2826522][E](Custom_C): 01 27 08 <-Power Tab Data + 355182 [2826566][E](Custom_C): 01 27 09 <-Power Tab Data + 355183 [2826620][E](Custom_C): 01 25 <-Firmware Version + 355184 [2826766][E](PTable): Success! + 355185 [2826912][E](Custom_C): 01 19 <-targetPosition + 355186 [2827508][E](PTable): Success! + 355187 [2827509][E](PTable): Clean Power Table + 355188 [2827509][E](PTable): Averaged Entry: watts=130.000000, cad=68.000000, targetPosition=1340.00000, (2)(4) + 355189 [2827521][E](PTable): cellValue: (124) wattDelta: (3.000000) cadDelta: (0.500000) allNeighborsPassed: (0) + 355190 [2827534][E](PTable): rightValue: (0.000000) leftValue: (120.666664) bottomValue: (120.000000) topValue: (0.000000) New averaged targetPosition: (120.333328) count: (2) + 355191 [2827545][E](PTable): Existing entry averaged (2)(4)(123), readings(11) + 355192 [2827879][E](Custom_C): 01 19 <-targetPosition + 355193 [2828234][E](Custom_C): 01 27 02 <-Power Tab Data + 355194 [2828240][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355195 [2828262][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355196 [2828294][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355197 [2828317][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 123 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355198 [2828349][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355199 [2828371][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355200 [2828402][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355201 [2828426][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355202 [2828458][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355203 [2828479][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355204 [2828511][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355205 [2828532][E](PTable): Power Table Reset + 355206 [2828543][E](ERG_Mode): Proportional: -16.000000, Integral: 5.400000, Derivative: -0.200000 + 355207 [2828793][E](PTable): Success! + 355208 [2828892][E](Custom_C): 01 19 <-targetPosition + 355209 [2829494][E](PTable): Success! + 355210 [2829882][E](Custom_C): 01 19 <-targetPosition + 355211 [2830195][E](PTable): Success! + 355212 [2830896][E](Custom_C): 01 2a <-hMin + 355213 [2830901][E](PTable): Success! + 355214 [2830901][E](PTable): Clean Power Table + 355215 [2830902][E](PTable): Averaged Entry: watts=133.600006, cad=68.000000, targetPosition=1336.00006, (2)(4) + 355216 [2830913][E](PTable): cellValue: (123) wattDelta: (2.830187) cadDelta: (0.471698) allNeighborsPassed: (0) + 355217 [2830915][E](PTable): rightValue: (0.000000) leftValue: (118.194664) bottomValue: (118.759995) topValue: (0.000000) New averaged targetPosition: (118.477325) count: (2) + 355218 [2830936][E](PTable): Existing entry averaged (2)(4)(122), readings(11) + 355219 [2830962][E](Custom_C): 01 19 <-targetPosition + 355220 [2831029][E](Custom_C): 01 2b <-hMax + 355221 [2831626][E](Custom_C): 01 27 02 <-Power Tab Data + 355222 [2831633][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355223 [2831654][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355224 [2831686][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355225 [2831708][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 122 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355226 [2831740][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355227 [2831762][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355228 [2831795][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355229 [2831816][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355230 [2831849][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355231 [2831871][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355232 [2831916][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355233 [2831938][E](PTable): Power Table Reset + 355234 [2832172][E](PTable): Success! + 355235 [2832874][E](PTable): Success! + 355236 [2832896][E](Custom_C): 01 19 <-targetPosition + 355237 [2833575][E](PTable): Success! + 355238 [2833576][E](ERG_Mode): Proportional: -64.000000, Integral: 2.600000, Derivative: -1.200000 + 355239 [2833887][E](Custom_C): 01 19 <-targetPosition + 355240 [2834281][E](PTable): Success! + 355241 [2834282][E](PTable): Clean Power Table + 355242 [2834282][E](PTable): Averaged Entry: watts=137.199997, cad=69.400002, targetPosition=1333.99994, (2)(5) + 355243 [2834294][E](PTable): cellValue: (133) wattDelta: (75.001144) cadDelta: (12.500191) allNeighborsPassed: (1) + 355244 [2834305][E](PTable): rightValue: (132.829330) leftValue: (133.170670) bottomValue: (132.951996) topValue: (133.048004) New averaged targetPosition: (133.000000) count: (4) + 355245 [2834316][E](PTable): Existing entry averaged (2)(5)(133), readings(5) + 355246 [2834911][E](Custom_C): 01 19 <-targetPosition + 355247 [2834974][E](Custom_C): 01 27 02 <-Power Tab Data + 355248 [2834979][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355249 [2835001][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355250 [2835033][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355251 [2835055][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 122 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355252 [2835087][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355253 [2835109][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355254 [2835141][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355255 [2835162][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355256 [2835195][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355257 [2835217][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355258 [2835249][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355259 [2835270][E](PTable): Power Table Reset + 355260 [2835515][E](PTable): Success! + 355261 [2835912][E](Custom_C): 01 2a <-hMin + 355262 [2835956][E](Custom_C): 01 19 <-targetPosition + 355263 [2836002][E](Custom_C): 01 2b <-hMax + 355264 [2836217][E](PTable): Success! + 355265 [2836879][E](Custom_C): 01 19 <-targetPosition + 355266 [2836920][E](PTable): Success! + 355267 [2837622][E](PTable): Success! + 355268 [2837628][E](PTable): Clean Power Table + 355269 [2837628][E](PTable): Averaged Entry: watts=134.399994, cad=68.000000, targetPosition=1326.00006, (2)(4) + 355270 [2837641][E](PTable): cellValue: (122) wattDelta: (2.830187) cadDelta: (0.471698) allNeighborsPassed: (0) + 355271 [2837643][E](PTable): rightValue: (127.087997) leftValue: (116.912003) bottomValue: (117.759995) topValue: (0.000000) New averaged targetPosition: (120.586670) count: (3) + 355272 [2837664][E](PTable): Existing entry averaged (2)(4)(121), readings(11) + 355273 [2837892][E](Custom_C): 01 19 <-targetPosition + 355274 [2838360][E](Custom_C): 01 27 02 <-Power Tab Data + 355275 [2838366][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355276 [2838387][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355277 [2838420][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355278 [2838443][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 133 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355279 [2838476][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355280 [2838498][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355281 [2838529][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355282 [2838553][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355283 [2838575][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355284 [2838608][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355285 [2838629][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355286 [2838660][E](PTable): Power Table Reset + 355287 [2838661][E](ERG_Mode): Proportional: -8.000000, Integral: 0.600000, Derivative: 0.800000 + 355288 [2838883][E](Custom_C): 01 19 <-targetPosition + 355289 [2838933][E](PTable): Success! + 355290 [2839638][E](PTable): Success! + 355291 [2839894][E](Custom_C): 01 19 <-targetPosition + 355292 [2840343][E](PTable): Success! + 355293 [2840896][E](Custom_C): 01 27 00 <-Power Tab Data + 355294 [2840952][E](Custom_C): 01 2a <-hMin + 355295 [2840997][E](Custom_C): 01 19 <-targetPosition + 355296 [2841048][E](PTable): Success! + 355297 [2841051][E](PTable): Clean Power Table + 355298 [2841051][E](PTable): Averaged Entry: watts=142.399994, cad=69.599998, targetPosition=1318.00003, (2)(5) + 355299 [2841066][E](PTable): cellValue: (133) wattDelta: (25.000063) cadDelta: (4.166677) allNeighborsPassed: (1) + 355300 [2841109][E](PTable): rightValue: (130.296005) leftValue: (130.904007) bottomValue: (130.504013) topValue: (130.695999) New averaged targetPosition: (130.600006) count: (4) + 355301 [2841124][E](PTable): Existing entry averaged (2)(5)(132), readings(6) + 355302 [2841177][E](Custom_C): 01 2b <-hMax + 355303 [2841257][E](Custom_C): 01 27 02 <-Power Tab Data + 355304 [2841301][E](Custom_C): 01 27 03 <-Power Tab Data + 355305 [2841347][E](Custom_C): 01 27 04 <-Power Tab Data + 355306 [2841414][E](Custom_C): 01 27 05 <-Power Tab Data + 355307 [2841459][E](Custom_C): 01 27 06 <-Power Tab Data + 355308 [2841504][E](Custom_C): 01 27 07 <-Power Tab Data + 355309 [2841560][E](Custom_C): 01 27 08 <-Power Tab Data + 355310 [2841617][E](Custom_C): 01 27 09 <-Power Tab Data + 355311 [2841869][E](Custom_C): 01 27 02 <-Power Tab Data + 355312 [2841875][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355313 [2841897][E](Custom_C): 01 19 <-targetPosition + 355314 [2841910][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355315 [2841936][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355316 [2841959][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 132 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355317 [2841981][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355318 [2842013][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355319 [2842036][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355320 [2842068][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355321 [2842089][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355322 [2842121][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355323 [2842144][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355324 [2842175][E](PTable): Power Table Reset + 355325 [2842302][E](Custom_C): 01 25 <-Firmware Version + 355326 [2842516][E](PTable): Success! + 355327 [2842887][E](Custom_C): 01 19 <-targetPosition + 355328 [2843219][E](PTable): Success! + 355329 [2843899][E](Custom_C): 01 19 <-targetPosition + 355330 [2843924][E](PTable): Success! + 355331 [2844626][E](PTable): Success! + 355332 [2844627][E](PTable): Clean Power Table + 355333 [2844627][E](PTable): Averaged Entry: watts=136.399994, cad=71.400002, targetPosition=1306.00006, (2)(5) + 355334 [2844639][E](PTable): cellValue: (132) wattDelta: (21.428665) cadDelta: (3.571444) allNeighborsPassed: (1) + 355335 [2844651][E](PTable): rightValue: (128.565353) leftValue: (129.834671) bottomValue: (129.592010) topValue: (128.808014) New averaged targetPosition: (129.200012) count: (4) + 355336 [2844662][E](PTable): Existing entry averaged (2)(5)(131), readings(7) + 355337 [2844889][E](Custom_C): 01 19 <-targetPosition + 355338 [2845312][E](Custom_C): 01 27 02 <-Power Tab Data + 355339 [2845318][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355340 [2845340][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355341 [2845372][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355342 [2845394][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 131 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355343 [2845426][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355344 [2845448][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355345 [2845480][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355346 [2845501][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355347 [2845533][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355348 [2845555][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355349 [2845587][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355350 [2845608][E](PTable): Power Table Reset + 355351 [2845618][E](ERG_Mode): Proportional: 0.000000, Integral: -6.000000, Derivative: 1.200000 + 355352 [2845829][E](PTable): Success! + 355353 [2845892][E](Custom_C): 01 2a <-hMin + 355354 [2845947][E](Custom_C): 01 19 <-targetPosition + 355355 [2846014][E](Custom_C): 01 2b <-hMax + 355356 [2846059][E](Custom_C): 01 25 <-Firmware Version + 355357 [2846530][E](PTable): Success! + 355358 [2846914][E](Custom_C): 01 19 <-targetPosition + 355359 [2847234][E](PTable): Success! + 355360 [2847904][E](Custom_C): 01 19 <-targetPosition + 355361 [2847938][E](PTable): Success! + 355362 [2847939][E](PTable): Clean Power Table + 355363 [2847939][E](PTable): Averaged Entry: watts=136.000000, cad=71.199997, targetPosition=1298.00003, (2)(5) + 355364 [2847950][E](PTable): cellValue: (131) wattDelta: (25.000063) cadDelta: (4.166677) allNeighborsPassed: (1) + 355365 [2847961][E](PTable): rightValue: (128.040009) leftValue: (129.160004) bottomValue: (128.888000) topValue: (128.312012) New averaged targetPosition: (128.600006) count: (4) + 355366 [2847974][E](PTable): Existing entry averaged (2)(5)(130), readings(8) + 355367 [2848615][E](Custom_C): 01 27 02 <-Power Tab Data + 355368 [2848620][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355369 [2848643][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355370 [2848674][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355371 [2848696][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355372 [2848728][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355373 [2848750][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355374 [2848782][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355375 [2848804][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355376 [2848837][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355377 [2848859][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355378 [2848891][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355379 [2848913][E](PTable): Power Table Reset + 355380 [2848916][E](Custom_C): 01 19 <-targetPosition + 355381 [2849112][E](PTable): Success! + 355382 [2849815][E](PTable): Success! + 355383 [2849884][E](Custom_C): 01 19 <-targetPosition + 355384 [2850520][E](PTable): Success! + 355385 [2850897][E](Custom_C): 01 2a <-hMin + 355386 [2850964][E](Custom_C): 01 19 <-targetPosition + 355387 [2851032][E](Custom_C): 01 2b <-hMax + 355388 [2851223][E](PTable): Success! + 355389 [2851224][E](PTable): Clean Power Table + 355390 [2851224][E](PTable): Averaged Entry: watts=137.199997, cad=75.800003, targetPosition=1290.00000, (3)(5) + 355391 [2851235][E](PTable): cellValue: (125) wattDelta: (7.500000) cadDelta: (1.250000) allNeighborsPassed: (1) + 355392 [2851246][E](PTable): rightValue: (123.293335) leftValue: (126.706665) bottomValue: (125.639999) topValue: (124.360001) New averaged targetPosition: (125.000000) count: (4) + 355393 [2851258][E](PTable): Existing entry averaged (3)(5)(125), readings(11) + 355394 [2851887][E](Custom_C): 01 19 <-targetPosition + 355395 [2851913][E](Custom_C): 01 27 03 <-Power Tab Data + 355396 [2851918][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355397 [2851939][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355398 [2851973][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355399 [2851994][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355400 [2852026][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355401 [2852048][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355402 [2852081][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355403 [2852102][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355404 [2852134][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355405 [2852156][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355406 [2852188][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355407 [2852209][E](PTable): Power Table Reset + 355408 [2852220][E](ERG_Mode): Proportional: -96.000000, Integral: -8.400001, Derivative: -1.200000 + 355409 [2852437][E](PTable): Success! + 355410 [2852922][E](Custom_C): 01 19 <-targetPosition + 355411 [2853139][E](PTable): Success! + 355412 [2853840][E](PTable): Success! + 355413 [2853889][E](Custom_C): 01 19 <-targetPosition + 355414 [2854545][E](PTable): Success! + 355415 [2854546][E](PTable): Clean Power Table + 355416 [2854546][E](PTable): Averaged Entry: watts=139.600006, cad=76.000000, targetPosition=1286.00006, (3)(5) + 355417 [2854557][E](PTable): cellValue: (125) wattDelta: (8.333320) cadDelta: (1.388887) allNeighborsPassed: (1) + 355418 [2854568][E](PTable): rightValue: (123.751999) leftValue: (126.248001) bottomValue: (125.720001) topValue: (124.279999) New averaged targetPosition: (125.000000) count: (4) + 355419 [2854580][E](PTable): Existing entry averaged (3)(5)(125), readings(11) + 355420 [2854913][E](Custom_C): 01 19 <-targetPosition + 355421 [2855280][E](Custom_C): 01 27 03 <-Power Tab Data + 355422 [2855286][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355423 [2855307][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355424 [2855340][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355425 [2855362][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355426 [2855394][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355427 [2855416][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355428 [2855449][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355429 [2855470][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355430 [2855502][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355431 [2855524][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355432 [2855556][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355433 [2855577][E](PTable): Power Table Reset + 355434 [2855812][E](PTable): Success! + 355435 [2855905][E](Custom_C): 01 27 00 <-Power Tab Data + 355436 [2855937][E](Custom_C): 01 2a <-hMin + 355437 [2856027][E](Custom_C): 01 19 <-targetPosition + 355438 [2856084][E](Custom_C): 01 27 01 <-Power Tab Data + 355439 [2856116][E](Custom_C): 01 2b <-hMax + 355440 [2856196][E](Custom_C): 01 27 02 <-Power Tab Data + 355441 [2856241][E](Custom_C): 01 27 03 <-Power Tab Data + 355442 [2856286][E](Custom_C): 01 27 04 <-Power Tab Data + 355443 [2856331][E](Custom_C): 01 27 05 <-Power Tab Data + 355444 [2856378][E](Custom_C): 01 27 06 <-Power Tab Data + 355445 [2856422][E](Custom_C): 01 27 07 <-Power Tab Data + 355446 [2856466][E](Custom_C): 01 27 08 <-Power Tab Data + 355447 [2856511][E](Custom_C): 01 27 09 <-Power Tab Data + 355448 [2856515][E](PTable): Success! + 355449 [2856909][E](Custom_C): 01 19 <-targetPosition + 355450 [2857219][E](PTable): Success! + 355451 [2857894][E](Custom_C): 01 19 <-targetPosition + 355452 [2857921][E](PTable): Success! + 355453 [2857922][E](PTable): Clean Power Table + 355454 [2857922][E](PTable): Averaged Entry: watts=135.600006, cad=76.599998, targetPosition=1275.99998, (3)(5) + 355455 [2857933][E](PTable): cellValue: (125) wattDelta: (11.538468) cadDelta: (1.923078) allNeighborsPassed: (1) + 355456 [2857944][E](PTable): rightValue: (123.751999) leftValue: (126.248001) bottomValue: (125.832001) topValue: (124.167999) New averaged targetPosition: (125.000000) count: (4) + 355457 [2857955][E](PTable): Existing entry averaged (3)(5)(125), readings(11) + 355458 [2858616][E](Custom_C): 01 27 03 <-Power Tab Data + 355459 [2858625][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355460 [2858647][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355461 [2858680][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355462 [2858701][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355463 [2858733][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355464 [2858755][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355465 [2858787][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355466 [2858808][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355467 [2858841][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355468 [2858862][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355469 [2858909][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355470 [2858931][E](PTable): Power Table Reset + 355471 [2859169][E](PTable): Success! + 355472 [2859169][E](ERG_Mode): Proportional: 0.000000, Integral: -6.000000, Derivative: 0.000000 + 355473 [2859872][E](PTable): Success! + 355474 [2859897][E](Custom_C): 01 19 <-targetPosition + 355475 [2860573][E](PTable): Success! + 355476 [2860887][E](Custom_C): 01 2a <-hMin + 355477 [2860931][E](Custom_C): 01 19 <-targetPosition + 355478 [2861000][E](Custom_C): 01 2b <-hMax + 355479 [2861281][E](PTable): Success! + 355480 [2861282][E](PTable): Clean Power Table + 355481 [2861282][E](PTable): Averaged Entry: watts=128.800003, cad=74.400002, targetPosition=1271.99997, (3)(4) + 355482 [2861293][E](PTable): cellValue: (109) wattDelta: (1.648352) cadDelta: (0.274725) allNeighborsPassed: (0) + 355483 [2861305][E](PTable): rightValue: (0.000000) leftValue: (103.661331) bottomValue: (106.816010) topValue: (0.000000) New averaged targetPosition: (105.238670) count: (2) + 355484 [2861316][E](PTable): Bottom failed at: (105) Target pos: (105.238670) Avg pos: (105) + 355485 [2861327][E](PTable): Was not in range failed bottom (4)(4)(105), readings (11) + 355486 [2861327][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (105) + 355487 [2861338][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 355488 [2861338][E](PTable): PT failed (4)(4)(105), readings (11) + 355489 [2861350][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355490 [2861372][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355491 [2861404][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355492 [2861425][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355493 [2861458][E](PTable): 75 rpm | 48 | 64 | | | 109 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355494 [2861479][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355495 [2861513][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 355496 [2861536][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 355497 [2861567][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355498 [2861589][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 355499 [2861621][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355500 [2861643][E](PTable): Power Table Reset + 355501 [2861922][E](Custom_C): 01 19 <-targetPosition + 355502 [2861985][E](PTable): Success! + 355503 [2862282][E](Custom_C): 01 25 <-Firmware Version + 355504 [2862687][E](PTable): Success! + 355505 [2862889][E](Custom_C): 01 19 <-targetPosition + 355506 [2863389][E](PTable): Success! + 355507 [2863902][E](Custom_C): 01 19 <-targetPosition + 355508 [2864090][E](PTable): Success! + 355509 [2864091][E](PTable): Clean Power Table + 355510 [2864091][E](PTable): Averaged Entry: watts=136.000000, cad=73.400002, targetPosition=1270.00000, (3)(5) + 355511 [2864103][E](PTable): cellValue: (125) wattDelta: (15.000000) cadDelta: (2.500000) allNeighborsPassed: (1) + 355512 [2864114][E](PTable): rightValue: (124.066666) leftValue: (125.933334) bottomValue: (124.360001) topValue: (125.639999) New averaged targetPosition: (125.000000) count: (4) + 355513 [2864125][E](PTable): Existing entry averaged (3)(5)(125), readings(11) + 355514 [2864823][E](Custom_C): 01 27 03 <-Power Tab Data + 355515 [2864828][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355516 [2864850][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355517 [2864886][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355518 [2864928][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355519 [2864950][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355520 [2864973][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355521 [2865005][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355522 [2865027][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355523 [2865059][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355524 [2865081][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355525 [2865113][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355526 [2865134][E](PTable): Power Table Reset + 355527 [2865145][E](ERG_Mode): Proportional: -104.000000, Integral: -8.400001, Derivative: -2.600000 + 355528 [2865357][E](PTable): Success! + 355529 [2865882][E](Custom_C): 01 2a <-hMin + 355530 [2865927][E](Custom_C): 01 19 <-targetPosition + 355531 [2865971][E](Custom_C): 01 2b <-hMax + 355532 [2866040][E](Custom_C): 01 25 <-Firmware Version + 355533 [2866058][E](PTable): Success! + 355534 [2866763][E](PTable): Success! + 355535 [2866894][E](Custom_C): 01 19 <-targetPosition + 355536 [2867469][E](PTable): Success! + 355537 [2867470][E](PTable): Clean Power Table + 355538 [2867470][E](PTable): Averaged Entry: watts=127.199997, cad=73.800003, targetPosition=1274.00002, (3)(4) + 355539 [2867482][E](PTable): cellValue: (109) wattDelta: (1.630435) cadDelta: (0.271739) allNeighborsPassed: (0) + 355540 [2867493][E](PTable): rightValue: (0.000000) leftValue: (104.584000) bottomValue: (104.584007) topValue: (0.000000) New averaged targetPosition: (104.584000) count: (2) + 355541 [2867504][E](PTable): Bottom failed at: (105) Target pos: (104.584000) Avg pos: (104) + 355542 [2867515][E](PTable): All test failed bottom (2)(4)(121), readings (11) + 355543 [2867515][E](PTable): WEIGHTED DOWNVOTING: Target Value: (104), NeighborValue: (105) + 355544 [2867526][E](PTable): WEIGHTED DOWNVOTING: Delta: (1), Penalty: (0) + 355545 [2867526][E](PTable): PT failed (4)(4)(105), readings (11) + 355546 [2867538][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355547 [2867560][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355548 [2867594][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355549 [2867616][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355550 [2867648][E](PTable): 75 rpm | 48 | 64 | | | 109 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355551 [2867670][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355552 [2867701][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 355553 [2867723][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 355554 [2867755][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355555 [2867777][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 355556 [2867809][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355557 [2867829][E](PTable): Power Table Reset + 355558 [2867885][E](Custom_C): 01 19 <-targetPosition + 355559 [2868171][E](PTable): Success! + 355560 [2868172][E](PTable): Using detected travel limits during homing + 355561 [2868873][E](PTable): Success! + 355562 [2868896][E](Custom_C): 01 19 <-targetPosition + 355563 [2869577][E](PTable): Success! + 355564 [2869909][E](Custom_C): 01 19 <-targetPosition + 355565 [2870280][E](PTable): Success! + 355566 [2870281][E](PTable): Clean Power Table + 355567 [2870281][E](PTable): Averaged Entry: watts=130.800003, cad=74.599998, targetPosition=1270.00000, (3)(4) + 355568 [2870292][E](PTable): cellValue: (109) wattDelta: (1.666667) cadDelta: (0.277778) allNeighborsPassed: (0) + 355569 [2870304][E](PTable): rightValue: (0.000000) leftValue: (102.519997) bottomValue: (107.559998) topValue: (0.000000) New averaged targetPosition: (105.039993) count: (2) + 355570 [2870315][E](PTable): Bottom failed at: (105) Target pos: (105.039993) Avg pos: (105) + 355571 [2870326][E](PTable): Was not in range failed bottom (4)(4)(105), readings (11) + 355572 [2870326][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (105) + 355573 [2870337][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 355574 [2870347][E](PTable): PT failed (4)(4)(105), readings (11) + 355575 [2870349][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355576 [2870371][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355577 [2870403][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355578 [2870425][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355579 [2870457][E](PTable): 75 rpm | 48 | 64 | | | 109 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355580 [2870478][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355581 [2870512][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 355582 [2870534][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 355583 [2870566][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355584 [2870588][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 355585 [2870620][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355586 [2870641][E](PTable): Power Table Reset + 355587 [2870651][E](ERG_Mode): Proportional: -8.000000, Integral: -5.800000, Derivative: -0.600000 + 355588 [2870914][E](Custom_C): 01 27 00 <-Power Tab Data + 355589 [2870967][E](Custom_C): 01 2a <-hMin + 355590 [2870981][E](PTable): Success! + 355591 [2871034][E](Custom_C): 01 19 <-targetPosition + 355592 [2871116][E](Custom_C): 01 27 01 <-Power Tab Data + 355593 [2871192][E](Custom_C): 01 2b <-hMax + 355594 [2871271][E](Custom_C): 01 27 02 <-Power Tab Data + 355595 [2871316][E](Custom_C): 01 27 03 <-Power Tab Data + 355596 [2871361][E](Custom_C): 01 27 04 <-Power Tab Data + 355597 [2871406][E](Custom_C): 01 27 05 <-Power Tab Data + 355598 [2871452][E](Custom_C): 01 27 06 <-Power Tab Data + 355599 [2871496][E](Custom_C): 01 27 07 <-Power Tab Data + 355600 [2871541][E](Custom_C): 01 27 08 <-Power Tab Data + 355601 [2871586][E](Custom_C): 01 27 09 <-Power Tab Data + 355602 [2871685][E](PTable): Success! + 355603 [2871889][E](Custom_C): 01 19 <-targetPosition + 355604 [2872390][E](PTable): Success! + 355605 [2872879][E](Custom_C): 01 19 <-targetPosition + 355606 [2873094][E](PTable): Success! + 355607 [2873095][E](PTable): Clean Power Table + 355608 [2873095][E](PTable): Averaged Entry: watts=128.800003, cad=74.599998, targetPosition=1270.00000, (3)(4) + 355609 [2873108][E](PTable): cellValue: (109) wattDelta: (1.666667) cadDelta: (0.277778) allNeighborsPassed: (0) + 355610 [2873109][E](PTable): rightValue: (0.000000) leftValue: (103.720001) bottomValue: (107.559998) topValue: (0.000000) New averaged targetPosition: (105.639999) count: (2) + 355611 [2873130][E](PTable): Bottom failed at: (105) Target pos: (105.639999) Avg pos: (105) + 355612 [2873141][E](PTable): Was not in range failed bottom (4)(4)(105), readings (11) + 355613 [2873141][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (105) + 355614 [2873151][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 355615 [2873152][E](PTable): PT failed (4)(4)(105), readings (11) + 355616 [2873166][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355617 [2873187][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355618 [2873220][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355619 [2873242][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355620 [2873275][E](PTable): 75 rpm | 48 | 64 | | | 109 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355621 [2873297][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355622 [2873328][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 355623 [2873350][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 355624 [2873382][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355625 [2873404][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 355626 [2873436][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355627 [2873456][E](PTable): Power Table Reset + 355628 [2873798][E](PTable): Success! + 355629 [2873914][E](Custom_C): 01 19 <-targetPosition + 355630 [2874500][E](PTable): Success! + 355631 [2874882][E](Custom_C): 01 19 <-targetPosition + 355632 [2875202][E](PTable): Success! + 355633 [2875894][E](Custom_C): 01 2a <-hMin + 355634 [2875907][E](PTable): Success! + 355635 [2875908][E](PTable): Clean Power Table + 355636 [2875908][E](PTable): Averaged Entry: watts=122.800003, cad=73.199997, targetPosition=1270.00000, (3)(4) + 355637 [2875919][E](PTable): cellValue: (109) wattDelta: (1.666667) cadDelta: (0.277778) allNeighborsPassed: (0) + 355638 [2875921][E](PTable): rightValue: (0.000000) leftValue: (107.320000) bottomValue: (102.519989) topValue: (0.000000) New averaged targetPosition: (104.919998) count: (2) + 355639 [2875943][E](Custom_C): 01 19 <-targetPosition + 355640 [2875946][E](PTable): Bottom failed at: (105) Target pos: (104.919998) Avg pos: (104) + 355641 [2875957][E](PTable): All test failed bottom (2)(4)(121), readings (11) + 355642 [2875957][E](PTable): WEIGHTED DOWNVOTING: Target Value: (104), NeighborValue: (105) + 355643 [2875968][E](PTable): WEIGHTED DOWNVOTING: Delta: (1), Penalty: (0) + 355644 [2875968][E](PTable): PT failed (4)(4)(105), readings (11) + 355645 [2875980][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355646 [2876016][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355647 [2876048][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355648 [2876070][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355649 [2876102][E](PTable): 75 rpm | 48 | 64 | | | 109 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355650 [2876123][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355651 [2876155][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 355652 [2876178][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 355653 [2876209][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355654 [2876231][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 355655 [2876264][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355656 [2876285][E](PTable): Power Table Reset + 355657 [2876285][E](ERG_Mode): Proportional: 48.000000, Integral: -3.200000, Derivative: 0.400000 + 355658 [2876608][E](PTable): Success! + 355659 [2876884][E](Custom_C): 01 19 <-targetPosition + 355660 [2877312][E](PTable): Success! + 355661 [2877897][E](Custom_C): 01 19 <-targetPosition + 355662 [2878016][E](PTable): Success! + 355663 [2878717][E](PTable): Success! + 355664 [2878718][E](PTable): Clean Power Table + 355665 [2878718][E](PTable): Averaged Entry: watts=122.000000, cad=71.199997, targetPosition=1275.99998, (2)(4) + 355666 [2878729][E](PTable): cellValue: (121) wattDelta: (4.545455) cadDelta: (0.757576) allNeighborsPassed: (1) + 355667 [2878740][E](PTable): rightValue: (121.440002) leftValue: (120.559998) bottomValue: (122.584000) topValue: (119.416000) New averaged targetPosition: (121.000000) count: (4) + 355668 [2878751][E](PTable): Existing entry averaged (2)(4)(121), readings(11) + 355669 [2878887][E](Custom_C): 01 19 <-targetPosition + 355670 [2879432][E](Custom_C): 01 27 02 <-Power Tab Data + 355671 [2879438][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355672 [2879460][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355673 [2879492][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355674 [2879515][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355675 [2879547][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355676 [2879568][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355677 [2879600][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355678 [2879622][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355679 [2879654][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355680 [2879676][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355681 [2879708][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355682 [2879729][E](PTable): Power Table Reset + 355683 [2879900][E](Custom_C): 01 19 <-targetPosition + 355684 [2879963][E](PTable): Success! + 355685 [2880664][E](PTable): Success! + 355686 [2880889][E](Custom_C): 01 2a <-hMin + 355687 [2880934][E](Custom_C): 01 19 <-targetPosition + 355688 [2881013][E](Custom_C): 01 2b <-hMax + 355689 [2881367][E](PTable): Success! + 355690 [2881368][E](ERG_Mode): Proportional: -40.000000, Integral: -2.600000, Derivative: -0.400000 + 355691 [2881902][E](Custom_C): 01 19 <-targetPosition + 355692 [2882069][E](PTable): Success! + 355693 [2882070][E](PTable): Clean Power Table + 355694 [2882070][E](PTable): Averaged Entry: watts=137.199997, cad=73.599998, targetPosition=1278.00003, (3)(5) + 355695 [2882077][E](PTable): cellValue: (125) wattDelta: (10.714274) cadDelta: (1.785712) allNeighborsPassed: (1) + 355696 [2882088][E](PTable): rightValue: (123.805328) leftValue: (126.194672) bottomValue: (124.215996) topValue: (125.784004) New averaged targetPosition: (125.000000) count: (4) + 355697 [2882100][E](PTable): Existing entry averaged (3)(5)(125), readings(11) + 355698 [2882262][E](Custom_C): 01 25 <-Firmware Version + 355699 [2882787][E](Custom_C): 01 27 03 <-Power Tab Data + 355700 [2882795][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355701 [2882817][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355702 [2882850][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355703 [2882871][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355704 [2882904][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355705 [2882939][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355706 [2882961][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355707 [2882995][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355708 [2883017][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355709 [2883049][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355710 [2883070][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355711 [2883101][E](PTable): Power Table Reset + 355712 [2883337][E](PTable): Success! + 355713 [2883881][E](Custom_C): 01 19 <-targetPosition + 355714 [2884040][E](PTable): Success! + 355715 [2884742][E](PTable): Success! + 355716 [2884894][E](Custom_C): 01 19 <-targetPosition + 355717 [2885446][E](PTable): Success! + 355718 [2885447][E](PTable): Clean Power Table + 355719 [2885447][E](PTable): Averaged Entry: watts=130.800003, cad=74.599998, targetPosition=1270.00000, (3)(4) + 355720 [2885459][E](PTable): cellValue: (109) wattDelta: (1.666667) cadDelta: (0.277778) allNeighborsPassed: (0) + 355721 [2885461][E](PTable): rightValue: (0.000000) leftValue: (102.519997) bottomValue: (107.559998) topValue: (0.000000) New averaged targetPosition: (105.039993) count: (2) + 355722 [2885482][E](PTable): Bottom failed at: (105) Target pos: (105.039993) Avg pos: (105) + 355723 [2885483][E](PTable): Was not in range failed bottom (4)(4)(105), readings (11) + 355724 [2885494][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (105) + 355725 [2885504][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 355726 [2885504][E](PTable): PT failed (4)(4)(105), readings (11) + 355727 [2885516][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355728 [2885538][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355729 [2885570][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355730 [2885592][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355731 [2885624][E](PTable): 75 rpm | 48 | 64 | | | 109 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355732 [2885646][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355733 [2885678][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 355734 [2885700][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 355735 [2885732][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355736 [2885753][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 355737 [2885785][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355738 [2885806][E](PTable): Power Table Reset + 355739 [2885897][E](Custom_C): 01 27 00 <-Power Tab Data + 355740 [2885929][E](Custom_C): 01 2a <-hMin + 355741 [2885974][E](Custom_C): 01 19 <-targetPosition + 355742 [2886031][E](Custom_C): 01 27 01 <-Power Tab Data + 355743 [2886087][E](Custom_C): 01 2b <-hMax + 355744 [2886144][E](Custom_C): 01 27 02 <-Power Tab Data + 355745 [2886147][E](PTable): Success! + 355746 [2886189][E](Custom_C): 01 27 03 <-Power Tab Data + 355747 [2886234][E](Custom_C): 01 27 04 <-Power Tab Data + 355748 [2886301][E](Custom_C): 01 27 05 <-Power Tab Data + 355749 [2886346][E](Custom_C): 01 27 06 <-Power Tab Data + 355750 [2886394][E](Custom_C): 01 27 07 <-Power Tab Data + 355751 [2886460][E](Custom_C): 01 27 08 <-Power Tab Data + 355752 [2886534][E](Custom_C): 01 27 09 <-Power Tab Data + 355753 [2886608][E](Custom_C): 01 25 <-Firmware Version + 355754 [2886849][E](PTable): Success! + 355755 [2886919][E](Custom_C): 01 19 <-targetPosition + 355756 [2887552][E](PTable): Success! + 355757 [2887553][E](ERG_Mode): Proportional: -16.000000, Integral: -3.400000, Derivative: -0.400000 + 355758 [2887887][E](Custom_C): 01 19 <-targetPosition + 355759 [2888256][E](PTable): Success! + 355760 [2888259][E](PTable): Clean Power Table + 355761 [2888259][E](PTable): Averaged Entry: watts=131.600006, cad=74.000000, targetPosition=1270.00000, (3)(4) + 355762 [2888271][E](PTable): cellValue: (109) wattDelta: (1.666667) cadDelta: (0.277778) allNeighborsPassed: (0) + 355763 [2888282][E](PTable): rightValue: (0.000000) leftValue: (102.039993) bottomValue: (105.400002) topValue: (0.000000) New averaged targetPosition: (103.720001) count: (2) + 355764 [2888293][E](PTable): Bottom failed at: (105) Target pos: (103.720001) Avg pos: (104) + 355765 [2888304][E](PTable): All test failed bottom (2)(4)(121), readings (11) + 355766 [2888304][E](PTable): WEIGHTED DOWNVOTING: Target Value: (103), NeighborValue: (105) + 355767 [2888315][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 355768 [2888315][E](PTable): PT failed (4)(4)(105), readings (11) + 355769 [2888327][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355770 [2888349][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355771 [2888381][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355772 [2888402][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355773 [2888435][E](PTable): 75 rpm | 48 | 64 | | | 109 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355774 [2888457][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355775 [2888489][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 355776 [2888511][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 355777 [2888544][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355778 [2888566][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 355779 [2888597][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355780 [2888618][E](PTable): Power Table Reset + 355781 [2888899][E](Custom_C): 01 19 <-targetPosition + 355782 [2889110][E](PTable): Success! + 355783 [2889813][E](PTable): Success! + 355784 [2889889][E](Custom_C): 01 19 <-targetPosition + 355785 [2890517][E](PTable): Success! + 355786 [2890901][E](Custom_C): 01 2a <-hMin + 355787 [2890946][E](Custom_C): 01 19 <-targetPosition + 355788 [2890992][E](Custom_C): 01 2b <-hMax + 355789 [2891218][E](PTable): Success! + 355790 [2891221][E](PTable): Clean Power Table + 355791 [2891221][E](PTable): Averaged Entry: watts=137.600006, cad=75.000000, targetPosition=1265.99998, (3)(5) + 355792 [2891232][E](PTable): cellValue: (125) wattDelta: (18.750017) cadDelta: (3.125003) allNeighborsPassed: (1) + 355793 [2891244][E](PTable): rightValue: (124.338669) leftValue: (125.661331) bottomValue: (125.000000) topValue: (125.000000) New averaged targetPosition: (125.000000) count: (4) + 355794 [2891255][E](PTable): Existing entry averaged (3)(5)(125), readings(11) + 355795 [2891891][E](Custom_C): 01 19 <-targetPosition + 355796 [2891922][E](Custom_C): 01 27 03 <-Power Tab Data + 355797 [2891927][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355798 [2891948][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355799 [2891980][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355800 [2892003][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355801 [2892035][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355802 [2892057][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355803 [2892089][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355804 [2892111][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355805 [2892143][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355806 [2892165][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355807 [2892197][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355808 [2892218][E](PTable): Power Table Reset + 355809 [2892483][E](PTable): Success! + 355810 [2892882][E](Custom_C): 01 19 <-targetPosition + 355811 [2893184][E](PTable): Success! + 355812 [2893185][E](ERG_Mode): Proportional: 0.000000, Integral: -5.800000, Derivative: -0.200000 + 355813 [2893890][E](PTable): Success! + 355814 [2893894][E](Custom_C): 01 19 <-targetPosition + 355815 [2894594][E](PTable): Success! + 355816 [2894595][E](PTable): Clean Power Table + 355817 [2894595][E](PTable): Averaged Entry: watts=128.800003, cad=74.000000, targetPosition=1260.00000, (3)(4) + 355818 [2894607][E](PTable): cellValue: (109) wattDelta: (1.764706) cadDelta: (0.294118) allNeighborsPassed: (0) + 355819 [2894618][E](PTable): rightValue: (0.000000) leftValue: (104.013336) bottomValue: (105.599998) topValue: (0.000000) New averaged targetPosition: (104.806671) count: (2) + 355820 [2894629][E](PTable): Bottom failed at: (105) Target pos: (104.806671) Avg pos: (104) + 355821 [2894640][E](PTable): All test failed bottom (2)(4)(121), readings (11) + 355822 [2894640][E](PTable): WEIGHTED DOWNVOTING: Target Value: (104), NeighborValue: (105) + 355823 [2894650][E](PTable): WEIGHTED DOWNVOTING: Delta: (1), Penalty: (0) + 355824 [2894651][E](PTable): PT failed (4)(4)(105), readings (11) + 355825 [2894664][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355826 [2894685][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355827 [2894718][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355828 [2894740][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355829 [2894772][E](PTable): 75 rpm | 48 | 64 | | | 109 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355830 [2894794][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355831 [2894826][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 355832 [2894847][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 355833 [2894880][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355834 [2894902][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 355835 [2894948][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355836 [2894969][E](PTable): Power Table Reset + 355837 [2895297][E](PTable): Success! + 355838 [2895942][E](Custom_C): 01 2a <-hMin + 355839 [2895986][E](Custom_C): 01 19 <-targetPosition + 355840 [2896000][E](PTable): Success! + 355841 [2896065][E](Custom_C): 01 2b <-hMax + 355842 [2896703][E](PTable): Success! + 355843 [2896887][E](Custom_C): 01 19 <-targetPosition + 355844 [2897406][E](PTable): Success! + 355845 [2897407][E](PTable): Clean Power Table + 355846 [2897407][E](PTable): Averaged Entry: watts=138.000000, cad=75.599998, targetPosition=1258.00003, (3)(5) + 355847 [2897419][E](PTable): cellValue: (125) wattDelta: (37.499859) cadDelta: (6.249976) allNeighborsPassed: (1) + 355848 [2897430][E](PTable): rightValue: (124.680000) leftValue: (125.320000) bottomValue: (125.096001) topValue: (124.903999) New averaged targetPosition: (125.000000) count: (4) + 355849 [2897443][E](PTable): Existing entry averaged (3)(5)(125), readings(11) + 355850 [2897898][E](Custom_C): 01 19 <-targetPosition + 355851 [2898121][E](Custom_C): 01 27 03 <-Power Tab Data + 355852 [2898127][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355853 [2898151][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355854 [2898183][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355855 [2898205][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355856 [2898237][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 109 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355857 [2898259][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355858 [2898291][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355859 [2898313][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355860 [2898345][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355861 [2898368][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355862 [2898400][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355863 [2898421][E](PTable): Power Table Reset + 355864 [2898421][E](ERG_Mode): Proportional: -32.000000, Integral: -6.800000, Derivative: -0.600000 + 355865 [2898648][E](PTable): Success! + 355866 [2898889][E](Custom_C): 01 19 <-targetPosition + 355867 [2899350][E](PTable): Success! + 355868 [2899879][E](Custom_C): 01 19 <-targetPosition + 355869 [2900052][E](PTable): Success! + 355870 [2900756][E](PTable): Success! + 355871 [2900757][E](PTable): Clean Power Table + 355872 [2900757][E](PTable): Averaged Entry: watts=123.199997, cad=74.599998, targetPosition=1255.99998, (3)(4) + 355873 [2900768][E](PTable): cellValue: (109) wattDelta: (1.807229) cadDelta: (0.301205) allNeighborsPassed: (0) + 355874 [2900779][E](PTable): rightValue: (0.000000) leftValue: (107.229332) bottomValue: (107.671997) topValue: (0.000000) New averaged targetPosition: (107.450668) count: (2) + 355875 [2900790][E](PTable): Existing entry averaged (3)(4)(108), readings(11) + 355876 [2900904][E](Custom_C): 01 27 00 <-Power Tab Data + 355877 [2900960][E](Custom_C): 01 2a <-hMin + 355878 [2901003][E](Custom_C): 01 19 <-targetPosition + 355879 [2901062][E](Custom_C): 01 27 01 <-Power Tab Data + 355880 [2901093][E](Custom_C): 01 2b <-hMax + 355881 [2901174][E](Custom_C): 01 27 02 <-Power Tab Data + 355882 [2901222][E](Custom_C): 01 27 03 <-Power Tab Data + 355883 [2901266][E](Custom_C): 01 27 04 <-Power Tab Data + 355884 [2901308][E](Custom_C): 01 27 05 <-Power Tab Data + 355885 [2901377][E](Custom_C): 01 27 06 <-Power Tab Data + 355886 [2901421][E](Custom_C): 01 27 07 <-Power Tab Data + 355887 [2901489][E](Custom_C): 01 27 08 <-Power Tab Data + 355888 [2901535][E](Custom_C): 01 27 09 <-Power Tab Data + 355889 [2901591][E](Custom_C): 01 27 03 <-Power Tab Data + 355890 [2901596][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355891 [2901618][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355892 [2901650][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355893 [2901672][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355894 [2901704][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 108 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355895 [2901726][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355896 [2901758][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355897 [2901780][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355898 [2901812][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355899 [2901836][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355900 [2901869][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355901 [2901889][E](Custom_C): 01 19 <-targetPosition + 355902 [2901893][E](PTable): Power Table Reset + 355903 [2902250][E](PTable): Success! + 355904 [2902268][E](Custom_C): 01 25 <-Firmware Version + 355905 [2902894][E](Custom_C): 01 19 <-targetPosition + 355906 [2902953][E](PTable): Success! + 355907 [2903655][E](PTable): Success! + 355908 [2903656][E](ERG_Mode): Proportional: 24.000000, Integral: -5.400000, Derivative: 4.400000 + 355909 [2903907][E](Custom_C): 01 19 <-targetPosition + 355910 [2904357][E](PTable): Success! + 355911 [2904358][E](PTable): Clean Power Table + 355912 [2904358][E](PTable): Averaged Entry: watts=151.600006, cad=76.199997, targetPosition=1250.00000, (3)(5) + 355913 [2904371][E](PTable): Keep old targetPosition: (125.000000) + 355914 [2904372][E](PTable): Existing entry averaged (3)(5)(125), readings(11) + 355915 [2904896][E](Custom_C): 01 19 <-targetPosition + 355916 [2905072][E](Custom_C): 01 27 03 <-Power Tab Data + 355917 [2905077][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355918 [2905099][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355919 [2905131][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355920 [2905154][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355921 [2905186][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 108 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355922 [2905210][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355923 [2905242][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355924 [2905268][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355925 [2905289][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355926 [2905322][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355927 [2905344][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355928 [2905375][E](PTable): Power Table Reset + 355929 [2905580][E](PTable): Success! + 355930 [2905898][E](Custom_C): 01 2a <-hMin + 355931 [2905954][E](Custom_C): 01 19 <-targetPosition + 355932 [2906022][E](Custom_C): 01 2b <-hMax + 355933 [2906089][E](Custom_C): 01 25 <-Firmware Version + 355934 [2906283][E](PTable): Success! + 355935 [2906898][E](Custom_C): 01 19 <-targetPosition + 355936 [2906985][E](PTable): Success! + 355937 [2907690][E](PTable): Success! + 355938 [2907691][E](PTable): Clean Power Table + 355939 [2907691][E](PTable): Averaged Entry: watts=129.600006, cad=74.400002, targetPosition=1244.00002, (3)(4) + 355940 [2907703][E](PTable): cellValue: (108) wattDelta: (1.829268) cadDelta: (0.304878) allNeighborsPassed: (0) + 355941 [2907714][E](PTable): rightValue: (113.248001) leftValue: (102.751999) bottomValue: (106.032005) topValue: (0.000000) New averaged targetPosition: (107.344002) count: (3) + 355942 [2907725][E](PTable): Existing entry averaged (3)(4)(107), readings(11) + 355943 [2907889][E](Custom_C): 01 19 <-targetPosition + 355944 [2908411][E](Custom_C): 01 27 03 <-Power Tab Data + 355945 [2908416][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355946 [2908439][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 355947 [2908471][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 355948 [2908493][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 355949 [2908525][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 107 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 355950 [2908547][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 355951 [2908578][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 355952 [2908600][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 355953 [2908633][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 355954 [2908654][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 355955 [2908686][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 355956 [2908708][E](PTable): Power Table Reset + 355957 [2908719][E](ERG_Mode): Proportional: 8.000000, Integral: -5.200000, Derivative: 0.000000 + 355958 [2908720][E](PTable): Using detected travel limits during homing + 355959 [2908880][E](Custom_C): 01 19 <-targetPosition + 355960 [2909060][E](PTable): Success! + 355961 [2909762][E](PTable): Success! + 355962 [2909891][E](Custom_C): 01 19 <-targetPosition + 355963 [2910463][E](PTable): Success! + 355964 [2910882][E](Custom_C): 01 2a <-hMin + 355965 [2910926][E](Custom_C): 01 19 <-targetPosition + 355966 [2910995][E](Custom_C): 01 2b <-hMax + 355967 [2911167][E](PTable): Success! + 355968 [2911169][E](PTable): Clean Power Table + 355969 [2911169][E](PTable): Averaged Entry: watts=131.199997, cad=73.599998, targetPosition=1240.00000, (3)(4) + 355970 [2911180][E](PTable): cellValue: (107) wattDelta: (1.764706) cadDelta: (0.294118) allNeighborsPassed: (0) + 355971 [2911192][E](PTable): rightValue: (113.346664) leftValue: (100.653336) bottomValue: (102.239998) topValue: (0.000000) New averaged targetPosition: (105.413330) count: (3) + 355972 [2911206][E](PTable): Bottom failed at: (105) Target pos: (105.413330) Avg pos: (105) + 355973 [2911207][E](PTable): Was not in range failed bottom (4)(4)(105), readings (11) + 355974 [2911217][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (105) + 355975 [2911228][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 355976 [2911228][E](PTable): PT failed (4)(4)(105), readings (11) + 355977 [2911241][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 355978 [2911263][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355979 [2911297][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355980 [2911320][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355981 [2911352][E](PTable): 75 rpm | 48 | 64 | | | 107 | 125 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355982 [2911375][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355983 [2911396][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 355984 [2911428][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 355985 [2911463][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 355986 [2911485][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 355987 [2911517][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 355988 [2911538][E](PTable): Power Table Reset + 355989 [2911868][E](PTable): Success! + 355990 [2911894][E](Custom_C): 01 19 <-targetPosition + 355991 [2912570][E](PTable): Success! + 355992 [2912885][E](Custom_C): 01 19 <-targetPosition + 355993 [2913273][E](PTable): Success! + 355994 [2913896][E](Custom_C): 01 19 <-targetPosition + 355995 [2913978][E](PTable): Success! + 355996 [2913979][E](PTable): Clean Power Table + 355997 [2913979][E](PTable): Averaged Entry: watts=132.399994, cad=74.800003, targetPosition=1240.00000, (3)(4) + 355998 [2913991][E](PTable): cellValue: (107) wattDelta: (1.764706) cadDelta: (0.294118) allNeighborsPassed: (0) + 355999 [2914001][E](PTable): rightValue: (114.026665) leftValue: (99.973335) bottomValue: (106.320007) topValue: (0.000000) New averaged targetPosition: (106.773338) count: (3) + 356000 [2914014][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 356001 [2914682][E](Custom_C): 01 27 03 <-Power Tab Data + 356002 [2914688][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356003 [2914710][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 356004 [2914742][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 356005 [2914764][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 356006 [2914796][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 125 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 356007 [2914818][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 356008 [2914853][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 356009 [2914875][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 356010 [2914924][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 356011 [2914947][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 356012 [2914969][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 356013 [2915000][E](PTable): Power Table Reset + 356014 [2915000][E](ERG_Mode): Proportional: 0.000000, Integral: -6.000000, Derivative: 0.000000 + 356015 [2915226][E](PTable): Success! + 356016 [2915900][E](Custom_C): 01 27 00 <-Power Tab Data + 356017 [2915930][E](PTable): Success! + 356018 [2915944][E](Custom_C): 01 2a <-hMin + 356019 [2916012][E](Custom_C): 01 19 <-targetPosition + 356020 [2916092][E](Custom_C): 01 27 01 <-Power Tab Data + 356021 [2916123][E](Custom_C): 01 2b <-hMax + 356022 [2916204][E](Custom_C): 01 27 02 <-Power Tab Data + 356023 [2916250][E](Custom_C): 01 27 03 <-Power Tab Data + 356024 [2916318][E](Custom_C): 01 27 04 <-Power Tab Data + 356025 [2916361][E](Custom_C): 01 27 05 <-Power Tab Data + 356026 [2916452][E](Custom_C): 01 27 06 <-Power Tab Data + 356027 [2916520][E](Custom_C): 01 27 07 <-Power Tab Data + 356028 [2916563][E](Custom_C): 01 27 08 <-Power Tab Data + 356029 [2916609][E](Custom_C): 01 27 09 <-Power Tab Data + 356030 [2916633][E](PTable): Success! + 356031 [2916912][E](Custom_C): 01 19 <-targetPosition + 356032 [2917390][E](PTable): Success! + 356033 [2917391][E](PTable): Clean Power Table + 356034 [2917396][E](PTable): Averaged Entry: watts=142.800003, cad=77.400002, targetPosition=1234.00002, (3)(5) + 356035 [2917398][E](PTable): cellValue: (125) wattDelta: (18.750017) cadDelta: (3.125003) allNeighborsPassed: (1) + 356036 [2917412][E](PTable): rightValue: (121.416000) leftValue: (122.184006) bottomValue: (122.568001) topValue: (121.032005) New averaged targetPosition: (121.800003) count: (4) + 356037 [2917423][E](PTable): Existing entry averaged (3)(5)(124), readings(11) + 356038 [2917879][E](Custom_C): 01 19 <-targetPosition + 356039 [2918153][E](Custom_C): 01 27 03 <-Power Tab Data + 356040 [2918159][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356041 [2918181][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 356042 [2918213][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 356043 [2918235][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 356044 [2918267][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 356045 [2918289][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 356046 [2918323][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 356047 [2918345][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 356048 [2918377][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 356049 [2918400][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 356050 [2918432][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 356051 [2918503][E](PTable): Writing File: /PowerTable.txt + 356052 [2918859][E](PTable): Power table saved successfully with 94 readings + 356053 [2918860][E](PTable): Power Table Reset + 356054 [2918892][E](Custom_C): 01 19 <-targetPosition + 356055 [2919115][E](PTable): Success! + 356056 [2919820][E](PTable): Success! + 356057 [2919882][E](Custom_C): 01 19 <-targetPosition + 356058 [2920524][E](PTable): Success! + 356059 [2920525][E](ERG_Mode): Proportional: -8.000000, Integral: -6.200000, Derivative: 0.000000 + 356060 [2920893][E](Custom_C): 01 2a <-hMin + 356061 [2920938][E](Custom_C): 01 19 <-targetPosition + 356062 [2921007][E](Custom_C): 01 2b <-hMax + 356063 [2921229][E](PTable): Success! + 356064 [2921231][E](PTable): Clean Power Table + 356065 [2921231][E](PTable): Averaged Entry: watts=134.000000, cad=78.199997, targetPosition=1224.00002, (4)(4) + 356066 [2921242][E](PTable): cellValue: (105) wattDelta: (1.724138) cadDelta: (0.287356) allNeighborsPassed: (0) + 356067 [2921253][E](PTable): rightValue: (0.000000) leftValue: (96.879997) bottomValue: (98.735992) topValue: (0.000000) New averaged targetPosition: (97.807999) count: (2) + 356068 [2921264][E](PTable): Bottom failed at: (104) Target pos: (97.807999) Avg pos: (100) + 356069 [2921275][E](PTable): All test failed bottom (3)(4)(106), readings (11) + 356070 [2921275][E](PTable): WEIGHTED DOWNVOTING: Target Value: (97), NeighborValue: (104) + 356071 [2921286][E](PTable): WEIGHTED DOWNVOTING: Delta: (7), Penalty: (1) + 356072 [2921287][E](PTable): PT failed (5)(4)(104), readings (10) + 356073 [2921299][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356074 [2921321][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356075 [2921354][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356076 [2921376][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356077 [2921408][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356078 [2921430][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356079 [2921461][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 356080 [2921483][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 356081 [2921515][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356082 [2921537][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 356083 [2921568][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356084 [2921589][E](PTable): Power Table Reset + 356085 [2921884][E](Custom_C): 01 19 <-targetPosition + 356086 [2921931][E](PTable): Success! + 356087 [2922267][E](Custom_C): 01 25 <-Firmware Version + 356088 [2922633][E](PTable): Success! + 356089 [2922897][E](Custom_C): 01 19 <-targetPosition + 356090 [2923339][E](PTable): Success! + 356091 [2923887][E](Custom_C): 01 19 <-targetPosition + 356092 [2923937][E](FTMS_SERVER): 05 ea 01 -> ERG Mode Target: 490 Current: 178 Incline: 119.849998 + 356093 [2923944][E](Custom_C): 01 28 <-targetWatts + 356094 [2924043][E](PTable): Success! + 356095 [2924043][E](PTable): Clean Power Table + 356096 [2924043][E](PTable): Averaged Entry: watts=154.800003, cad=81.000000, targetPosition=1211.99997, (4)(5) + 356097 [2924056][E](PTable): cellValue: (118) wattDelta: (9.375009) cadDelta: (1.562502) allNeighborsPassed: (1) + 356098 [2924067][E](PTable): rightValue: (118.512001) leftValue: (117.487999) bottomValue: (118.639999) topValue: (117.360001) New averaged targetPosition: (118.000000) count: (4) + 356099 [2924079][E](PTable): Existing entry averaged (4)(5)(118), readings(11) + 356100 [2924726][E](Custom_C): 01 27 04 <-Power Tab Data + 356101 [2924731][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356102 [2924753][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 356103 [2924785][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | | 214 | 215 | 217 | 220 | 221 | 222 | 223 | 225 | 227 | | | | | | | | | | + 356104 [2924808][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | 200 | | 203 | 210 | 215 | 218 | 220 | | 221 | 223 | 225 | | | | | | | | | | + 356105 [2924841][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 192 | 196 | 202 | 208 | 212 | 216 | 217 | 218 | 219 | 222 | | | | | | | | | | | + 356106 [2924863][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | 191 | 195 | 201 | 206 | 210 | 214 | 216 | 217 | 218 | 221 | | | | | | | | | | | + 356107 [2924887][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 189 | 194 | 199 | 203 | 207 | 211 | 213 | 215 | 217 | | | | | | | | | | | | + 356108 [2924937][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 183 | 187 | 192 | 197 | 201 | 205 | 209 | 211 | 213 | 216 | | | | | | | | | | | | + 356109 [2924959][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 180 | 185 | 190 | 194 | 198 | 202 | 206 | 208 | 212 | | | | | | | | | | | | | + 356110 [2924982][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | 163 | 168 | 173 | 178 | 182 | 187 | 191 | 196 | 200 | 204 | | | | | | | | | | | | | | | + 356111 [2925014][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | 175 | 179 | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 356112 [2925035][E](PTable): Power Table Reset + 356113 [2925045][E](PTable): Lookup debug 420 X1 510 X2 80 Y1 95 Y2 0 + 356114 [2925047][E](PTable): Lookup used neighbors L 171 R 182 R1 180 + 356115 [2925057][E](PTable): Lookup used neighbors U 181 D 170 R2 177 + 356116 [2925058][E](PTable): Lookup used actual 173 R3 173 + 356117 [2925068][E](PTable): Lookup result: 490w 85cad 17600 + 356118 [2925068][E](ERG_Mode): SetPoint changed:490w PowerTable Result: 17600 + 356119 [2925080][E](ERG_Mode): Capping ERG seek time to 5 seconds + 356120 [2925389][E](PTable): Success! + 356121 [2925889][E](Custom_C): 01 2a <-hMin + 356122 [2925934][E](Custom_C): 01 19 <-targetPosition + 356123 [2925979][E](Custom_C): 01 2b <-hMax + 356124 [2926069][E](Custom_C): 01 25 <-Firmware Version + 356125 [2926093][E](PTable): Success! + 356126 [2926796][E](PTable): Success! + 356127 [2926797][E](ERG_Mode): Proportional: 1152.000000, Integral: 34.799999, Derivative: 0.000000 + 356128 [2926879][E](Custom_C): 01 19 <-targetPosition + 356129 [2927499][E](PTable): Power Table Reset + 356130 [2927892][E](Custom_C): 01 19 <-targetPosition + 356131 [2928205][E](PTable): Success! + 356132 [2928882][E](Custom_C): 01 19 <-targetPosition + 356133 [2928908][E](PTable): Success! + 356134 [2929610][E](PTable): Success! + 356135 [2929916][E](Custom_C): 01 19 <-targetPosition + 356136 [2930315][E](PTable): Success! + 356137 [2930316][E](PTable): Clean Power Table + 356138 [2930316][E](PTable): Averaged Entry: watts=311.600006, cad=100.199997, targetPosition=1553.99994, (8)(10) + 356139 [2930328][E](PTable): cellValue: (141) wattDelta: (2.083334) cadDelta: (0.347222) allNeighborsPassed: (0) + 356140 [2930339][E](PTable): rightValue: (0.000000) leftValue: (135.432007) bottomValue: (141.575989) topValue: (0.000000) New averaged targetPosition: (138.503998) count: (2) + 356141 [2930350][E](PTable): Left failed at: (140) Target pos: (138.503998) Avg pos: (139) + 356142 [2930361][E](PTable): All test failed left (8)(9)(140), readings (1) + 356143 [2930361][E](PTable): WEIGHTED DOWNVOTING: Target Value: (138), NeighborValue: (140) + 356144 [2930372][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 356145 [2930372][E](PTable): PT failed (8)(9)(140), readings (1) + 356146 [2930385][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356147 [2930407][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356148 [2930439][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356149 [2930461][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356150 [2930493][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356151 [2930515][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356152 [2930547][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 356153 [2930569][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 356154 [2930601][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356155 [2930624][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | | | | | | | | | | | | | | | | | | | | | | + 356156 [2930656][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356157 [2930677][E](PTable): Power Table Reset + 356158 [2930898][E](Custom_C): 01 27 00 <-Power Tab Data + 356159 [2930955][E](Custom_C): 01 2a <-hMin + 356160 [2930997][E](Custom_C): 01 19 <-targetPosition + 356161 [2931016][E](PTable): Success! + 356162 [2931079][E](Custom_C): 01 27 01 <-Power Tab Data + 356163 [2931108][E](Custom_C): 01 2b <-hMax + 356164 [2931190][E](Custom_C): 01 27 02 <-Power Tab Data + 356165 [2931257][E](Custom_C): 01 27 03 <-Power Tab Data + 356166 [2931300][E](Custom_C): 01 27 04 <-Power Tab Data + 356167 [2931371][E](Custom_C): 01 27 05 <-Power Tab Data + 356168 [2931413][E](Custom_C): 01 27 06 <-Power Tab Data + 356169 [2931503][E](Custom_C): 01 27 07 <-Power Tab Data + 356170 [2931572][E](Custom_C): 01 27 08 <-Power Tab Data + 356171 [2931615][E](Custom_C): 01 27 09 <-Power Tab Data + 356172 [2931720][E](PTable): Success! + 356173 [2931896][E](Custom_C): 01 19 <-targetPosition + 356174 [2932421][E](PTable): Success! + 356175 [2932422][E](ERG_Mode): Proportional: -936.000000, Integral: -18.200001, Derivative: -22.600000 + 356176 [2932887][E](Custom_C): 01 19 <-targetPosition + 356177 [2933123][E](PTable): Success! + 356178 [2933124][E](PTable): Clean Power Table + 356179 [2933124][E](PTable): Averaged Entry: watts=531.200012, cad=101.400002, targetPosition=1636.00006, (8)(18) + 356180 [2933135][E](PTable): Keep old targetPosition: (163.600006) + 356181 [2933136][E](PTable): New entry recorded (8)(18)(163) + 356182 [2933554][E](Custom_C): 01 27 08 <-Power Tab Data + 356183 [2933560][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356184 [2933584][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | | | | | | | | | | | | 231 | | | | | | | | | | + 356185 [2933616][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | 214 | 215 | 216 | 218 | 221 | 224 | 225 | 226 | 227 | 230 | | | | | | | | | | + 356186 [2933637][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | | 201 | 208 | 214 | 217 | 219 | 221 | 223 | 224 | 225 | 226 | | | | | | | | | | + 356187 [2933669][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 193 | 200 | 206 | 211 | 216 | 218 | 220 | 222 | 223 | 224 | 225 | | | | | | | | | | + 356188 [2933693][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | | 199 | 203 | 208 | 213 | 214 | 215 | 216 | 220 | 223 | | | | | | | | | | | + 356189 [2933725][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 191 | 196 | 200 | 205 | 210 | 211 | 212 | 213 | 217 | 221 | | | | | | | | | | | + 356190 [2933747][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 184 | 185 | 193 | 197 | 202 | 207 | 208 | 209 | 212 | | | | | | | | | | | | | + 356191 [2933779][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 181 | | 190 | 194 | 199 | 204 | 205 | 207 | | | | | | | | | | | | | | + 356192 [2933801][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 163 | 165 | 187 | 191 | 196 | 201 | 203 | | | | | | | | | | | | | | | + 356193 [2933823][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | | | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 356194 [2933854][E](PTable): Power Table Reset + 356195 [2933871][E](PTable): Success! + 356196 [2933899][E](Custom_C): 01 19 <-targetPosition + 356197 [2934572][E](PTable): Success! + 356198 [2934889][E](Custom_C): 01 19 <-targetPosition + 356199 [2935279][E](PTable): Success! + 356200 [2935879][E](Custom_C): 01 2a <-hMin + 356201 [2935946][E](Custom_C): 01 19 <-targetPosition + 356202 [2935984][E](PTable): Success! + 356203 [2935985][E](PTable): Clean Power Table + 356204 [2935985][E](PTable): Averaged Entry: watts=405.200012, cad=100.199997, targetPosition=1608.00003, (8)(14) + 356205 [2935996][E](Custom_C): 01 2b <-hMax + 356206 [2935999][E](PTable): cellValue: (161) wattDelta: (150.002289) cadDelta: (25.000381) allNeighborsPassed: (1) + 356207 [2936010][E](PTable): rightValue: (160.501343) leftValue: (160.698669) bottomValue: (160.608002) topValue: (160.592010) New averaged targetPosition: (160.600006) count: (4) + 356208 [2936021][E](PTable): Existing entry averaged (8)(14)(160), readings(1) + 356209 [2936408][E](Custom_C): 01 27 08 <-Power Tab Data + 356210 [2936413][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356211 [2936435][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | | | | | | | | | | | | 231 | | | | | | | | | | + 356212 [2936468][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | 214 | 215 | 216 | 218 | 221 | 224 | 225 | 226 | 227 | 230 | | | | | | | | | | + 356213 [2936490][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | | 201 | 208 | 214 | 217 | 219 | 221 | 223 | 224 | 225 | 226 | | | | | | | | | | + 356214 [2936522][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 193 | 200 | 206 | 211 | 216 | 218 | 220 | 222 | 223 | 224 | 225 | | | | | | | | | | + 356215 [2936544][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | | 199 | 203 | 208 | 213 | 214 | 215 | 216 | 220 | 223 | | | | | | | | | | | + 356216 [2936577][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 191 | 196 | 200 | 205 | 210 | 211 | 212 | 213 | 217 | 221 | | | | | | | | | | | + 356217 [2936598][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 176 | | 179 | 184 | 185 | 193 | 197 | 202 | 207 | 208 | 209 | 212 | | | | | | | | | | | | | + 356218 [2936631][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 181 | | 190 | 194 | 199 | 204 | 205 | 207 | | | | | | | | | | | | | | + 356219 [2936653][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 160 | | | | 163 | 165 | 187 | 191 | 196 | 201 | 203 | | | | | | | | | | | | | | | + 356220 [2936685][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | | | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 356221 [2936706][E](PTable): Power Table Reset + 356222 [2936914][E](Custom_C): 01 19 <-targetPosition + 356223 [2936976][E](PTable): Success! + 356224 [2937680][E](PTable): Success! + 356225 [2937927][E](Custom_C): 01 19 <-targetPosition + 356226 [2938382][E](PTable): Success! + 356227 [2938383][E](ERG_Mode): Proportional: -24.000000, Integral: 5.400000, Derivative: -0.600000 + 356228 [2938485][E](FTMS_SERVER): 05 82 00 -> ERG Mode Target: 130 Current: 496 Incline: 165.028015 + 356229 [2938501][E](Custom_C): 01 28 <-targetWatts + 356230 [2938893][E](Custom_C): 01 19 <-targetPosition + 356231 [2939084][E](PTable): Success! + 356232 [2939085][E](PTable): Clean Power Table + 356233 [2939085][E](PTable): Averaged Entry: watts=477.600006, cad=100.000000, targetPosition=1650.00000, (8)(16) + 356234 [2939096][E](PTable): Keep old targetPosition: (165.000000) + 356235 [2939097][E](PTable): Right failed at: (163) Target pos: (165.000000) Avg pos: (164) + 356236 [2939109][E](PTable): Current Position moved right was valid! Current position: 165.000000 + 356237 [2939120][E](PTable): Existing entry averaged (8)(18)(164), readings(1) + 356238 [2939536][E](PTable): Right Neighbors position was valid with Left Neighbors cadence and watts! Right Neighbor Position: 163 + 356239 [2939536][E](PTable): Existing entry averaged (8)(14)(161), readings(2) + 356240 [2939682][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356241 [2939704][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | | | | | | | | | | | | 231 | | | | | | | | | | + 356242 [2939736][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | 214 | 215 | 216 | 218 | 221 | 224 | 225 | 226 | 227 | 230 | | | | | | | | | | + 356243 [2939758][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | | 201 | 208 | 214 | 217 | 219 | 221 | 223 | 224 | 225 | 226 | | | | | | | | | | + 356244 [2939780][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 193 | 200 | 206 | 211 | 216 | 218 | 220 | 222 | 223 | 224 | 225 | | | | | | | | | | + 356245 [2939813][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | | 199 | 203 | 208 | 213 | 214 | 215 | 216 | 220 | 223 | | | | | | | | | | | + 356246 [2939835][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 191 | 196 | 200 | 205 | 210 | 211 | 212 | 213 | 217 | 221 | | | | | | | | | | | + 356247 [2939867][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 167 | 176 | | 179 | 184 | 185 | 193 | 197 | 202 | 207 | 208 | 209 | 212 | | | | | | | | | | | | | + 356248 [2939888][E](Custom_C): 01 19 <-targetPosition + 356249 [2939913][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 187 | 191 | 196 | 201 | 203 | | | | | | | | | | | | | | | + 356250 [2939937][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | | | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 356251 [2939958][E](PTable): Power Table Reset + 356252 [2939969][E](PTable): Lookup debug 60 X1 150 X2 95 Y1 105 Y2 0 + 356253 [2939970][E](PTable): Lookup used neighbors L 72 R 104 R1 97 + 356254 [2939970][E](PTable): Lookup used neighbors U 102 D 98 R2 100 + 356255 [2939981][E](PTable): Lookup used actual 100 R3 100 + 356256 [2939982][E](PTable): Lookup result: 130w 99cad 9800 + 356257 [2939992][E](ERG_Mode): SetPoint changed:130w PowerTable Result: 9800 + 356258 [2939992][E](ERG_Mode): Capping ERG seek time to 5 seconds + 356259 [2940020][E](PTable): Success! + 356260 [2940720][E](PTable): Success! + 356261 [2940897][E](Custom_C): 01 2a <-hMin + 356262 [2940941][E](Custom_C): 01 19 <-targetPosition + 356263 [2941009][E](Custom_C): 01 2b <-hMax + 356264 [2941422][E](PTable): Success! + 356265 [2941887][E](Custom_C): 01 19 <-targetPosition + 356266 [2942124][E](PTable): Power Table Reset + 356267 [2942269][E](Custom_C): 01 25 <-Firmware Version + 356268 [2942825][E](PTable): Success! + 356269 [2942921][E](Custom_C): 01 19 <-targetPosition + 356270 [2943529][E](PTable): Success! + 356271 [2943530][E](ERG_Mode): Proportional: -384.000000, Integral: -15.600000, Derivative: 10.000000 + 356272 [2943889][E](Custom_C): 01 19 <-targetPosition + 356273 [2944231][E](PTable): Success! + 356274 [2944901][E](Custom_C): 01 19 <-targetPosition + 356275 [2944933][E](PTable): Success! + 356276 [2944934][E](PTable): Clean Power Table + 356277 [2944934][E](PTable): Averaged Entry: watts=331.600006, cad=95.599998, targetPosition=1330.00000, (7)(11) + 356278 [2944947][E](PTable): cellValue: (145) wattDelta: (2.500000) cadDelta: (0.416667) allNeighborsPassed: (0) + 356279 [2944949][E](PTable): rightValue: (121.639999) leftValue: (0.000000) bottomValue: (0.000000) topValue: (119.560005) New averaged targetPosition: (120.600006) count: (2) + 356280 [2944970][E](PTable): Left failed at: (142) Target pos: (120.600006) Avg pos: (131) + 356281 [2944971][E](PTable): All test failed left (7)(10)(142), readings (11) + 356282 [2944981][E](PTable): WEIGHTED DOWNVOTING: Target Value: (120), NeighborValue: (142) + 356283 [2944992][E](PTable): WEIGHTED DOWNVOTING: Delta: (22), Penalty: (4) + 356284 [2944992][E](PTable): PT failed (7)(10)(142), readings (7) + 356285 [2945003][E](PTable): Bottom failed at: (144) Target pos: (120.600006) Avg pos: (132) + 356286 [2945003][E](PTable): Was not in range failed bottom (8)(11)(144), readings (11) + 356287 [2945014][E](PTable): WEIGHTED DOWNVOTING: Target Value: (120), NeighborValue: (144) + 356288 [2945024][E](PTable): WEIGHTED DOWNVOTING: Delta: (24), Penalty: (4) + 356289 [2945024][E](PTable): PT failed (8)(11)(144), readings (7) + 356290 [2945037][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356291 [2945060][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356292 [2945092][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356293 [2945114][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356294 [2945147][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356295 [2945170][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356296 [2945192][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 356297 [2945224][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 356298 [2945246][E](PTable): 95 rpm | | | | | 102 | 105 | 115 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356299 [2945280][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 356300 [2945302][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356301 [2945333][E](PTable): Power Table Reset + 356302 [2945751][E](PTable): Success! + 356303 [2945905][E](Custom_C): 01 27 00 <-Power Tab Data + 356304 [2945959][E](Custom_C): 01 2a <-hMin + 356305 [2946048][E](Custom_C): 01 19 <-targetPosition + 356306 [2946130][E](Custom_C): 01 27 01 <-Power Tab Data + 356307 [2946161][E](Custom_C): 01 2b <-hMax + 356308 [2946219][E](Custom_C): 01 27 02 <-Power Tab Data + 356309 [2946263][E](Custom_C): 01 27 03 <-Power Tab Data + 356310 [2946332][E](Custom_C): 01 27 04 <-Power Tab Data + 356311 [2946376][E](Custom_C): 01 27 05 <-Power Tab Data + 356312 [2946421][E](Custom_C): 01 27 06 <-Power Tab Data + 356313 [2946455][E](PTable): Success! + 356314 [2946465][E](Custom_C): 01 27 07 <-Power Tab Data + 356315 [2946535][E](Custom_C): 01 27 08 <-Power Tab Data + 356316 [2946579][E](Custom_C): 01 27 09 <-Power Tab Data + 356317 [2946635][E](Custom_C): 01 25 <-Firmware Version + 356318 [2946887][E](Custom_C): 01 19 <-targetPosition + 356319 [2947156][E](PTable): Success! + 356320 [2947157][E](PTable): Using detected travel limits during homing + 356321 [2947857][E](PTable): Success! + 356322 [2947859][E](PTable): Clean Power Table + 356323 [2947859][E](PTable): Averaged Entry: watts=178.000000, cad=94.400002, targetPosition=1188.00003, (7)(6) + 356324 [2947870][E](PTable): cellValue: (115) wattDelta: (7.894731) cadDelta: (1.315788) allNeighborsPassed: (0) + 356325 [2947881][E](PTable): rightValue: (114.746666) leftValue: (115.253334) bottomValue: (114.543999) topValue: (0.000000) New averaged targetPosition: (114.848000) count: (3) + 356326 [2947893][E](Custom_C): 01 19 <-targetPosition + 356327 [2947896][E](PTable): Existing entry averaged (7)(6)(114), readings(2) + 356328 [2948300][E](Custom_C): 01 27 07 <-Power Tab Data + 356329 [2948306][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356330 [2948329][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | | | | | | | | | | | | 231 | | | | | | | | | | + 356331 [2948361][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | 214 | 215 | 216 | 218 | 221 | 224 | 225 | 226 | 227 | 230 | | | | | | | | | | + 356332 [2948382][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | | 201 | 208 | 214 | 217 | 219 | 221 | 223 | 224 | 225 | 226 | | | | | | | | | | + 356333 [2948414][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 193 | 200 | 206 | 211 | 216 | 218 | 220 | 222 | 223 | 224 | 225 | | | | | | | | | | + 356334 [2948436][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | | 199 | 203 | 208 | 213 | 214 | 215 | 216 | 220 | 223 | | | | | | | | | | | + 356335 [2948468][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 191 | 196 | 200 | 205 | 210 | 211 | 212 | 213 | 217 | 221 | | | | | | | | | | | + 356336 [2948490][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 184 | 185 | 193 | 197 | 202 | 207 | 208 | 209 | 212 | | | | | | | | | | | | | + 356337 [2948522][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 181 | | 190 | 194 | 199 | 204 | 205 | 207 | | | | | | | | | | | | | | + 356338 [2948545][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 187 | 191 | 196 | 201 | 203 | | | | | | | | | | | | | | | + 356339 [2948577][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | | | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 356340 [2948598][E](PTable): Power Table Reset + 356341 [2948834][E](PTable): Success! + 356342 [2948840][E](ERG_Mode): Proportional: 8.000000, Integral: -5.800000, Derivative: 1.400000 + 356343 [2948906][E](Custom_C): 01 19 <-targetPosition + 356344 [2949535][E](PTable): Success! + 356345 [2949897][E](Custom_C): 01 19 <-targetPosition + 356346 [2950238][E](PTable): Success! + 356347 [2950932][E](Custom_C): 01 2a <-hMin + 356348 [2950942][E](PTable): Success! + 356349 [2950942][E](PTable): Clean Power Table + 356350 [2950943][E](PTable): Averaged Entry: watts=125.599998, cad=88.000000, targetPosition=1160.00000, (6)(4) + 356351 [2950954][E](PTable): cellValue: (103) wattDelta: (2.307692) cadDelta: (0.384615) allNeighborsPassed: (0) + 356352 [2950965][E](PTable): rightValue: (0.000000) leftValue: (100.573334) bottomValue: (97.800003) topValue: (0.000000) New averaged targetPosition: (99.186668) count: (2) + 356353 [2950976][E](Custom_C): 01 19 <-targetPosition + 356354 [2950983][E](PTable): Bottom failed at: (102) Target pos: (99.186668) Avg pos: (100) + 356355 [2950984][E](PTable): All test failed bottom (5)(4)(104), readings (10) + 356356 [2950994][E](PTable): WEIGHTED DOWNVOTING: Target Value: (99), NeighborValue: (102) + 356357 [2951005][E](PTable): WEIGHTED DOWNVOTING: Delta: (3), Penalty: (0) + 356358 [2951005][E](PTable): PT failed (7)(4)(102), readings (8) + 356359 [2951018][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356360 [2951040][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356361 [2951086][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356362 [2951108][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356363 [2951140][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356364 [2951161][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356365 [2951194][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 356366 [2951215][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 356367 [2951247][E](PTable): 95 rpm | | | | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356368 [2951269][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 356369 [2951302][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356370 [2951323][E](PTable): Power Table Reset + 356371 [2951647][E](PTable): Success! + 356372 [2951899][E](Custom_C): 01 19 <-targetPosition + 356373 [2952348][E](PTable): Success! + 356374 [2952889][E](Custom_C): 01 19 <-targetPosition + 356375 [2953050][E](PTable): Success! + 356376 [2953752][E](PTable): Success! + 356377 [2953753][E](PTable): Clean Power Table + 356378 [2953753][E](PTable): Averaged Entry: watts=112.400002, cad=87.199997, targetPosition=1170.00000, (5)(4) + 356379 [2953765][E](PTable): cellValue: (104) wattDelta: (2.307692) cadDelta: (0.384615) allNeighborsPassed: (0) + 356380 [2953776][E](PTable): rightValue: (0.000000) leftValue: (107.293335) bottomValue: (109.719994) topValue: (0.000000) New averaged targetPosition: (108.506668) count: (2) + 356381 [2953787][E](PTable): Right failed at: (108) Target pos: (108.506668) Avg pos: (108) + 356382 [2953798][E](PTable): Was not in range failed right (5)(5)(108), readings (11) + 356383 [2953799][E](PTable): WEIGHTED DOWNVOTING: Target Value: (108), NeighborValue: (108) + 356384 [2953809][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 356385 [2953810][E](PTable): PT failed (5)(5)(108), readings (11) + 356386 [2953820][E](PTable): Top failed at: (105) Target pos: (108.506668) Avg pos: (106) + 356387 [2953831][E](PTable): All test failed top (4)(4)(105), readings (11) + 356388 [2953832][E](PTable): WEIGHTED DOWNVOTING: Target Value: (108), NeighborValue: (105) + 356389 [2953842][E](PTable): WEIGHTED DOWNVOTING: Delta: (3), Penalty: (0) + 356390 [2953843][E](PTable): PT failed (4)(4)(105), readings (11) + 356391 [2953857][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356392 [2953879][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356393 [2953926][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356394 [2953950][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356395 [2953972][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356396 [2954004][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356397 [2954026][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 356398 [2954059][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 356399 [2954081][E](PTable): 95 rpm | | | | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356400 [2954114][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 356401 [2954136][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356402 [2954167][E](PTable): Power Table Reset + 356403 [2954167][E](ERG_Mode): Proportional: 48.000000, Integral: 0.600000, Derivative: -1.800000 + 356404 [2954457][E](PTable): Success! + 356405 [2954891][E](Custom_C): 01 19 <-targetPosition + 356406 [2955158][E](PTable): Success! + 356407 [2955860][E](PTable): Success! + 356408 [2955881][E](Custom_C): 01 2a <-hMin + 356409 [2955948][E](Custom_C): 01 19 <-targetPosition + 356410 [2955994][E](Custom_C): 01 2b <-hMax + 356411 [2956563][E](PTable): Success! + 356412 [2956563][E](PTable): Clean Power Table + 356413 [2956564][E](PTable): Averaged Entry: watts=120.000000, cad=85.000000, targetPosition=1184.00002, (5)(4) + 356414 [2956575][E](PTable): cellValue: (104) wattDelta: (2.083333) cadDelta: (0.347222) allNeighborsPassed: (0) + 356415 [2956586][E](PTable): rightValue: (0.000000) leftValue: (104.000000) bottomValue: (104.000000) topValue: (0.000000) New averaged targetPosition: (104.000000) count: (2) + 356416 [2956597][E](PTable): Existing entry averaged (5)(4)(104), readings(10) + 356417 [2956894][E](Custom_C): 01 19 <-targetPosition + 356418 [2957019][E](Custom_C): 01 27 05 <-Power Tab Data + 356419 [2957026][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356420 [2957048][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | | | | | | | | | | | | 231 | | | | | | | | | | + 356421 [2957080][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | 214 | 215 | 216 | 218 | 221 | 224 | 225 | 226 | 227 | 230 | | | | | | | | | | + 356422 [2957102][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | | 201 | 208 | 214 | 217 | 219 | 221 | 223 | 224 | 225 | 226 | | | | | | | | | | + 356423 [2957134][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 193 | 200 | 206 | 211 | 216 | 218 | 220 | 222 | 223 | 224 | 225 | | | | | | | | | | + 356424 [2957156][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | | 199 | 203 | 208 | 213 | 214 | 215 | 216 | 220 | 223 | | | | | | | | | | | + 356425 [2957187][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 191 | 196 | 200 | 205 | 210 | 211 | 212 | 213 | 217 | 221 | | | | | | | | | | | + 356426 [2957209][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 184 | 185 | 193 | 197 | 202 | 207 | 208 | 209 | 212 | | | | | | | | | | | | | + 356427 [2957241][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 181 | | 190 | 194 | 199 | 204 | 205 | 207 | | | | | | | | | | | | | | + 356428 [2957264][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 187 | 191 | 196 | 201 | 203 | | | | | | | | | | | | | | | + 356429 [2957296][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | | | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 356430 [2957317][E](PTable): Power Table Reset + 356431 [2957348][E](PTable): Success! + 356432 [2957907][E](Custom_C): 01 19 <-targetPosition + 356433 [2958053][E](PTable): Success! + 356434 [2958757][E](PTable): Success! + 356435 [2958897][E](Custom_C): 01 19 <-targetPosition + 356436 [2959459][E](PTable): Success! + 356437 [2959460][E](PTable): Clean Power Table + 356438 [2959460][E](PTable): Averaged Entry: watts=120.800003, cad=84.000000, targetPosition=1191.99997, (5)(4) + 356439 [2959471][E](PTable): cellValue: (104) wattDelta: (1.973685) cadDelta: (0.328947) allNeighborsPassed: (0) + 356440 [2959482][E](PTable): rightValue: (0.000000) leftValue: (103.594666) bottomValue: (100.959999) topValue: (0.000000) New averaged targetPosition: (102.277328) count: (2) + 356441 [2959494][E](PTable): Bottom failed at: (103) Target pos: (102.277328) Avg pos: (102) + 356442 [2959505][E](PTable): All test failed bottom (4)(4)(105), readings (11) + 356443 [2959506][E](PTable): WEIGHTED DOWNVOTING: Target Value: (102), NeighborValue: (103) + 356444 [2959516][E](PTable): WEIGHTED DOWNVOTING: Delta: (1), Penalty: (0) + 356445 [2959516][E](PTable): PT failed (6)(4)(103), readings (8) + 356446 [2959529][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356447 [2959550][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356448 [2959583][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356449 [2959605][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356450 [2959637][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356451 [2959659][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356452 [2959692][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 356453 [2959713][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 356454 [2959745][E](PTable): 95 rpm | | | | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356455 [2959767][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 356456 [2959799][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356457 [2959820][E](PTable): Power Table Reset + 356458 [2959820][E](ERG_Mode): Proportional: 16.000000, Integral: 6.000000, Derivative: -0.800000 + 356459 [2959887][E](Custom_C): 01 19 <-targetPosition + 356460 [2960160][E](PTable): Success! + 356461 [2960865][E](PTable): Success! + 356462 [2960911][E](Custom_C): 01 27 00 <-Power Tab Data + 356463 [2960966][E](Custom_C): 01 2a <-hMin + 356464 [2961011][E](Custom_C): 01 19 <-targetPosition + 356465 [2961068][E](Custom_C): 01 27 01 <-Power Tab Data + 356466 [2961102][E](Custom_C): 01 2b <-hMax + 356467 [2961183][E](Custom_C): 01 27 02 <-Power Tab Data + 356468 [2961228][E](Custom_C): 01 27 03 <-Power Tab Data + 356469 [2961294][E](Custom_C): 01 27 04 <-Power Tab Data + 356470 [2961362][E](Custom_C): 01 27 05 <-Power Tab Data + 356471 [2961428][E](Custom_C): 01 27 06 <-Power Tab Data + 356472 [2961473][E](Custom_C): 01 27 07 <-Power Tab Data + 356473 [2961518][E](Custom_C): 01 27 08 <-Power Tab Data + 356474 [2961565][E](Custom_C): 01 27 09 <-Power Tab Data + 356475 [2961569][E](PTable): Success! + 356476 [2961888][E](Custom_C): 01 19 <-targetPosition + 356477 [2962272][E](Custom_C): 01 25 <-Firmware Version + 356478 [2962276][E](PTable): Success! + 356479 [2962277][E](PTable): Clean Power Table + 356480 [2962277][E](PTable): Averaged Entry: watts=197.199997, cad=90.199997, targetPosition=1170.00000, (6)(7) + 356481 [2962288][E](PTable): cellValue: (124) wattDelta: (4.285714) cadDelta: (0.714286) allNeighborsPassed: (0) + 356482 [2962300][E](PTable): rightValue: (107.013336) leftValue: (0.000000) bottomValue: (0.000000) topValue: (109.720001) New averaged targetPosition: (108.366669) count: (2) + 356483 [2962311][E](PTable): Left failed at: (117) Target pos: (108.366669) Avg pos: (112) + 356484 [2962322][E](PTable): All test failed left (6)(6)(117), readings (7) + 356485 [2962322][E](PTable): WEIGHTED DOWNVOTING: Target Value: (108), NeighborValue: (117) + 356486 [2962333][E](PTable): WEIGHTED DOWNVOTING: Delta: (9), Penalty: (1) + 356487 [2962333][E](PTable): PT failed (6)(6)(117), readings (6) + 356488 [2962344][E](PTable): Bottom failed at: (122) Target pos: (108.366669) Avg pos: (115) + 356489 [2962354][E](PTable): Was not in range failed bottom (7)(7)(122), readings (5) + 356490 [2962355][E](PTable): WEIGHTED DOWNVOTING: Target Value: (108), NeighborValue: (122) + 356491 [2962366][E](PTable): WEIGHTED DOWNVOTING: Delta: (14), Penalty: (2) + 356492 [2962366][E](PTable): PT failed (7)(7)(122), readings (3) + 356493 [2962378][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356494 [2962401][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356495 [2962433][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356496 [2962456][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356497 [2962488][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356498 [2962510][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356499 [2962542][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 356500 [2962563][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 356501 [2962595][E](PTable): 95 rpm | | | | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356502 [2962617][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 356503 [2962649][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356504 [2962671][E](PTable): Power Table Reset + 356505 [2962901][E](Custom_C): 01 19 <-targetPosition + 356506 [2962980][E](PTable): Success! + 356507 [2963685][E](PTable): Success! + 356508 [2963892][E](Custom_C): 01 19 <-targetPosition + 356509 [2964386][E](PTable): Success! + 356510 [2964882][E](Custom_C): 01 19 <-targetPosition + 356511 [2965088][E](PTable): Success! + 356512 [2965089][E](PTable): Clean Power Table + 356513 [2965089][E](PTable): Averaged Entry: watts=122.400002, cad=88.000000, targetPosition=1154.00002, (6)(4) + 356514 [2965100][E](PTable): cellValue: (103) wattDelta: (2.419354) cadDelta: (0.403226) allNeighborsPassed: (0) + 356515 [2965111][E](PTable): rightValue: (0.000000) leftValue: (102.007996) bottomValue: (98.040001) topValue: (0.000000) New averaged targetPosition: (100.024002) count: (2) + 356516 [2965122][E](PTable): Bottom failed at: (102) Target pos: (100.024002) Avg pos: (101) + 356517 [2965134][E](PTable): All test failed bottom (5)(4)(104), readings (11) + 356518 [2965134][E](PTable): WEIGHTED DOWNVOTING: Target Value: (100), NeighborValue: (102) + 356519 [2965145][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 356520 [2965145][E](PTable): PT failed (7)(4)(102), readings (8) + 356521 [2965157][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356522 [2965179][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356523 [2965211][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356524 [2965232][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356525 [2965265][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356526 [2965287][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356527 [2965319][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 356528 [2965341][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 356529 [2965373][E](PTable): 95 rpm | | | | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356530 [2965394][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 356531 [2965427][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356532 [2965447][E](PTable): Power Table Reset + 356533 [2965458][E](ERG_Mode): Proportional: 64.000000, Integral: -1.400000, Derivative: 0.800000 + 356534 [2965816][E](PTable): Success! + 356535 [2965893][E](Custom_C): 01 2a <-hMin + 356536 [2965962][E](Custom_C): 01 19 <-targetPosition + 356537 [2966006][E](Custom_C): 01 2b <-hMax + 356538 [2966051][E](Custom_C): 01 25 <-Firmware Version + 356539 [2966519][E](PTable): Success! + 356540 [2966907][E](Custom_C): 01 19 <-targetPosition + 356541 [2967221][E](PTable): Success! + 356542 [2967919][E](Custom_C): 01 19 <-targetPosition + 356543 [2967924][E](PTable): Success! + 356544 [2967925][E](PTable): Clean Power Table + 356545 [2967925][E](PTable): Averaged Entry: watts=112.800003, cad=86.599998, targetPosition=1164.00002, (5)(4) + 356546 [2967937][E](PTable): cellValue: (104) wattDelta: (2.419354) cadDelta: (0.403226) allNeighborsPassed: (0) + 356547 [2967948][E](PTable): rightValue: (0.000000) leftValue: (106.975998) bottomValue: (107.967995) topValue: (0.000000) New averaged targetPosition: (107.472000) count: (2) + 356548 [2967959][E](PTable): Top failed at: (105) Target pos: (107.472000) Avg pos: (106) + 356549 [2967970][E](PTable): All test failed top (4)(4)(105), readings (11) + 356550 [2967970][E](PTable): WEIGHTED DOWNVOTING: Target Value: (107), NeighborValue: (105) + 356551 [2967980][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 356552 [2967981][E](PTable): PT failed (4)(4)(105), readings (11) + 356553 [2967993][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356554 [2968015][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356555 [2968047][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356556 [2968069][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356557 [2968101][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356558 [2968122][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356559 [2968154][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 356560 [2968176][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 356561 [2968208][E](PTable): 95 rpm | | | | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356562 [2968230][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 356563 [2968261][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356564 [2968282][E](PTable): Power Table Reset + 356565 [2968625][E](PTable): Success! + 356566 [2968887][E](Custom_C): 01 19 <-targetPosition + 356567 [2969330][E](PTable): Success! + 356568 [2969899][E](Custom_C): 01 19 <-targetPosition + 356569 [2970033][E](PTable): Success! + 356570 [2970738][E](PTable): Success! + 356571 [2970739][E](PTable): Clean Power Table + 356572 [2970739][E](PTable): Averaged Entry: watts=124.400002, cad=85.599998, targetPosition=1184.00002, (5)(4) + 356573 [2970751][E](PTable): cellValue: (104) wattDelta: (2.083333) cadDelta: (0.347222) allNeighborsPassed: (0) + 356574 [2970763][E](PTable): rightValue: (0.000000) leftValue: (101.888000) bottomValue: (105.727997) topValue: (0.000000) New averaged targetPosition: (103.807999) count: (2) + 356575 [2970774][E](PTable): Bottom failed at: (103) Target pos: (103.807999) Avg pos: (103) + 356576 [2970785][E](PTable): Was not in range failed bottom (6)(4)(103), readings (8) + 356577 [2970786][E](PTable): WEIGHTED DOWNVOTING: Target Value: (103), NeighborValue: (103) + 356578 [2970797][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 356579 [2970797][E](PTable): PT failed (6)(4)(103), readings (8) + 356580 [2970809][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356581 [2970831][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356582 [2970865][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356583 [2970889][E](Custom_C): 01 2a <-hMin + 356584 [2970893][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356585 [2970915][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356586 [2970946][E](Custom_C): 01 19 <-targetPosition + 356587 [2970951][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356588 [2970973][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 356589 [2971005][E](Custom_C): 01 2b <-hMax + 356590 [2971009][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 356591 [2971030][E](PTable): 95 rpm | | | | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356592 [2971065][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 356593 [2971086][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356594 [2971118][E](PTable): Power Table Reset + 356595 [2971118][E](ERG_Mode): Proportional: -16.000000, Integral: 3.200000, Derivative: -0.800000 + 356596 [2971440][E](PTable): Success! + 356597 [2971912][E](Custom_C): 01 19 <-targetPosition + 356598 [2972141][E](PTable): Success! + 356599 [2972845][E](PTable): Success! + 356600 [2972892][E](Custom_C): 01 19 <-targetPosition + 356601 [2973549][E](PTable): Success! + 356602 [2973550][E](PTable): Clean Power Table + 356603 [2973550][E](PTable): Averaged Entry: watts=126.000000, cad=86.599998, targetPosition=1190.00000, (5)(4) + 356604 [2973561][E](PTable): cellValue: (104) wattDelta: (2.000000) cadDelta: (0.333333) allNeighborsPassed: (0) + 356605 [2973573][E](PTable): rightValue: (0.000000) leftValue: (101.000000) bottomValue: (108.799995) topValue: (0.000000) New averaged targetPosition: (104.899994) count: (2) + 356606 [2973584][E](PTable): Existing entry averaged (5)(4)(104), readings(11) + 356607 [2973882][E](Custom_C): 01 19 <-targetPosition + 356608 [2973992][E](Custom_C): 01 27 05 <-Power Tab Data + 356609 [2973998][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356610 [2974020][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | | | | | | | | | | | | 231 | | | | | | | | | | + 356611 [2974052][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | 214 | 215 | 216 | 218 | 221 | 224 | 225 | 226 | 227 | 230 | | | | | | | | | | + 356612 [2974074][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | | 201 | 208 | 214 | 217 | 219 | 221 | 223 | 224 | 225 | 226 | | | | | | | | | | + 356613 [2974106][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 193 | 200 | 206 | 211 | 216 | 218 | 220 | 222 | 223 | 224 | 225 | | | | | | | | | | + 356614 [2974128][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | | 199 | 203 | 208 | 213 | 214 | 215 | 216 | 220 | 223 | | | | | | | | | | | + 356615 [2974160][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 191 | 196 | 200 | 205 | 210 | 211 | 212 | 213 | 217 | 221 | | | | | | | | | | | + 356616 [2974182][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 184 | 185 | 193 | 197 | 202 | 207 | 208 | 209 | 212 | | | | | | | | | | | | | + 356617 [2974214][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 181 | | 190 | 194 | 199 | 204 | 205 | 207 | | | | | | | | | | | | | | + 356618 [2974236][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 187 | 191 | 196 | 201 | 203 | | | | | | | | | | | | | | | + 356619 [2974268][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | | | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 356620 [2974289][E](PTable): Power Table Reset + 356621 [2974317][E](PTable): Success! + 356622 [2974894][E](Custom_C): 01 19 <-targetPosition + 356623 [2975022][E](PTable): Success! + 356624 [2975723][E](PTable): Success! + 356625 [2975922][E](Custom_C): 01 27 00 <-Power Tab Data + 356626 [2975952][E](Custom_C): 01 2a <-hMin + 356627 [2976042][E](Custom_C): 01 19 <-targetPosition + 356628 [2976098][E](Custom_C): 01 27 01 <-Power Tab Data + 356629 [2976131][E](Custom_C): 01 2b <-hMax + 356630 [2976211][E](Custom_C): 01 27 02 <-Power Tab Data + 356631 [2976256][E](Custom_C): 01 27 03 <-Power Tab Data + 356632 [2976301][E](Custom_C): 01 27 04 <-Power Tab Data + 356633 [2976346][E](Custom_C): 01 27 05 <-Power Tab Data + 356634 [2976414][E](Custom_C): 01 27 06 <-Power Tab Data + 356635 [2976424][E](PTable): Success! + 356636 [2976425][E](PTable): Clean Power Table + 356637 [2976425][E](PTable): Averaged Entry: watts=133.199997, cad=86.800003, targetPosition=1188.00003, (5)(4) + 356638 [2976438][E](PTable): cellValue: (104) wattDelta: (2.027027) cadDelta: (0.337838) allNeighborsPassed: (0) + 356639 [2976450][E](PTable): rightValue: (0.000000) leftValue: (97.487999) bottomValue: (109.328011) topValue: (0.000000) New averaged targetPosition: (103.408005) count: (2) + 356640 [2976495][E](PTable): Bottom failed at: (103) Target pos: (103.408005) Avg pos: (103) + 356641 [2976496][E](PTable): Was not in range failed bottom (6)(4)(103), readings (8) + 356642 [2976506][E](PTable): WEIGHTED DOWNVOTING: Target Value: (103), NeighborValue: (103) + 356643 [2976507][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 356644 [2976517][E](PTable): PT failed (6)(4)(103), readings (8) + 356645 [2976530][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356646 [2976552][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356647 [2976616][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356648 [2976638][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356649 [2976660][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356650 [2976729][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356651 [2976752][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 356652 [2976773][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 356653 [2976806][E](PTable): 95 rpm | | | | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356654 [2976827][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 356655 [2976859][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356656 [2976880][E](PTable): Power Table Reset + 356657 [2976891][E](ERG_Mode): Proportional: -80.000000, Integral: 0.800000, Derivative: 0.000000 + 356658 [2976942][E](Custom_C): 01 19 <-targetPosition + 356659 [2977357][E](PTable): Success! + 356660 [2977887][E](Custom_C): 01 19 <-targetPosition + 356661 [2978057][E](PTable): Success! + 356662 [2978762][E](PTable): Success! + 356663 [2978899][E](Custom_C): 01 19 <-targetPosition + 356664 [2979466][E](PTable): Success! + 356665 [2979467][E](PTable): Clean Power Table + 356666 [2979467][E](PTable): Averaged Entry: watts=154.000000, cad=86.400002, targetPosition=1171.99997, (5)(5) + 356667 [2979479][E](PTable): cellValue: (108) wattDelta: (3.260871) cadDelta: (0.543478) allNeighborsPassed: (1) + 356668 [2979490][E](PTable): rightValue: (109.226669) leftValue: (106.773331) bottomValue: (110.576004) topValue: (105.423996) New averaged targetPosition: (108.000000) count: (4) + 356669 [2979501][E](PTable): Existing entry averaged (5)(5)(108), readings(11) + 356670 [2979889][E](Custom_C): 01 19 <-targetPosition + 356671 [2979904][E](Custom_C): 01 27 05 <-Power Tab Data + 356672 [2979911][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356673 [2979934][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | | | | | | | | | | | | 231 | | | | | | | | | | + 356674 [2979968][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | 214 | 215 | 216 | 218 | 221 | 224 | 225 | 226 | 227 | 230 | | | | | | | | | | + 356675 [2979989][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | | 201 | 208 | 214 | 217 | 219 | 221 | 223 | 224 | 225 | 226 | | | | | | | | | | + 356676 [2980022][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 193 | 200 | 206 | 211 | 216 | 218 | 220 | 222 | 223 | 224 | 225 | | | | | | | | | | + 356677 [2980044][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | | 199 | 203 | 208 | 213 | 214 | 215 | 216 | 220 | 223 | | | | | | | | | | | + 356678 [2980077][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 191 | 196 | 200 | 205 | 210 | 211 | 212 | 213 | 217 | 221 | | | | | | | | | | | + 356679 [2980098][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 184 | 185 | 193 | 197 | 202 | 207 | 208 | 209 | 212 | | | | | | | | | | | | | + 356680 [2980130][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 181 | | 190 | 194 | 199 | 204 | 205 | 207 | | | | | | | | | | | | | | + 356681 [2980152][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 187 | 191 | 196 | 201 | 203 | | | | | | | | | | | | | | | + 356682 [2980185][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | | | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 356683 [2980206][E](PTable): Power Table Reset + 356684 [2980223][E](PTable): Success! + 356685 [2980881][E](Custom_C): 01 2a <-hMin + 356686 [2980924][E](PTable): Success! + 356687 [2980946][E](Custom_C): 01 19 <-targetPosition + 356688 [2981014][E](Custom_C): 01 2b <-hMax + 356689 [2981629][E](PTable): Success! + 356690 [2981891][E](Custom_C): 01 19 <-targetPosition + 356691 [2982273][E](Custom_C): 01 25 <-Firmware Version + 356692 [2982332][E](PTable): Success! + 356693 [2982333][E](PTable): Clean Power Table + 356694 [2982333][E](PTable): Averaged Entry: watts=175.600006, cad=92.800003, targetPosition=1144.00002, (7)(6) + 356695 [2982344][E](PTable): cellValue: (114) wattDelta: (74.999718) cadDelta: (12.499952) allNeighborsPassed: (1) + 356696 [2982355][E](PTable): rightValue: (113.941330) leftValue: (114.058670) bottomValue: (113.823997) topValue: (114.176003) New averaged targetPosition: (114.000000) count: (4) + 356697 [2982366][E](PTable): Existing entry averaged (7)(6)(114), readings(3) + 356698 [2982754][E](Custom_C): 01 27 07 <-Power Tab Data + 356699 [2982759][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356700 [2982781][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | | | | | | | | | | | | 231 | | | | | | | | | | + 356701 [2982813][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | 214 | 215 | 216 | 218 | 221 | 224 | 225 | 226 | 227 | 230 | | | | | | | | | | + 356702 [2982836][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | | 201 | 208 | 214 | 217 | 219 | 221 | 223 | 224 | 225 | 226 | | | | | | | | | | + 356703 [2982868][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 193 | 200 | 206 | 211 | 216 | 218 | 220 | 222 | 223 | 224 | 225 | | | | | | | | | | + 356704 [2982889][E](Custom_C): 01 19 <-targetPosition + 356705 [2982903][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | | 199 | 203 | 208 | 213 | 214 | 215 | 216 | 220 | 223 | | | | | | | | | | | + 356706 [2982926][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 191 | 196 | 200 | 205 | 210 | 211 | 212 | 213 | 217 | 221 | | | | | | | | | | | + 356707 [2982948][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 184 | 185 | 193 | 197 | 202 | 207 | 208 | 209 | 212 | | | | | | | | | | | | | + 356708 [2982981][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 181 | | 190 | 194 | 199 | 204 | 205 | 207 | | | | | | | | | | | | | | + 356709 [2983002][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 187 | 191 | 196 | 201 | 203 | | | | | | | | | | | | | | | + 356710 [2983034][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | | | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 356711 [2983055][E](PTable): Power Table Reset + 356712 [2983066][E](ERG_Mode): Proportional: -168.000000, Integral: -10.200000, Derivative: 1.800000 + 356713 [2983323][E](PTable): Success! + 356714 [2983823][E](FTMS_SERVER): 05 ea 01 -> ERG Mode Target: 490 Current: 148 Incline: 111.559998 + 356715 [2983830][E](Custom_C): 01 28 <-targetWatts + 356716 [2983894][E](Custom_C): 01 19 <-targetPosition + 356717 [2984027][E](PTable): Success! + 356718 [2984028][E](PTable): Lookup debug 420 X1 540 X2 95 Y1 105 Y2 -28072604249918737284684465448095458887475461210034139779307480498072751368519832178646598033815134966602260023603819691482628334862885135092613463429611520 + 356719 [2984040][E](PTable): Lookup used neighbors L 161 R 164 R1 163 + 356720 [2984051][E](PTable): Lookup used neighbors U 170 D 166 R2 168 + 356721 [2984051][E](PTable): Lookup result: 490w 101cad 16400 + 356722 [2984063][E](ERG_Mode): SetPoint changed:490w PowerTable Result: 16400 + 356723 [2984064][E](ERG_Mode): Capping ERG seek time to 5 seconds + 356724 [2984074][E](PTable): Using detected travel limits during homing + 356725 [2984079][E](PTable): Success! + 356726 [2984784][E](PTable): Success! + 356727 [2984786][E](PTable): Clean Power Table + 356728 [2984786][E](PTable): Averaged Entry: watts=152.000000, cad=101.199997, targetPosition=1130.00000, (8)(5) + 356729 [2984798][E](PTable): Keep old targetPosition: (113.000000) + 356730 [2984798][E](PTable): Right failed at: (113) Target pos: (113.000000) Avg pos: (113) + 356731 [2984809][E](PTable): Was not in range failed right (8)(6)(113), readings (8) + 356732 [2984809][E](PTable): WEIGHTED DOWNVOTING: Target Value: (113), NeighborValue: (113) + 356733 [2984820][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 356734 [2984830][E](PTable): PT failed (8)(6)(113), readings (8) + 356735 [2984831][E](PTable): Top failed at: (105) Target pos: (113.000000) Avg pos: (109) + 356736 [2984842][E](PTable): All test failed top (7)(5)(105), readings (11) + 356737 [2984842][E](PTable): WEIGHTED DOWNVOTING: Target Value: (113), NeighborValue: (105) + 356738 [2984853][E](PTable): WEIGHTED DOWNVOTING: Delta: (8), Penalty: (1) + 356739 [2984863][E](PTable): PT failed (7)(5)(105), readings (10) + 356740 [2984865][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356741 [2984897][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356742 [2984939][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356743 [2984963][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356744 [2984986][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356745 [2985018][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356746 [2985040][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 356747 [2985072][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 356748 [2985094][E](PTable): 95 rpm | | | | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356749 [2985126][E](PTable): 100 rpm | | | 72 | | 100 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 356750 [2985148][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356751 [2985179][E](PTable): Power Table Reset + 356752 [2985689][E](PTable): Success! + 356753 [2985896][E](Custom_C): 01 2a <-hMin + 356754 [2985952][E](Custom_C): 01 19 <-targetPosition + 356755 [2985986][E](Custom_C): 01 2b <-hMax + 356756 [2986055][E](Custom_C): 01 25 <-Firmware Version + 356757 [2986390][E](PTable): Success! + 356758 [2986887][E](Custom_C): 01 19 <-targetPosition + 356759 [2987092][E](PTable): Power Table Reset + 356760 [2987899][E](Custom_C): 01 19 <-targetPosition + 356761 [2988505][E](ERG_Mode): Proportional: -328.000000, Integral: -4.600000, Derivative: -5.800000 + 356762 [2988889][E](Custom_C): 01 19 <-targetPosition + 356763 [2989879][E](Custom_C): 01 19 <-targetPosition + 356764 [2990904][E](Custom_C): 01 27 00 <-Power Tab Data + 356765 [2990959][E](Custom_C): 01 2a <-hMin + 356766 [2991004][E](Custom_C): 01 19 <-targetPosition + 356767 [2991106][E](Custom_C): 01 27 01 <-Power Tab Data + 356768 [2991162][E](Custom_C): 01 2b <-hMax + 356769 [2991218][E](Custom_C): 01 27 02 <-Power Tab Data + 356770 [2991286][E](Custom_C): 01 27 03 <-Power Tab Data + 356771 [2991333][E](Custom_C): 01 27 04 <-Power Tab Data + 356772 [2991378][E](Custom_C): 01 27 05 <-Power Tab Data + 356773 [2991421][E](Custom_C): 01 27 06 <-Power Tab Data + 356774 [2991488][E](Custom_C): 01 27 07 <-Power Tab Data + 356775 [2991533][E](Custom_C): 01 27 08 <-Power Tab Data + 356776 [2991578][E](Custom_C): 01 27 09 <-Power Tab Data + 356777 [2991905][E](Custom_C): 01 19 <-targetPosition + 356778 [2992894][E](Custom_C): 01 19 <-targetPosition + 356779 [2993885][E](Custom_C): 01 19 <-targetPosition + 356780 [2994128][E](ERG_Mode): Proportional: 176.000000, Integral: -1.200000, Derivative: 4.000000 + 356781 [2994896][E](Custom_C): 01 19 <-targetPosition + 356782 [2995887][E](Custom_C): 01 2a <-hMin + 356783 [2995931][E](Custom_C): 01 19 <-targetPosition + 356784 [2995976][E](Custom_C): 01 2b <-hMax + 356785 [2996899][E](Custom_C): 01 19 <-targetPosition + 356786 [2997912][E](Custom_C): 01 19 <-targetPosition + 356787 [2998645][E](FTMS_SERVER): 05 82 00 -> ERG Mode Target: 130 Current: 512 Incline: 157.804001 + 356788 [2998654][E](Custom_C): 01 28 <-targetWatts + 356789 [2998878][E](Custom_C): 01 19 <-targetPosition + 356790 [2999052][E](PTable): Lookup Extrapolated 93 from 100, 132, for 130w 109cad + 356791 [2999053][E](ERG_Mode): SetPoint changed:130w PowerTable Result: 9300 + 356792 [2999064][E](ERG_Mode): Capping ERG seek time to 5 seconds + 356793 [2999771][E](ERG_Mode): Proportional: -1288.000000, Integral: -34.400002, Derivative: -30.000000 + 356794 [2999892][E](Custom_C): 01 19 <-targetPosition + 356795 [3000472][E](PTable): Success! + 356796 [3000882][E](Custom_C): 01 2a <-hMin + 356797 [3000926][E](Custom_C): 01 19 <-targetPosition + 356798 [3000993][E](Custom_C): 01 2b <-hMax + 356799 [3001175][E](PTable): Success! + 356800 [3001881][E](PTable): Success! + 356801 [3001893][E](Custom_C): 01 19 <-targetPosition + 356802 [3002276][E](Custom_C): 01 25 <-Firmware Version + 356803 [3002582][E](PTable): Power Table Reset + 356804 [3002929][E](Custom_C): 01 19 <-targetPosition + 356805 [3003317][E](PTable): Success! + 356806 [3003896][E](Custom_C): 01 19 <-targetPosition + 356807 [3004020][E](PTable): Success! + 356808 [3004724][E](PTable): Success! + 356809 [3004886][E](Custom_C): 01 19 <-targetPosition + 356810 [3005427][E](PTable): Success! + 356811 [3005428][E](PTable): Clean Power Table + 356812 [3005429][E](PTable): Averaged Entry: watts=179.199997, cad=96.599998, targetPosition=1150.00000, (7)(6) + 356813 [3005440][E](PTable): cellValue: (114) wattDelta: (30.000000) cadDelta: (5.000000) allNeighborsPassed: (1) + 356814 [3005451][E](PTable): rightValue: (113.973335) leftValue: (114.026665) bottomValue: (114.320000) topValue: (113.680000) New averaged targetPosition: (114.000000) count: (4) + 356815 [3005463][E](PTable): Existing entry averaged (7)(6)(114), readings(4) + 356816 [3005834][E](Custom_C): 01 27 07 <-Power Tab Data + 356817 [3005838][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356818 [3005860][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | | | | | | | | | | | | 231 | | | | | | | | | | + 356819 [3005892][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | 214 | 215 | 216 | 218 | 221 | 224 | 225 | 226 | 227 | 230 | | | | | | | | | | + 356820 [3005914][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | | 201 | 208 | 214 | 217 | 219 | 221 | 223 | 224 | 225 | 226 | | | | | | | | | | + 356821 [3005982][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 193 | 200 | 206 | 211 | 216 | 218 | 220 | 222 | 223 | 224 | 225 | | | | | | | | | | + 356822 [3006004][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | | 199 | 203 | 208 | 213 | 214 | 215 | 216 | 220 | 223 | | | | | | | | | | | + 356823 [3006049][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 191 | 196 | 200 | 205 | 210 | 211 | 212 | 213 | 217 | 221 | | | | | | | | | | | + 356824 [3006072][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 184 | 185 | 193 | 197 | 202 | 207 | 208 | 209 | 212 | | | | | | | | | | | | | + 356825 [3006093][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 181 | | 190 | 194 | 199 | 204 | 205 | 207 | | | | | | | | | | | | | | + 356826 [3006137][E](PTable): 100 rpm | -12 | 11 | 72 | | 100 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 187 | 191 | 196 | 201 | 203 | | | | | | | | | | | | | | | + 356827 [3006159][E](PTable): 105 rpm | -24 | 10 | 69 | 95 | 98 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | | | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 356828 [3006192][E](PTable): Power Table Reset + 356829 [3006228][E](ERG_Mode): Proportional: -24.000000, Integral: -6.600000, Derivative: 1.800000 + 356830 [3006248][E](PTable): Success! + 356831 [3006259][E](Custom_C): 01 2b <-hMax + 356832 [3006340][E](Custom_C): 01 27 02 <-Power Tab Data + 356833 [3006395][E](Custom_C): 01 27 03 <-Power Tab Data + 356834 [3006453][E](Custom_C): 01 27 04 <-Power Tab Data + 356835 [3006523][E](Custom_C): 01 27 05 <-Power Tab Data + 356836 [3006587][E](Custom_C): 01 27 06 <-Power Tab Data + 356837 [3006656][E](Custom_C): 01 27 07 <-Power Tab Data + 356838 [3006705][E](Custom_C): 01 27 08 <-Power Tab Data + 356839 [3006766][E](Custom_C): 01 27 09 <-Power Tab Data + 356840 [3006821][E](Custom_C): 01 25 <-Firmware Version + 356841 [3006888][E](Custom_C): 01 19 <-targetPosition + 356842 [3006953][E](PTable): Success! + 356843 [3007658][E](PTable): Success! + 356844 [3007901][E](Custom_C): 01 19 <-targetPosition + 356845 [3008287][E](BLE_Client): HRM battery updated 100 + 356846 [3008362][E](PTable): Success! + 356847 [3008363][E](PTable): Clean Power Table + 356848 [3008363][E](PTable): Averaged Entry: watts=122.400002, cad=93.000000, targetPosition=1130.00000, (7)(4) + 356849 [3008375][E](PTable): cellValue: (102) wattDelta: (2.727273) cadDelta: (0.454545) allNeighborsPassed: (0) + 356850 [3008386][E](PTable): rightValue: (0.000000) leftValue: (101.120003) bottomValue: (97.599998) topValue: (0.000000) New averaged targetPosition: (99.360001) count: (2) + 356851 [3008397][E](PTable): Bottom failed at: (100) Target pos: (99.360001) Avg pos: (99) + 356852 [3008407][E](PTable): Current Position moved down is valid! Current position: 99.360001 + 356853 [3008408][E](PTable): Existing entry averaged (8)(4)(99), readings(11) + 356854 [3008779][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356855 [3008801][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | | | | | | | | | | | | 231 | | | | | | | | | | + 356856 [3008832][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | 214 | 215 | 216 | 218 | 221 | 224 | 225 | 226 | 227 | 230 | | | | | | | | | | + 356857 [3008854][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | | 201 | 208 | 214 | 217 | 219 | 221 | 223 | 224 | 225 | 226 | | | | | | | | | | + 356858 [3008887][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 193 | 200 | 206 | 211 | 216 | 218 | 220 | 222 | 223 | 224 | 225 | | | | | | | | | | + 356859 [3008924][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | | 199 | 203 | 208 | 213 | 214 | 215 | 216 | 220 | 223 | | | | | | | | | | | + 356860 [3008948][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 191 | 196 | 200 | 205 | 210 | 211 | 212 | 213 | 217 | 221 | | | | | | | | | | | + 356861 [3008970][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 184 | 185 | 193 | 197 | 202 | 207 | 208 | 209 | 212 | | | | | | | | | | | | | + 356862 [3009002][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 181 | | 190 | 194 | 199 | 204 | 205 | 207 | | | | | | | | | | | | | | + 356863 [3009024][E](PTable): 100 rpm | -12 | 11 | 72 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 187 | 191 | 196 | 201 | 203 | | | | | | | | | | | | | | | + 356864 [3009056][E](PTable): 105 rpm | -24 | 10 | 69 | 93 | 96 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | | | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 356865 [3009077][E](PTable): Power Table Reset + 356866 [3009329][E](PTable): Success! + 356867 [3009881][E](Custom_C): 01 19 <-targetPosition + 356868 [3010031][E](PTable): Success! + 356869 [3010732][E](PTable): Success! + 356870 [3010916][E](Custom_C): 01 2a <-hMin + 356871 [3010961][E](Custom_C): 01 19 <-targetPosition + 356872 [3011006][E](Custom_C): 01 2b <-hMax + 356873 [3011434][E](PTable): Success! + 356874 [3011435][E](PTable): Clean Power Table + 356875 [3011435][E](PTable): Averaged Entry: watts=110.800003, cad=90.400002, targetPosition=1135.99998, (6)(4) + 356876 [3011447][E](PTable): cellValue: (103) wattDelta: (2.830189) cadDelta: (0.471698) allNeighborsPassed: (0) + 356877 [3011459][E](PTable): rightValue: (0.000000) leftValue: (106.250664) bottomValue: (103.848007) topValue: (0.000000) New averaged targetPosition: (105.049332) count: (2) + 356878 [3011470][E](PTable): Top failed at: (104) Target pos: (105.049332) Avg pos: (104) + 356879 [3011481][E](PTable): All test failed top (5)(4)(104), readings (11) + 356880 [3011481][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (104) + 356881 [3011492][E](PTable): WEIGHTED DOWNVOTING: Delta: (1), Penalty: (0) + 356882 [3011492][E](PTable): PT failed (5)(4)(104), readings (11) + 356883 [3011507][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356884 [3011530][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356885 [3011552][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356886 [3011584][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356887 [3011608][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356888 [3011640][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356889 [3011663][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 356890 [3011695][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 356891 [3011717][E](PTable): 95 rpm | | | | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356892 [3011749][E](PTable): 100 rpm | | | 72 | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 356893 [3011770][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356894 [3011802][E](PTable): Power Table Reset + 356895 [3011802][E](ERG_Mode): Proportional: 112.000000, Integral: 1.800000, Derivative: 3.200000 + 356896 [3011884][E](Custom_C): 01 19 <-targetPosition + 356897 [3012138][E](PTable): Success! + 356898 [3012841][E](PTable): Success! + 356899 [3012896][E](Custom_C): 01 19 <-targetPosition + 356900 [3013546][E](PTable): Success! + 356901 [3013887][E](Custom_C): 01 19 <-targetPosition + 356902 [3014247][E](PTable): Success! + 356903 [3014248][E](PTable): Clean Power Table + 356904 [3014248][E](PTable): Averaged Entry: watts=106.000000, cad=86.000000, targetPosition=1155.99998, (5)(4) + 356905 [3014260][E](PTable): cellValue: (104) wattDelta: (2.586207) cadDelta: (0.431035) allNeighborsPassed: (0) + 356906 [3014272][E](PTable): rightValue: (0.000000) leftValue: (109.413330) bottomValue: (106.320000) topValue: (0.000000) New averaged targetPosition: (107.866669) count: (2) + 356907 [3014283][E](PTable): Top failed at: (105) Target pos: (107.866669) Avg pos: (106) + 356908 [3014284][E](PTable): All test failed top (4)(4)(105), readings (11) + 356909 [3014295][E](PTable): WEIGHTED DOWNVOTING: Target Value: (107), NeighborValue: (105) + 356910 [3014305][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 356911 [3014305][E](PTable): PT failed (4)(4)(105), readings (11) + 356912 [3014318][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356913 [3014340][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356914 [3014373][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356915 [3014395][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356916 [3014427][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356917 [3014448][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356918 [3014481][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 356919 [3014502][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 356920 [3014534][E](PTable): 95 rpm | | | | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356921 [3014556][E](PTable): 100 rpm | | | 72 | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 356922 [3014588][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356923 [3014609][E](PTable): Power Table Reset + 356924 [3014922][E](Custom_C): 01 19 <-targetPosition + 356925 [3014950][E](PTable): Success! + 356926 [3015655][E](PTable): Success! + 356927 [3015889][E](Custom_C): 01 2a <-hMin + 356928 [3015957][E](Custom_C): 01 19 <-targetPosition + 356929 [3016001][E](Custom_C): 01 2b <-hMax + 356930 [3016359][E](PTable): Success! + 356931 [3016879][E](Custom_C): 01 19 <-targetPosition + 356932 [3017060][E](PTable): Success! + 356933 [3017061][E](PTable): Clean Power Table + 356934 [3017061][E](PTable): Averaged Entry: watts=111.199997, cad=83.199997, targetPosition=1184.00002, (5)(4) + 356935 [3017075][E](PTable): cellValue: (104) wattDelta: (2.083333) cadDelta: (0.347222) allNeighborsPassed: (0) + 356936 [3017076][E](PTable): rightValue: (0.000000) leftValue: (108.223999) bottomValue: (98.815994) topValue: (0.000000) New averaged targetPosition: (103.519997) count: (2) + 356937 [3017097][E](PTable): Bottom failed at: (103) Target pos: (103.519997) Avg pos: (103) + 356938 [3017099][E](PTable): Was not in range failed bottom (6)(4)(103), readings (8) + 356939 [3017109][E](PTable): WEIGHTED DOWNVOTING: Target Value: (103), NeighborValue: (103) + 356940 [3017120][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 356941 [3017120][E](PTable): PT failed (6)(4)(103), readings (8) + 356942 [3017132][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356943 [3017154][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356944 [3017186][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356945 [3017207][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356946 [3017240][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356947 [3017262][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356948 [3017294][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 356949 [3017316][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 356950 [3017348][E](PTable): 95 rpm | | | | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 356951 [3017370][E](PTable): 100 rpm | | | 72 | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 356952 [3017401][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 356953 [3017422][E](PTable): Power Table Reset + 356954 [3017433][E](ERG_Mode): Proportional: 40.000000, Integral: 7.000000, Derivative: -1.800000 + 356955 [3017764][E](PTable): Success! + 356956 [3017891][E](Custom_C): 01 19 <-targetPosition + 356957 [3018468][E](PTable): Success! + 356958 [3018904][E](Custom_C): 01 19 <-targetPosition + 356959 [3019197][E](PTable): Success! + 356960 [3019197][E](PTable): Using detected travel limits during homing + 356961 [3019895][E](Custom_C): 01 19 <-targetPosition + 356962 [3019898][E](PTable): Success! + 356963 [3019899][E](PTable): Clean Power Table + 356964 [3019899][E](PTable): Averaged Entry: watts=146.000000, cad=81.800003, targetPosition=1194.00002, (4)(5) + 356965 [3019913][E](PTable): cellValue: (118) wattDelta: (21.428549) cadDelta: (3.571425) allNeighborsPassed: (1) + 356966 [3019915][E](PTable): rightValue: (117.813332) leftValue: (118.186668) bottomValue: (118.503998) topValue: (117.496002) New averaged targetPosition: (118.000000) count: (4) + 356967 [3019937][E](PTable): Existing entry averaged (4)(5)(118), readings(11) + 356968 [3020312][E](Custom_C): 01 27 04 <-Power Tab Data + 356969 [3020318][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 356970 [3020340][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | | | | | | | | | | | | 231 | | | | | | | | | | + 356971 [3020372][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | 214 | 215 | 216 | 218 | 221 | 224 | 225 | 226 | 227 | 230 | | | | | | | | | | + 356972 [3020393][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | | 201 | 208 | 214 | 217 | 219 | 221 | 223 | 224 | 225 | 226 | | | | | | | | | | + 356973 [3020426][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 193 | 200 | 206 | 211 | 216 | 218 | 220 | 222 | 223 | 224 | 225 | | | | | | | | | | + 356974 [3020447][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | | 199 | 203 | 208 | 213 | 214 | 215 | 216 | 220 | 223 | | | | | | | | | | | + 356975 [3020479][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 191 | 196 | 200 | 205 | 210 | 211 | 212 | 213 | 217 | 221 | | | | | | | | | | | + 356976 [3020501][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 184 | 185 | 193 | 197 | 202 | 207 | 208 | 209 | 212 | | | | | | | | | | | | | + 356977 [3020533][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 181 | | 190 | 194 | 199 | 204 | 205 | 207 | | | | | | | | | | | | | | + 356978 [3020555][E](PTable): 100 rpm | -12 | 11 | 72 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 187 | 191 | 196 | 201 | 203 | | | | | | | | | | | | | | | + 356979 [3020588][E](PTable): 105 rpm | -24 | 10 | 69 | 93 | 96 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | | | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 356980 [3020608][E](PTable): Power Table Reset + 356981 [3020856][E](PTable): Success! + 356982 [3020897][E](Custom_C): 01 27 00 <-Power Tab Data + 356983 [3020951][E](Custom_C): 01 2a <-hMin + 356984 [3020996][E](Custom_C): 01 19 <-targetPosition + 356985 [3021077][E](Custom_C): 01 27 01 <-Power Tab Data + 356986 [3021108][E](Custom_C): 01 2b <-hMax + 356987 [3021189][E](Custom_C): 01 27 02 <-Power Tab Data + 356988 [3021234][E](Custom_C): 01 27 03 <-Power Tab Data + 356989 [3021278][E](Custom_C): 01 27 04 <-Power Tab Data + 356990 [3021323][E](Custom_C): 01 27 05 <-Power Tab Data + 356991 [3021391][E](Custom_C): 01 27 06 <-Power Tab Data + 356992 [3021435][E](Custom_C): 01 27 07 <-Power Tab Data + 356993 [3021480][E](Custom_C): 01 27 08 <-Power Tab Data + 356994 [3021525][E](Custom_C): 01 27 09 <-Power Tab Data + 356995 [3021561][E](PTable): Success! + 356996 [3021897][E](Custom_C): 01 19 <-targetPosition + 356997 [3022262][E](PTable): Success! + 356998 [3022278][E](Custom_C): 01 25 <-Firmware Version + 356999 [3022886][E](Custom_C): 01 19 <-targetPosition + 357000 [3022965][E](PTable): Success! + 357001 [3022967][E](PTable): Clean Power Table + 357002 [3022967][E](PTable): Averaged Entry: watts=130.800003, cad=83.000000, targetPosition=1180.00000, (5)(4) + 357003 [3022978][E](PTable): cellValue: (104) wattDelta: (2.142857) cadDelta: (0.357143) allNeighborsPassed: (0) + 357004 [3022989][E](PTable): rightValue: (0.000000) leftValue: (98.959999) bottomValue: (98.400002) topValue: (0.000000) New averaged targetPosition: (98.680000) count: (2) + 357005 [3023000][E](PTable): Bottom failed at: (103) Target pos: (98.680000) Avg pos: (100) + 357006 [3023011][E](PTable): All test failed bottom (4)(4)(105), readings (11) + 357007 [3023012][E](PTable): WEIGHTED DOWNVOTING: Target Value: (98), NeighborValue: (103) + 357008 [3023022][E](PTable): WEIGHTED DOWNVOTING: Delta: (5), Penalty: (1) + 357009 [3023022][E](PTable): PT failed (6)(4)(103), readings (7) + 357010 [3023034][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357011 [3023056][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357012 [3023088][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357013 [3023110][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357014 [3023141][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357015 [3023163][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357016 [3023195][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 357017 [3023217][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 357018 [3023249][E](PTable): 95 rpm | | | | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357019 [3023271][E](PTable): 100 rpm | | | 72 | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 357020 [3023304][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357021 [3023325][E](PTable): Power Table Reset + 357022 [3023668][E](PTable): Success! + 357023 [3023669][E](ERG_Mode): Proportional: 56.000000, Integral: 2.400000, Derivative: 0.200000 + 357024 [3023899][E](Custom_C): 01 19 <-targetPosition + 357025 [3024370][E](PTable): Success! + 357026 [3024889][E](Custom_C): 01 19 <-targetPosition + 357027 [3025074][E](PTable): Success! + 357028 [3025779][E](PTable): Success! + 357029 [3025780][E](PTable): Clean Power Table + 357030 [3025780][E](PTable): Averaged Entry: watts=113.599998, cad=80.800003, targetPosition=1194.00002, (4)(4) + 357031 [3025792][E](PTable): cellValue: (105) wattDelta: (2.083333) cadDelta: (0.347222) allNeighborsPassed: (0) + 357032 [3025803][E](PTable): rightValue: (0.000000) leftValue: (108.071999) bottomValue: (107.304008) topValue: (0.000000) New averaged targetPosition: (107.688004) count: (2) + 357033 [3025814][E](PTable): Top failed at: (106) Target pos: (107.688004) Avg pos: (106) + 357034 [3025825][E](PTable): Current Position moved up was valid! Current position: 107.688004 + 357035 [3025825][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 357036 [3025901][E](Custom_C): 01 2a <-hMin + 357037 [3025947][E](Custom_C): 01 19 <-targetPosition + 357038 [3025991][E](Custom_C): 01 2b <-hMax + 357039 [3026036][E](Custom_C): 01 25 <-Firmware Version + 357040 [3026230][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357041 [3026252][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | | | | | | | | | | | | 231 | | | | | | | | | | + 357042 [3026284][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | 214 | 215 | 216 | 218 | 221 | 224 | 225 | 226 | 227 | 230 | | | | | | | | | | + 357043 [3026306][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | | 201 | 208 | 214 | 217 | 219 | 221 | 223 | 224 | 225 | 226 | | | | | | | | | | + 357044 [3026338][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 193 | 200 | 206 | 211 | 216 | 218 | 220 | 222 | 223 | 224 | 225 | | | | | | | | | | + 357045 [3026360][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | | 199 | 203 | 208 | 213 | 214 | 215 | 216 | 220 | 223 | | | | | | | | | | | + 357046 [3026393][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 191 | 196 | 200 | 205 | 210 | 211 | 212 | 213 | 217 | 221 | | | | | | | | | | | + 357047 [3026414][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 184 | 185 | 193 | 197 | 202 | 207 | 208 | 209 | 212 | | | | | | | | | | | | | + 357048 [3026446][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 181 | | 190 | 194 | 199 | 204 | 205 | 207 | | | | | | | | | | | | | | + 357049 [3026468][E](PTable): 100 rpm | -12 | 11 | 72 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 187 | 191 | 196 | 201 | 203 | | | | | | | | | | | | | | | + 357050 [3026500][E](PTable): 105 rpm | -24 | 10 | 69 | 93 | 96 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | | | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 357051 [3026521][E](PTable): Power Table Reset + 357052 [3026538][E](PTable): Success! + 357053 [3026914][E](Custom_C): 01 19 <-targetPosition + 357054 [3027243][E](PTable): Success! + 357055 [3027886][E](Custom_C): 01 19 <-targetPosition + 357056 [3027945][E](PTable): Success! + 357057 [3028647][E](PTable): Success! + 357058 [3028648][E](PTable): Clean Power Table + 357059 [3028648][E](PTable): Averaged Entry: watts=122.800003, cad=80.199997, targetPosition=1204.00002, (4)(4) + 357060 [3028661][E](PTable): cellValue: (105) wattDelta: (1.948052) cadDelta: (0.324675) allNeighborsPassed: (0) + 357061 [3028671][E](PTable): rightValue: (0.000000) leftValue: (103.562668) bottomValue: (105.615990) topValue: (0.000000) New averaged targetPosition: (104.589325) count: (2) + 357062 [3028683][E](PTable): Bottom failed at: (104) Target pos: (104.589325) Avg pos: (104) + 357063 [3028693][E](PTable): Was not in range failed bottom (5)(4)(104), readings (11) + 357064 [3028694][E](PTable): WEIGHTED DOWNVOTING: Target Value: (104), NeighborValue: (104) + 357065 [3028704][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 357066 [3028715][E](PTable): PT failed (5)(4)(104), readings (11) + 357067 [3028718][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357068 [3028739][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357069 [3028771][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357070 [3028793][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357071 [3028825][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357072 [3028847][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357073 [3028879][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 357074 [3028900][E](Custom_C): 01 19 <-targetPosition + 357075 [3028917][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 357076 [3028939][E](PTable): 95 rpm | | | | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357077 [3028971][E](PTable): 100 rpm | | | 72 | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 357078 [3028993][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357079 [3029016][E](PTable): Power Table Reset + 357080 [3029027][E](ERG_Mode): Proportional: 16.000000, Integral: 6.400000, Derivative: 0.000000 + 357081 [3029350][E](PTable): Success! + 357082 [3029883][E](Custom_C): 01 19 <-targetPosition + 357083 [3030055][E](PTable): Success! + 357084 [3030759][E](PTable): Success! + 357085 [3030907][E](Custom_C): 01 2a <-hMin + 357086 [3030941][E](Custom_C): 01 19 <-targetPosition + 357087 [3030986][E](Custom_C): 01 2b <-hMax + 357088 [3031462][E](PTable): Success! + 357089 [3031463][E](PTable): Clean Power Table + 357090 [3031463][E](PTable): Averaged Entry: watts=121.599998, cad=81.599998, targetPosition=1210.00000, (4)(4) + 357091 [3031475][E](PTable): cellValue: (105) wattDelta: (1.875000) cadDelta: (0.312500) allNeighborsPassed: (0) + 357092 [3031487][E](PTable): rightValue: (0.000000) leftValue: (104.146667) bottomValue: (110.119995) topValue: (0.000000) New averaged targetPosition: (107.133331) count: (2) + 357093 [3031498][E](PTable): Top failed at: (106) Target pos: (107.133331) Avg pos: (106) + 357094 [3031508][E](PTable): Current Position moved up was valid! Current position: 107.133331 + 357095 [3031509][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 357096 [3031883][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357097 [3031928][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | | | | | | | | | | | | 231 | | | | | | | | | | + 357098 [3031950][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | 213 | | | | | 214 | 215 | 216 | 218 | 221 | 224 | 225 | 226 | 227 | 230 | | | | | | | | | | + 357099 [3031982][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | 199 | | | | | 201 | 208 | 214 | 217 | 219 | 221 | 223 | 224 | 225 | 226 | | | | | | | | | | + 357100 [3032004][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | 186 | 187 | 188 | 189 | 193 | 200 | 206 | 211 | 216 | 218 | 220 | 222 | 223 | 224 | 225 | | | | | | | | | | + 357101 [3032036][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 178 | 181 | 185 | | | 199 | 203 | 208 | 213 | 214 | 215 | 216 | 220 | 223 | | | | | | | | | | | + 357102 [3032057][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 182 | 188 | 191 | 196 | 200 | 205 | 210 | 211 | 212 | 213 | 217 | 221 | | | | | | | | | | | + 357103 [3032090][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 184 | 185 | 193 | 197 | 202 | 207 | 208 | 209 | 212 | | | | | | | | | | | | | + 357104 [3032112][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 166 | 170 | 176 | 181 | | 190 | 194 | 199 | 204 | 205 | 207 | | | | | | | | | | | | | | + 357105 [3032144][E](PTable): 100 rpm | -12 | 11 | 72 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 187 | 191 | 196 | 201 | 203 | | | | | | | | | | | | | | | + 357106 [3032165][E](PTable): 105 rpm | -24 | 10 | 69 | 93 | 96 | 103 | 107 | 114 | 122 | 138 | 139 | 143 | 148 | 152 | 157 | 161 | 166 | 170 | | | 184 | 188 | 193 | 197 | 202 | 206 | 211 | 215 | 220 | 224 | | | | | | | | | | + 357107 [3032196][E](PTable): Power Table Reset + 357108 [3032213][E](PTable): Success! + 357109 [3032900][E](Custom_C): 01 19 <-targetPosition + 357110 [3032918][E](PTable): Success! + 357111 [3033619][E](PTable): Success! + 357112 [3033888][E](Custom_C): 01 19 <-targetPosition + 357113 [3034320][E](PTable): Success! + 357114 [3034321][E](PTable): Clean Power Table + 357115 [3034321][E](PTable): Averaged Entry: watts=122.000000, cad=81.000000, targetPosition=1215.99998, (4)(4) + 357116 [3034333][E](PTable): cellValue: (105) wattDelta: (1.807229) cadDelta: (0.301205) allNeighborsPassed: (0) + 357117 [3034344][E](PTable): rightValue: (0.000000) leftValue: (103.893333) bottomValue: (108.320000) topValue: (0.000000) New averaged targetPosition: (106.106667) count: (2) + 357118 [3034355][E](PTable): Top failed at: (106) Target pos: (106.106667) Avg pos: (106) + 357119 [3034366][E](PTable): Was not in range failed top (3)(4)(106), readings (11) + 357120 [3034366][E](PTable): WEIGHTED DOWNVOTING: Target Value: (106), NeighborValue: (106) + 357121 [3034377][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 357122 [3034377][E](PTable): PT failed (3)(4)(106), readings (11) + 357123 [3034390][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357124 [3034412][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357125 [3034444][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357126 [3034465][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357127 [3034498][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357128 [3034519][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357129 [3034551][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 357130 [3034574][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 357131 [3034606][E](PTable): 95 rpm | | | | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357132 [3034628][E](PTable): 100 rpm | | | 72 | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 357133 [3034660][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357134 [3034680][E](PTable): Power Table Reset + 357135 [3034691][E](ERG_Mode): Proportional: -8.000000, Integral: 5.800000, Derivative: -0.800000 + 357136 [3034901][E](Custom_C): 01 19 <-targetPosition + 357137 [3035022][E](PTable): Success! + 357138 [3035724][E](PTable): Success! + 357139 [3035929][E](Custom_C): 01 27 00 <-Power Tab Data + 357140 [3035960][E](Custom_C): 01 2a <-hMin + 357141 [3036027][E](Custom_C): 01 19 <-targetPosition + 357142 [3036083][E](Custom_C): 01 27 01 <-Power Tab Data + 357143 [3036139][E](Custom_C): 01 2b <-hMax + 357144 [3036218][E](Custom_C): 01 27 02 <-Power Tab Data + 357145 [3036263][E](Custom_C): 01 27 03 <-Power Tab Data + 357146 [3036309][E](Custom_C): 01 27 04 <-Power Tab Data + 357147 [3036353][E](Custom_C): 01 27 05 <-Power Tab Data + 357148 [3036421][E](Custom_C): 01 27 06 <-Power Tab Data + 357149 [3036430][E](PTable): Success! + 357150 [3036465][E](Custom_C): 01 27 07 <-Power Tab Data + 357151 [3036512][E](Custom_C): 01 27 08 <-Power Tab Data + 357152 [3036556][E](Custom_C): 01 27 09 <-Power Tab Data + 357153 [3036881][E](Custom_C): 01 19 <-targetPosition + 357154 [3037133][E](PTable): Success! + 357155 [3037134][E](PTable): Clean Power Table + 357156 [3037134][E](PTable): Averaged Entry: watts=126.000000, cad=80.400002, targetPosition=1224.00002, (4)(4) + 357157 [3037146][E](PTable): cellValue: (105) wattDelta: (1.724138) cadDelta: (0.287356) allNeighborsPassed: (0) + 357158 [3037148][E](PTable): rightValue: (0.000000) leftValue: (101.520004) bottomValue: (106.392006) topValue: (0.000000) New averaged targetPosition: (103.956009) count: (2) + 357159 [3037169][E](PTable): Bottom failed at: (104) Target pos: (103.956009) Avg pos: (103) + 357160 [3037180][E](PTable): All test failed bottom (3)(4)(106), readings (11) + 357161 [3037180][E](PTable): WEIGHTED DOWNVOTING: Target Value: (103), NeighborValue: (104) + 357162 [3037190][E](PTable): WEIGHTED DOWNVOTING: Delta: (1), Penalty: (0) + 357163 [3037190][E](PTable): PT failed (5)(4)(104), readings (11) + 357164 [3037204][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357165 [3037227][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357166 [3037259][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357167 [3037281][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357168 [3037305][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357169 [3037337][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357170 [3037359][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 357171 [3037391][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 357172 [3037413][E](PTable): 95 rpm | | | | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357173 [3037445][E](PTable): 100 rpm | | | 72 | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 357174 [3037466][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357175 [3037498][E](PTable): Power Table Reset + 357176 [3037834][E](PTable): Success! + 357177 [3037893][E](Custom_C): 01 19 <-targetPosition + 357178 [3038539][E](PTable): Success! + 357179 [3038884][E](Custom_C): 01 19 <-targetPosition + 357180 [3039243][E](PTable): Success! + 357181 [3039896][E](Custom_C): 01 19 <-targetPosition + 357182 [3039944][E](PTable): Success! + 357183 [3039945][E](PTable): Clean Power Table + 357184 [3039945][E](PTable): Averaged Entry: watts=128.800003, cad=80.199997, targetPosition=1230.00000, (4)(4) + 357185 [3039956][E](PTable): cellValue: (105) wattDelta: (1.666667) cadDelta: (0.277778) allNeighborsPassed: (0) + 357186 [3039967][E](PTable): rightValue: (0.000000) leftValue: (99.720001) bottomValue: (105.719986) topValue: (0.000000) New averaged targetPosition: (102.719994) count: (2) + 357187 [3039978][E](PTable): Bottom failed at: (104) Target pos: (102.719994) Avg pos: (103) + 357188 [3039990][E](PTable): All test failed bottom (3)(4)(106), readings (11) + 357189 [3039990][E](PTable): WEIGHTED DOWNVOTING: Target Value: (102), NeighborValue: (104) + 357190 [3040000][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 357191 [3040000][E](PTable): PT failed (5)(4)(104), readings (11) + 357192 [3040013][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357193 [3040035][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357194 [3040067][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357195 [3040089][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357196 [3040121][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357197 [3040142][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357198 [3040175][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 357199 [3040196][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 357200 [3040229][E](PTable): 95 rpm | | | | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357201 [3040250][E](PTable): 100 rpm | | | 72 | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 357202 [3040284][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357203 [3040305][E](PTable): Power Table Reset + 357204 [3040305][E](ERG_Mode): Proportional: -24.000000, Integral: 5.400000, Derivative: -1.200000 + 357205 [3040745][E](PTable): Success! + 357206 [3040887][E](Custom_C): 01 2a <-hMin + 357207 [3040931][E](Custom_C): 01 19 <-targetPosition + 357208 [3040976][E](Custom_C): 01 2b <-hMax + 357209 [3041448][E](PTable): Success! + 357210 [3041899][E](Custom_C): 01 19 <-targetPosition + 357211 [3042151][E](PTable): Success! + 357212 [3042281][E](Custom_C): 01 25 <-Firmware Version + 357213 [3042889][E](Custom_C): 01 19 <-targetPosition + 357214 [3043829][E](FTMS_SERVER): 05 ea 01 -> ERG Mode Target: 490 Current: 128 Incline: 106.660004 + 357215 [3043837][E](Custom_C): 01 28 <-targetWatts + 357216 [3043902][E](Custom_C): 01 19 <-targetPosition + 357217 [3044258][E](ERG_Mode): SetPoint changed:490w PowerTable Result: 12114 + 357218 [3044915][E](Custom_C): 01 19 <-targetPosition + 357219 [3045669][E](ERG_Mode): Proportional: 1304.000000, Integral: 38.600002, Derivative: -0.600000 + 357220 [3045881][E](Custom_C): 01 2a <-hMin + 357221 [3045949][E](Custom_C): 01 19 <-targetPosition + 357222 [3045993][E](Custom_C): 01 2b <-hMax + 357223 [3046063][E](Custom_C): 01 25 <-Firmware Version + 357224 [3046894][E](Custom_C): 01 19 <-targetPosition + 357225 [3047884][E](Custom_C): 01 19 <-targetPosition + 357226 [3048896][E](Custom_C): 01 19 <-targetPosition + 357227 [3049886][E](Custom_C): 01 19 <-targetPosition + 357228 [3050900][E](Custom_C): 01 27 00 <-Power Tab Data + 357229 [3050944][E](Custom_C): 01 2a <-hMin + 357230 [3050991][E](Custom_C): 01 19 <-targetPosition + 357231 [3051080][E](Custom_C): 01 27 01 <-Power Tab Data + 357232 [3051124][E](Custom_C): 01 2b <-hMax + 357233 [3051204][E](Custom_C): 01 27 02 <-Power Tab Data + 357234 [3051271][E](Custom_C): 01 27 03 <-Power Tab Data + 357235 [3051316][E](Custom_C): 01 27 04 <-Power Tab Data + 357236 [3051361][E](Custom_C): 01 27 05 <-Power Tab Data + 357237 [3051395][E](Custom_C): 01 27 06 <-Power Tab Data + 357238 [3051443][E](Custom_C): 01 27 07 <-Power Tab Data + 357239 [3051485][E](Custom_C): 01 27 08 <-Power Tab Data + 357240 [3051541][E](Custom_C): 01 27 09 <-Power Tab Data + 357241 [3051889][E](Custom_C): 01 19 <-targetPosition + 357242 [3052117][E](ERG_Mode): Proportional: -248.000000, Integral: -10.200000, Derivative: 3.800000 + 357243 [3052901][E](Custom_C): 01 19 <-targetPosition + 357244 [3053892][E](Custom_C): 01 19 <-targetPosition + 357245 [3054229][E](PTable): Power Table Reset + 357246 [3054881][E](Custom_C): 01 19 <-targetPosition + 357247 [3054930][E](PTable): Success! + 357248 [3054931][E](PTable): Using detected travel limits during homing + 357249 [3055634][E](PTable): Success! + 357250 [3055883][E](Custom_C): 01 2a <-hMin + 357251 [3055916][E](Custom_C): 01 19 <-targetPosition + 357252 [3055939][E](Custom_C): 01 2b <-hMax + 357253 [3056335][E](PTable): Success! + 357254 [3056884][E](Custom_C): 01 19 <-targetPosition + 357255 [3057037][E](PTable): Success! + 357256 [3057038][E](PTable): Clean Power Table + 357257 [3057038][E](PTable): Averaged Entry: watts=462.799988, cad=103.199997, targetPosition=1633.99994, (9)(15) + 357258 [3057050][E](PTable): Keep old targetPosition: (163.399994) + 357259 [3057050][E](PTable): New entry recorded (9)(15)(163) + 357260 [3057714][E](Custom_C): 01 27 09 <-Power Tab Data + 357261 [3057719][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357262 [3057741][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 357263 [3057773][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | | | | | | | 211 | 214 | | | | | 215 | 216 | 217 | | | | | | | | | | + 357264 [3057795][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | | | | | 200 | 203 | 207 | 210 | 211 | 212 | 213 | 215 | | | 216 | | | | | | | | | | + 357265 [3057827][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | | 190 | 191 | 194 | 197 | 200 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | | | | | | | | | | + 357266 [3057850][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | | 180 | 187 | 190 | 193 | 196 | 197 | | 198 | | 199 | 200 | | | 201 | | | | | | | | | | + 357267 [3057882][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 183 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 196 | 204 | | | | | | | | | | | + 357268 [3057903][E](Custom_C): 01 19 <-targetPosition + 357269 [3057915][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 181 | 183 | 185 | 187 | 188 | 189 | 190 | 192 | | | 201 | | | | | | | | | | | + 357270 [3057938][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 172 | | 175 | 178 | 179 | | 180 | 182 | | | | | 184 | 198 | | | | | | | | | | | + 357271 [3057969][E](PTable): 100 rpm | -12 | 11 | 72 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 170 | 171 | 172 | 190 | 192 | | 195 | | | | | | | | | | | + 357272 [3057992][E](PTable): 105 rpm | -24 | 10 | 69 | 93 | 96 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 158 | 163 | 165 | 167 | | | | | | | 168 | | | 181 | 192 | 197 | | | | | | | | | | + 357273 [3058023][E](PTable): Power Table Reset + 357274 [3058265][E](ERG_Mode): Proportional: -8.000000, Integral: 5.800000, Derivative: -0.200000 + 357275 [3058765][E](FTMS_SERVER): 05 82 00 -> ERG Mode Target: 130 Current: 492 Incline: 164.619995 + 357276 [3058774][E](Custom_C): 01 28 <-targetWatts + 357277 [3058886][E](Custom_C): 01 19 <-targetPosition + 357278 [3058971][E](PTable): Lookup Extrapolated 96 from 96, 132, for 130w 106cad + 357279 [3058972][E](ERG_Mode): SetPoint changed:130w PowerTable Result: 9600 + 357280 [3058982][E](ERG_Mode): Capping ERG seek time to 5 seconds + 357281 [3059691][E](PTable): Success! + 357282 [3059887][E](Custom_C): 01 19 <-targetPosition + 357283 [3060889][E](Custom_C): 01 2a <-hMin + 357284 [3060922][E](Custom_C): 01 19 <-targetPosition + 357285 [3060958][E](Custom_C): 01 2b <-hMax + 357286 [3061913][E](Custom_C): 01 19 <-targetPosition + 357287 [3062273][E](Custom_C): 01 25 <-Firmware Version + 357288 [3062890][E](Custom_C): 01 19 <-targetPosition + 357289 [3063892][E](Custom_C): 01 19 <-targetPosition + 357290 [3063910][E](PTable): Power Table Reset + 357291 [3063911][E](ERG_Mode): Proportional: -152.000000, Integral: -9.800000, Derivative: 1.600000 + 357292 [3064615][E](PTable): Success! + 357293 [3064883][E](Custom_C): 01 19 <-targetPosition + 357294 [3065317][E](PTable): Success! + 357295 [3065896][E](Custom_C): 01 27 00 <-Power Tab Data + 357296 [3065917][E](Custom_C): 01 2a <-hMin + 357297 [3065951][E](Custom_C): 01 19 <-targetPosition + 357298 [3065987][E](Custom_C): 01 27 01 <-Power Tab Data + 357299 [3066008][E](Custom_C): 01 2b <-hMax + 357300 [3066022][E](PTable): Success! + 357301 [3066053][E](Custom_C): 01 27 02 <-Power Tab Data + 357302 [3066122][E](Custom_C): 01 27 03 <-Power Tab Data + 357303 [3066156][E](Custom_C): 01 27 04 <-Power Tab Data + 357304 [3066222][E](Custom_C): 01 27 05 <-Power Tab Data + 357305 [3066256][E](Custom_C): 01 27 06 <-Power Tab Data + 357306 [3066290][E](Custom_C): 01 27 07 <-Power Tab Data + 357307 [3066334][E](Custom_C): 01 27 08 <-Power Tab Data + 357308 [3066393][E](Custom_C): 01 27 09 <-Power Tab Data + 357309 [3066447][E](Custom_C): 01 25 <-Firmware Version + 357310 [3066724][E](PTable): Success! + 357311 [3066725][E](PTable): Clean Power Table + 357312 [3066726][E](PTable): Averaged Entry: watts=140.399994, cad=98.199997, targetPosition=1158.00003, (8)(5) + 357313 [3066739][E](PTable): Keep old targetPosition: (115.800003) + 357314 [3066739][E](PTable): Right failed at: (113) Target pos: (115.800003) Avg pos: (114) + 357315 [3066750][E](PTable): All test failed right (8)(6)(113), readings (8) + 357316 [3066750][E](PTable): WEIGHTED DOWNVOTING: Target Value: (115), NeighborValue: (113) + 357317 [3066761][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 357318 [3066771][E](PTable): PT failed (8)(6)(113), readings (8) + 357319 [3066772][E](PTable): Top failed at: (105) Target pos: (115.800003) Avg pos: (110) + 357320 [3066783][E](PTable): All test failed top (7)(5)(105), readings (10) + 357321 [3066783][E](PTable): WEIGHTED DOWNVOTING: Target Value: (115), NeighborValue: (105) + 357322 [3066794][E](PTable): WEIGHTED DOWNVOTING: Delta: (10), Penalty: (2) + 357323 [3066794][E](PTable): PT failed (7)(5)(105), readings (8) + 357324 [3066806][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357325 [3066828][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357326 [3066861][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357327 [3066882][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357328 [3066934][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357329 [3066956][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357330 [3066978][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 357331 [3067011][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 357332 [3067032][E](PTable): 95 rpm | | | | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357333 [3067065][E](PTable): 100 rpm | | | 72 | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 357334 [3067087][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 357335 [3067118][E](PTable): Power Table Reset + 357336 [3067425][E](PTable): Success! + 357337 [3067886][E](Custom_C): 01 19 <-targetPosition + 357338 [3068133][E](PTable): Success! + 357339 [3068835][E](PTable): Success! + 357340 [3068888][E](Custom_C): 01 19 <-targetPosition + 357341 [3069538][E](PTable): Success! + 357342 [3069540][E](PTable): Clean Power Table + 357343 [3069540][E](PTable): Averaged Entry: watts=140.800003, cad=95.599998, targetPosition=1144.00002, (7)(5) + 357344 [3069551][E](PTable): cellValue: (105) wattDelta: (3.191489) cadDelta: (0.531915) allNeighborsPassed: (0) + 357345 [3069562][E](PTable): rightValue: (0.000000) leftValue: (107.882668) bottomValue: (106.127998) topValue: (0.000000) New averaged targetPosition: (107.005333) count: (2) + 357346 [3069573][E](PTable): Top failed at: (106) Target pos: (107.005333) Avg pos: (106) + 357347 [3069585][E](PTable): Current Position moved up was valid! Current position: 107.005333 + 357348 [3069585][E](PTable): Existing entry averaged (6)(5)(106), readings(11) + 357349 [3069888][E](Custom_C): 01 19 <-targetPosition + 357350 [3070240][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357351 [3070262][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 357352 [3070284][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | | | | | | | 211 | 214 | | | | | 215 | 216 | 217 | | | | | | | | | | + 357353 [3070316][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | | | | | 200 | 203 | 207 | 210 | 211 | 212 | 213 | 215 | | | 216 | | | | | | | | | | + 357354 [3070338][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | | 190 | 191 | 194 | 197 | 200 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | | | | | | | | | | + 357355 [3070371][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | | 180 | 187 | 190 | 193 | 196 | 197 | | 198 | | 199 | 200 | | | 201 | | | | | | | | | | + 357356 [3070393][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 183 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 196 | 204 | | | | | | | | | | | + 357357 [3070426][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 181 | 183 | 185 | 187 | 188 | 189 | 190 | 192 | | | 201 | | | | | | | | | | | + 357358 [3070448][E](PTable): 95 rpm | 0 | 12 | 76 | | 102 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 172 | | 175 | 178 | 179 | | 180 | 182 | | | | | 184 | 198 | | | | | | | | | | | + 357359 [3070481][E](PTable): 100 rpm | -12 | 11 | 72 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 170 | 171 | 172 | 190 | 192 | | 195 | | | | | | | | | | | + 357360 [3070503][E](PTable): 105 rpm | -24 | 10 | 69 | 93 | 96 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 158 | 163 | 165 | 167 | | | | | | | 168 | | | 181 | 192 | 197 | | | | | | | | | | + 357361 [3070534][E](PTable): Power Table Reset + 357362 [3070535][E](ERG_Mode): Proportional: -24.000000, Integral: -6.600000, Derivative: -0.600000 + 357363 [3070771][E](PTable): Success! + 357364 [3070946][E](Custom_C): 01 2a <-hMin + 357365 [3070968][E](Custom_C): 01 19 <-targetPosition + 357366 [3071036][E](Custom_C): 01 2b <-hMax + 357367 [3071473][E](PTable): Success! + 357368 [3071892][E](Custom_C): 01 19 <-targetPosition + 357369 [3072176][E](PTable): Success! + 357370 [3072884][E](Custom_C): 01 19 <-targetPosition + 357371 [3072889][E](PTable): Success! + 357372 [3072890][E](PTable): Clean Power Table + 357373 [3072891][E](PTable): Averaged Entry: watts=123.599998, cad=94.400002, targetPosition=1144.00002, (7)(4) + 357374 [3072903][E](PTable): cellValue: (102) wattDelta: (2.419354) cadDelta: (0.403226) allNeighborsPassed: (0) + 357375 [3072904][E](PTable): rightValue: (0.000000) leftValue: (100.512001) bottomValue: (100.512001) topValue: (0.000000) New averaged targetPosition: (100.512001) count: (2) + 357376 [3072925][E](PTable): Existing entry averaged (7)(4)(101), readings(8) + 357377 [3073622][E](Custom_C): 01 27 07 <-Power Tab Data + 357378 [3073628][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357379 [3073650][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 357380 [3073684][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | | | | | | | 211 | 214 | | | | | 215 | 216 | 217 | | | | | | | | | | + 357381 [3073707][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | | | | | 200 | 203 | 207 | 210 | 211 | 212 | 213 | 215 | | | 216 | | | | | | | | | | + 357382 [3073739][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | | 190 | 191 | 194 | 197 | 200 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | | | | | | | | | | + 357383 [3073761][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | | 180 | 187 | 190 | 193 | 196 | 197 | | 198 | | 199 | 200 | | | 201 | | | | | | | | | | + 357384 [3073793][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 183 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 196 | 204 | | | | | | | | | | | + 357385 [3073815][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 181 | 183 | 185 | 187 | 188 | 189 | 190 | 192 | | | 201 | | | | | | | | | | | + 357386 [3073847][E](PTable): 95 rpm | 0 | 12 | 76 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 172 | | 175 | 178 | 179 | | 180 | 182 | | | | | 184 | 198 | | | | | | | | | | | + 357387 [3073869][E](PTable): 100 rpm | -12 | 11 | 72 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 170 | 171 | 172 | 190 | 192 | | 195 | | | | | | | | | | | + 357388 [3073909][E](PTable): 105 rpm | -24 | 10 | 69 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 158 | 163 | 165 | 167 | | | | | | | 168 | | | 181 | 192 | 197 | | | | | | | | | | + 357389 [3073930][E](PTable): Power Table Reset + 357390 [3074149][E](PTable): Success! + 357391 [3074853][E](PTable): Success! + 357392 [3074884][E](Custom_C): 01 19 <-targetPosition + 357393 [3075556][E](PTable): Success! + 357394 [3075557][E](ERG_Mode): Proportional: 0.000000, Integral: -4.000000, Derivative: 0.200000 + 357395 [3075896][E](Custom_C): 01 2a <-hMin + 357396 [3075942][E](Custom_C): 01 19 <-targetPosition + 357397 [3075963][E](Custom_C): 01 2b <-hMax + 357398 [3076262][E](PTable): Success! + 357399 [3076263][E](PTable): Clean Power Table + 357400 [3076263][E](PTable): Averaged Entry: watts=129.199997, cad=92.000000, targetPosition=1150.00000, (6)(4) + 357401 [3076275][E](PTable): cellValue: (103) wattDelta: (2.500000) cadDelta: (0.416667) allNeighborsPassed: (0) + 357402 [3076286][E](PTable): rightValue: (0.000000) leftValue: (99.320000) bottomValue: (107.800003) topValue: (0.000000) New averaged targetPosition: (103.559998) count: (2) + 357403 [3076297][E](PTable): Existing entry averaged (6)(4)(103), readings(7) + 357404 [3076887][E](Custom_C): 01 19 <-targetPosition + 357405 [3076983][E](Custom_C): 01 27 06 <-Power Tab Data + 357406 [3076989][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357407 [3077010][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 357408 [3077043][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | | | | | | | 211 | 214 | | | | | 215 | 216 | 217 | | | | | | | | | | + 357409 [3077066][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | | | | | 200 | 203 | 207 | 210 | 211 | 212 | 213 | 215 | | | 216 | | | | | | | | | | + 357410 [3077099][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | | 190 | 191 | 194 | 197 | 200 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | | | | | | | | | | + 357411 [3077121][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | | 180 | 187 | 190 | 193 | 196 | 197 | | 198 | | 199 | 200 | | | 201 | | | | | | | | | | + 357412 [3077155][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 183 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 196 | 204 | | | | | | | | | | | + 357413 [3077177][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 181 | 183 | 185 | 187 | 188 | 189 | 190 | 192 | | | 201 | | | | | | | | | | | + 357414 [3077209][E](PTable): 95 rpm | 0 | 12 | 76 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 172 | | 175 | 178 | 179 | | 180 | 182 | | | | | 184 | 198 | | | | | | | | | | | + 357415 [3077230][E](PTable): 100 rpm | -12 | 11 | 72 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 170 | 171 | 172 | 190 | 192 | | 195 | | | | | | | | | | | + 357416 [3077263][E](PTable): 105 rpm | -24 | 10 | 69 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 158 | 163 | 165 | 167 | | | | | | | 168 | | | 181 | 192 | 197 | | | | | | | | | | + 357417 [3077284][E](PTable): Power Table Reset + 357418 [3077469][E](PTable): Success! + 357419 [3077887][E](Custom_C): 01 19 <-targetPosition + 357420 [3078173][E](PTable): Success! + 357421 [3078878][E](PTable): Success! + 357422 [3078911][E](Custom_C): 01 19 <-targetPosition + 357423 [3079581][E](PTable): Success! + 357424 [3079582][E](PTable): Clean Power Table + 357425 [3079582][E](PTable): Averaged Entry: watts=126.400002, cad=91.199997, targetPosition=1150.00000, (6)(4) + 357426 [3079596][E](PTable): cellValue: (103) wattDelta: (2.500000) cadDelta: (0.416667) allNeighborsPassed: (0) + 357427 [3079597][E](PTable): rightValue: (0.000000) leftValue: (100.440002) bottomValue: (105.879990) topValue: (0.000000) New averaged targetPosition: (103.159996) count: (2) + 357428 [3079618][E](PTable): Existing entry averaged (6)(4)(103), readings(8) + 357429 [3079878][E](Custom_C): 01 19 <-targetPosition + 357430 [3080280][E](Custom_C): 01 27 06 <-Power Tab Data + 357431 [3080286][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357432 [3080308][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 357433 [3080340][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | | | | | | | 211 | 214 | | | | | 215 | 216 | 217 | | | | | | | | | | + 357434 [3080362][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | | | | | 200 | 203 | 207 | 210 | 211 | 212 | 213 | 215 | | | 216 | | | | | | | | | | + 357435 [3080394][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | | 190 | 191 | 194 | 197 | 200 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | | | | | | | | | | + 357436 [3080417][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | | 180 | 187 | 190 | 193 | 196 | 197 | | 198 | | 199 | 200 | | | 201 | | | | | | | | | | + 357437 [3080449][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 183 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 196 | 204 | | | | | | | | | | | + 357438 [3080470][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 181 | 183 | 185 | 187 | 188 | 189 | 190 | 192 | | | 201 | | | | | | | | | | | + 357439 [3080502][E](PTable): 95 rpm | 0 | 12 | 76 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 172 | | 175 | 178 | 179 | | 180 | 182 | | | | | 184 | 198 | | | | | | | | | | | + 357440 [3080526][E](PTable): 100 rpm | -12 | 11 | 72 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 170 | 171 | 172 | 190 | 192 | | 195 | | | | | | | | | | | + 357441 [3080548][E](PTable): 105 rpm | -24 | 10 | 69 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 158 | 163 | 165 | 167 | | | | | | | 168 | | | 181 | 192 | 197 | | | | | | | | | | + 357442 [3080579][E](PTable): Power Table Reset + 357443 [3080580][E](ERG_Mode): Proportional: 16.000000, Integral: -1.200000, Derivative: -1.000000 + 357444 [3080811][E](PTable): Success! + 357445 [3080905][E](Custom_C): 01 27 00 <-Power Tab Data + 357446 [3080959][E](Custom_C): 01 2a <-hMin + 357447 [3080993][E](Custom_C): 01 19 <-targetPosition + 357448 [3081042][E](Custom_C): 01 27 01 <-Power Tab Data + 357449 [3081082][E](Custom_C): 01 2b <-hMax + 357450 [3081130][E](Custom_C): 01 27 02 <-Power Tab Data + 357451 [3081196][E](Custom_C): 01 27 03 <-Power Tab Data + 357452 [3081229][E](Custom_C): 01 27 04 <-Power Tab Data + 357453 [3081275][E](Custom_C): 01 27 05 <-Power Tab Data + 357454 [3081319][E](Custom_C): 01 27 06 <-Power Tab Data + 357455 [3081375][E](Custom_C): 01 27 07 <-Power Tab Data + 357456 [3081409][E](Custom_C): 01 27 08 <-Power Tab Data + 357457 [3081466][E](Custom_C): 01 27 09 <-Power Tab Data + 357458 [3081515][E](PTable): Success! + 357459 [3081896][E](Custom_C): 01 19 <-targetPosition + 357460 [3082216][E](PTable): Success! + 357461 [3082286][E](Custom_C): 01 25 <-Firmware Version + 357462 [3082894][E](Custom_C): 01 19 <-targetPosition + 357463 [3082917][E](PTable): Success! + 357464 [3082918][E](PTable): Clean Power Table + 357465 [3082918][E](PTable): Averaged Entry: watts=114.400002, cad=88.199997, targetPosition=1155.99998, (6)(4) + 357466 [3082929][E](PTable): cellValue: (103) wattDelta: (2.380953) cadDelta: (0.396825) allNeighborsPassed: (0) + 357467 [3082940][E](PTable): rightValue: (0.000000) leftValue: (105.351997) bottomValue: (98.463989) topValue: (0.000000) New averaged targetPosition: (101.907990) count: (2) + 357468 [3082951][E](PTable): Bottom failed at: (101) Target pos: (101.907990) Avg pos: (101) + 357469 [3082962][E](PTable): Was not in range failed bottom (7)(4)(101), readings (9) + 357470 [3082962][E](PTable): WEIGHTED DOWNVOTING: Target Value: (101), NeighborValue: (101) + 357471 [3082973][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 357472 [3082984][E](PTable): PT failed (7)(4)(101), readings (9) + 357473 [3082986][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357474 [3083008][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357475 [3083039][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357476 [3083061][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357477 [3083094][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357478 [3083116][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357479 [3083148][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 357480 [3083170][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 357481 [3083202][E](PTable): 95 rpm | | | | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357482 [3083224][E](PTable): 100 rpm | | | 72 | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 357483 [3083255][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 357484 [3083276][E](PTable): Power Table Reset + 357485 [3083621][E](PTable): Success! + 357486 [3083883][E](Custom_C): 01 19 <-targetPosition + 357487 [3084326][E](PTable): Success! + 357488 [3084896][E](Custom_C): 01 19 <-targetPosition + 357489 [3085029][E](PTable): Success! + 357490 [3085733][E](PTable): Success! + 357491 [3085734][E](PTable): Clean Power Table + 357492 [3085734][E](PTable): Averaged Entry: watts=119.199997, cad=85.800003, targetPosition=1165.99998, (5)(4) + 357493 [3085746][E](PTable): cellValue: (104) wattDelta: (2.380953) cadDelta: (0.396825) allNeighborsPassed: (0) + 357494 [3085757][E](PTable): rightValue: (0.000000) leftValue: (104.335999) bottomValue: (106.016006) topValue: (0.000000) New averaged targetPosition: (105.176003) count: (2) + 357495 [3085768][E](PTable): Top failed at: (105) Target pos: (105.176003) Avg pos: (105) + 357496 [3085779][E](PTable): Was not in range failed top (4)(4)(105), readings (11) + 357497 [3085780][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (105) + 357498 [3085790][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 357499 [3085791][E](PTable): PT failed (4)(4)(105), readings (11) + 357500 [3085803][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357501 [3085825][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357502 [3085858][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357503 [3085880][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357504 [3085929][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357505 [3085950][E](Custom_C): 01 19 <-targetPosition + 357506 [3085956][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357507 [3085978][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 357508 [3086024][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 357509 [3086045][E](Custom_C): 01 25 <-Firmware Version + 357510 [3086049][E](PTable): 95 rpm | | | | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357511 [3086081][E](PTable): 100 rpm | | | 72 | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 357512 [3086102][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 357513 [3086134][E](PTable): Power Table Reset + 357514 [3086134][E](ERG_Mode): Proportional: 40.000000, Integral: 6.600000, Derivative: -0.400000 + 357515 [3086436][E](PTable): Success! + 357516 [3086922][E](Custom_C): 01 19 <-targetPosition + 357517 [3087137][E](PTable): Success! + 357518 [3087839][E](PTable): Success! + 357519 [3087890][E](Custom_C): 01 19 <-targetPosition + 357520 [3088541][E](PTable): Success! + 357521 [3088542][E](PTable): Clean Power Table + 357522 [3088542][E](PTable): Averaged Entry: watts=112.000000, cad=83.599998, targetPosition=1188.00003, (5)(4) + 357523 [3088554][E](PTable): cellValue: (104) wattDelta: (2.027027) cadDelta: (0.337838) allNeighborsPassed: (0) + 357524 [3088565][E](PTable): rightValue: (0.000000) leftValue: (107.946671) bottomValue: (99.855995) topValue: (0.000000) New averaged targetPosition: (103.901337) count: (2) + 357525 [3088576][E](PTable): Bottom failed at: (103) Target pos: (103.901337) Avg pos: (103) + 357526 [3088586][E](PTable): Was not in range failed bottom (6)(4)(103), readings (9) + 357527 [3088587][E](PTable): WEIGHTED DOWNVOTING: Target Value: (103), NeighborValue: (103) + 357528 [3088597][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 357529 [3088608][E](PTable): PT failed (6)(4)(103), readings (9) + 357530 [3088610][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357531 [3088635][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357532 [3088667][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357533 [3088688][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357534 [3088720][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357535 [3088742][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357536 [3088774][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 357537 [3088796][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 357538 [3088828][E](PTable): 95 rpm | | | | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357539 [3088850][E](PTable): 100 rpm | | | 72 | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 357540 [3088882][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 357541 [3088903][E](Custom_C): 01 19 <-targetPosition + 357542 [3089245][E](PTable): Success! + 357543 [3089891][E](Custom_C): 01 19 <-targetPosition + 357544 [3089949][E](PTable): Success! + 357545 [3090650][E](PTable): Success! + 357546 [3090881][E](Custom_C): 01 2a <-hMin + 357547 [3090903][E](Custom_C): 01 19 <-targetPosition + 357548 [3090937][E](Custom_C): 01 2b <-hMax + 357549 [3091355][E](PTable): Success! + 357550 [3091356][E](PTable): Clean Power Table + 357551 [3091356][E](PTable): Averaged Entry: watts=115.599998, cad=81.400002, targetPosition=1208.00003, (4)(4) + 357552 [3091368][E](PTable): cellValue: (105) wattDelta: (1.898734) cadDelta: (0.316456) allNeighborsPassed: (0) + 357553 [3091372][E](PTable): rightValue: (0.000000) leftValue: (107.317337) bottomValue: (109.424004) topValue: (0.000000) New averaged targetPosition: (108.370667) count: (2) + 357554 [3091393][E](PTable): Top failed at: (106) Target pos: (108.370667) Avg pos: (107) + 357555 [3091394][E](PTable): Current Position moved up was valid! Current position: 108.370667 + 357556 [3091405][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 357557 [3091883][E](Custom_C): 01 19 <-targetPosition + 357558 [3092064][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357559 [3092087][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 357560 [3092109][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | | | | | | | 211 | 214 | | | | | 215 | 216 | 217 | | | | | | | | | | + 357561 [3092141][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | | | | | 200 | 203 | 207 | 210 | 211 | 212 | 213 | 215 | | | 216 | | | | | | | | | | + 357562 [3092162][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | | 190 | 191 | 194 | 197 | 200 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | | | | | | | | | | + 357563 [3092197][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | | 180 | 187 | 190 | 193 | 196 | 197 | | 198 | | 199 | 200 | | | 201 | | | | | | | | | | + 357564 [3092218][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 183 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 196 | 204 | | | | | | | | | | | + 357565 [3092251][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 181 | 183 | 185 | 187 | 188 | 189 | 190 | 192 | | | 201 | | | | | | | | | | | + 357566 [3092273][E](PTable): 95 rpm | 0 | 12 | 76 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 172 | | 175 | 178 | 179 | | 180 | 182 | | | | | 184 | 198 | | | | | | | | | | | + 357567 [3092305][E](PTable): 100 rpm | -12 | 11 | 72 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 170 | 171 | 172 | 190 | 192 | | 195 | | | | | | | | | | | + 357568 [3092327][E](PTable): 105 rpm | -24 | 10 | 69 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 158 | 163 | 165 | 167 | | | | | | | 168 | | | 181 | 192 | 197 | | | | | | | | | | + 357569 [3092358][E](PTable): Power Table Reset + 357570 [3092358][E](ERG_Mode): Proportional: 40.000000, Integral: 7.000000, Derivative: -0.400000 + 357571 [3092606][E](PTable): Success! + 357572 [3092883][E](Custom_C): 01 19 <-targetPosition + 357573 [3093310][E](PTable): Success! + 357574 [3093311][E](PTable): Using detected travel limits during homing + 357575 [3093907][E](Custom_C): 01 19 <-targetPosition + 357576 [3094012][E](PTable): Success! + 357577 [3094716][E](PTable): Success! + 357578 [3094717][E](PTable): Clean Power Table + 357579 [3094718][E](PTable): Averaged Entry: watts=116.800003, cad=79.000000, targetPosition=1224.00002, (4)(4) + 357580 [3094729][E](PTable): cellValue: (105) wattDelta: (1.724138) cadDelta: (0.287356) allNeighborsPassed: (0) + 357581 [3094740][E](PTable): rightValue: (0.000000) leftValue: (106.855995) bottomValue: (101.519997) topValue: (0.000000) New averaged targetPosition: (104.187996) count: (2) + 357582 [3094751][E](PTable): Bottom failed at: (104) Target pos: (104.187996) Avg pos: (104) + 357583 [3094763][E](PTable): Was not in range failed bottom (5)(4)(104), readings (11) + 357584 [3094763][E](PTable): WEIGHTED DOWNVOTING: Target Value: (104), NeighborValue: (104) + 357585 [3094774][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 357586 [3094774][E](PTable): PT failed (5)(4)(104), readings (11) + 357587 [3094786][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357588 [3094808][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357589 [3094840][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357590 [3094862][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357591 [3094893][E](Custom_C): 01 19 <-targetPosition + 357592 [3094898][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357593 [3094920][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357594 [3094952][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 357595 [3094976][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 357596 [3095008][E](PTable): 95 rpm | | | | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357597 [3095029][E](PTable): 100 rpm | | | 72 | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 357598 [3095061][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 357599 [3095084][E](PTable): Power Table Reset + 357600 [3095421][E](PTable): Success! + 357601 [3095936][E](Custom_C): 01 27 00 <-Power Tab Data + 357602 [3095966][E](Custom_C): 01 2a <-hMin + 357603 [3096022][E](Custom_C): 01 19 <-targetPosition + 357604 [3096068][E](Custom_C): 01 27 01 <-Power Tab Data + 357605 [3096101][E](Custom_C): 01 2b <-hMax + 357606 [3096124][E](PTable): Success! + 357607 [3096135][E](Custom_C): 01 27 02 <-Power Tab Data + 357608 [3096180][E](Custom_C): 01 27 03 <-Power Tab Data + 357609 [3096226][E](Custom_C): 01 27 04 <-Power Tab Data + 357610 [3096259][E](Custom_C): 01 27 05 <-Power Tab Data + 357611 [3096316][E](Custom_C): 01 27 06 <-Power Tab Data + 357612 [3096349][E](Custom_C): 01 27 07 <-Power Tab Data + 357613 [3096395][E](Custom_C): 01 27 08 <-Power Tab Data + 357614 [3096439][E](Custom_C): 01 27 09 <-Power Tab Data + 357615 [3096825][E](PTable): Success! + 357616 [3096889][E](Custom_C): 01 19 <-targetPosition + 357617 [3097526][E](PTable): Success! + 357618 [3097527][E](PTable): Clean Power Table + 357619 [3097527][E](PTable): Averaged Entry: watts=116.400002, cad=77.599998, targetPosition=1241.99997, (4)(4) + 357620 [3097539][E](PTable): cellValue: (105) wattDelta: (1.562500) cadDelta: (0.260417) allNeighborsPassed: (0) + 357621 [3097550][E](PTable): rightValue: (0.000000) leftValue: (107.304001) bottomValue: (95.783997) topValue: (0.000000) New averaged targetPosition: (101.543999) count: (2) + 357622 [3097561][E](PTable): Bottom failed at: (104) Target pos: (101.543999) Avg pos: (102) + 357623 [3097572][E](PTable): All test failed bottom (3)(4)(106), readings (11) + 357624 [3097572][E](PTable): WEIGHTED DOWNVOTING: Target Value: (101), NeighborValue: (104) + 357625 [3097583][E](PTable): WEIGHTED DOWNVOTING: Delta: (3), Penalty: (0) + 357626 [3097583][E](PTable): PT failed (5)(4)(104), readings (11) + 357627 [3097595][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357628 [3097617][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357629 [3097650][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357630 [3097672][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357631 [3097703][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357632 [3097727][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357633 [3097759][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 357634 [3097780][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 357635 [3097813][E](PTable): 95 rpm | | | | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357636 [3097835][E](PTable): 100 rpm | | | 72 | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 357637 [3097867][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 357638 [3097887][E](PTable): Power Table Reset + 357639 [3097901][E](Custom_C): 01 19 <-targetPosition + 357640 [3098305][E](PTable): Success! + 357641 [3098305][E](ERG_Mode): Proportional: 56.000000, Integral: 7.400000, Derivative: 0.400000 + 357642 [3098902][E](Custom_C): 01 19 <-targetPosition + 357643 [3099005][E](PTable): Success! + 357644 [3099706][E](PTable): Success! + 357645 [3099893][E](Custom_C): 01 19 <-targetPosition + 357646 [3100408][E](PTable): Success! + 357647 [3100409][E](PTable): Clean Power Table + 357648 [3100409][E](PTable): Averaged Entry: watts=118.400002, cad=75.400002, targetPosition=1254.00002, (3)(4) + 357649 [3100421][E](PTable): cellValue: (106) wattDelta: (1.546392) cadDelta: (0.257732) allNeighborsPassed: (0) + 357650 [3100432][E](PTable): rightValue: (0.000000) leftValue: (107.034668) bottomValue: (107.552002) topValue: (0.000000) New averaged targetPosition: (107.293335) count: (2) + 357651 [3100444][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 357652 [3100882][E](Custom_C): 01 2a <-hMin + 357653 [3100916][E](Custom_C): 01 19 <-targetPosition + 357654 [3100938][E](Custom_C): 01 2b <-hMax + 357655 [3101136][E](Custom_C): 01 27 03 <-Power Tab Data + 357656 [3101141][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357657 [3101163][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | | | | | | | | | | + 357658 [3101195][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 178 | 190 | 193 | 207 | 210 | | | | | | | 211 | 214 | | | | | 215 | 216 | 217 | | | | | | | | | | + 357659 [3101219][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 176 | 189 | 194 | 197 | | | | | 200 | 203 | 207 | 210 | 211 | 212 | 213 | 215 | | | 216 | | | | | | | | | | + 357660 [3101252][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | | 190 | 191 | 194 | 197 | 200 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | | | | | | | | | | + 357661 [3101274][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | | 180 | 187 | 190 | 193 | 196 | 197 | | 198 | | 199 | 200 | | | 201 | | | | | | | | | | + 357662 [3101306][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 183 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 196 | 204 | | | | | | | | | | | + 357663 [3101328][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 181 | 183 | 185 | 187 | 188 | 189 | 190 | 192 | | | 201 | | | | | | | | | | | + 357664 [3101360][E](PTable): 95 rpm | 0 | 12 | 76 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 172 | | 175 | 178 | 179 | | 180 | 182 | | | | | 184 | 198 | | | | | | | | | | | + 357665 [3101382][E](PTable): 100 rpm | -12 | 11 | 72 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 170 | 171 | 172 | 190 | 192 | | 195 | | | | | | | | | | | + 357666 [3101415][E](PTable): 105 rpm | -24 | 10 | 69 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 158 | 163 | 165 | 167 | | | | | | | 168 | | | 181 | 192 | 197 | | | | | | | | | | + 357667 [3101435][E](PTable): Power Table Reset + 357668 [3101682][E](PTable): Success! + 357669 [3101883][E](Custom_C): 01 19 <-targetPosition + 357670 [3102266][E](Custom_C): 01 25 <-Firmware Version + 357671 [3102384][E](PTable): Success! + 357672 [3102897][E](Custom_C): 01 19 <-targetPosition + 357673 [3103086][E](PTable): Success! + 357674 [3103734][E](FTMS_SERVER): 05 ea 01 -> ERG Mode Target: 490 Current: 124 Incline: 127.550003 + 357675 [3103743][E](Custom_C): 01 28 <-targetWatts + 357676 [3103788][E](PTable): Success! + 357677 [3103789][E](PTable): Clean Power Table + 357678 [3103789][E](PTable): Averaged Entry: watts=122.400002, cad=74.000000, targetPosition=1265.99998, (3)(4) + 357679 [3103800][E](PTable): cellValue: (106) wattDelta: (1.456311) cadDelta: (0.242718) allNeighborsPassed: (0) + 357680 [3103811][E](PTable): rightValue: (0.000000) leftValue: (104.351997) bottomValue: (101.879997) topValue: (0.000000) New averaged targetPosition: (103.115997) count: (2) + 357681 [3103823][E](PTable): Bottom failed at: (105) Target pos: (103.115997) Avg pos: (104) + 357682 [3103835][E](PTable): All test failed bottom (2)(4)(121), readings (11) + 357683 [3103835][E](PTable): WEIGHTED DOWNVOTING: Target Value: (103), NeighborValue: (105) + 357684 [3103845][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 357685 [3103845][E](PTable): PT failed (4)(4)(105), readings (11) + 357686 [3103858][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357687 [3103881][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357688 [3103913][E](Custom_C): 01 19 <-targetPosition + 357689 [3103921][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 178 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357690 [3103943][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 176 | 189 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357691 [3103965][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357692 [3103998][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357693 [3104020][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 357694 [3104052][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 357695 [3104077][E](PTable): 95 rpm | | | | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357696 [3104110][E](PTable): 100 rpm | | | 72 | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 357697 [3104132][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 357698 [3104163][E](PTable): Power Table Reset + 357699 [3104163][E](PTable): Lookup debug 330 X1 -3840 X2 -580 Y1 -580 Y2 0 + 357700 [3104165][E](ERG_Mode): Table Result Failed Low Test: -32768 + 357701 [3104177][E](ERG_Mode): SetPoint changed:490w PowerTable Result: 14219 + 357702 [3104184][E](PTable): Success! + 357703 [3104898][E](Custom_C): 01 19 <-targetPosition + 357704 [3105069][E](PTable): Success! + 357705 [3105070][E](ERG_Mode): Proportional: 1512.000000, Integral: 43.799999, Derivative: 37.600002 + 357706 [3105771][E](PTable): Power Table Reset + 357707 [3105888][E](Custom_C): 01 2a <-hMin + 357708 [3105933][E](Custom_C): 01 19 <-targetPosition + 357709 [3105967][E](Custom_C): 01 2b <-hMax + 357710 [3106014][E](Custom_C): 01 25 <-Firmware Version + 357711 [3106476][E](PTable): Success! + 357712 [3106900][E](Custom_C): 01 19 <-targetPosition + 357713 [3107180][E](PTable): Success! + 357714 [3107884][E](PTable): Power Table Reset + 357715 [3107890][E](Custom_C): 01 19 <-targetPosition + 357716 [3108585][E](PTable): Success! + 357717 [3108883][E](Custom_C): 01 19 <-targetPosition + 357718 [3109286][E](PTable): Success! + 357719 [3109882][E](Custom_C): 01 19 <-targetPosition + 357720 [3109987][E](PTable): Success! + 357721 [3110689][E](PTable): Success! + 357722 [3110690][E](PTable): Clean Power Table + 357723 [3110690][E](PTable): Averaged Entry: watts=308.399994, cad=70.000000, targetPosition=1876.00006, (2)(10) + 357724 [3110702][E](PTable): Keep old targetPosition: (187.600006) + 357725 [3110702][E](PTable): Right failed at: (176) Target pos: (187.600006) Avg pos: (181) + 357726 [3110713][E](PTable): Current Position moved right was valid! Current position: 187.600006 + 357727 [3110724][E](PTable): Existing entry averaged (2)(11)(179), readings(2) + 357728 [3110895][E](Custom_C): 01 27 00 <-Power Tab Data + 357729 [3110916][E](Custom_C): 01 2a <-hMin + 357730 [3110951][E](Custom_C): 01 19 <-targetPosition + 357731 [3110985][E](Custom_C): 01 27 01 <-Power Tab Data + 357732 [3111018][E](Custom_C): 01 2b <-hMax + 357733 [3111075][E](Custom_C): 01 27 02 <-Power Tab Data + 357734 [3111109][E](Custom_C): 01 27 03 <-Power Tab Data + 357735 [3111155][E](Custom_C): 01 27 04 <-Power Tab Data + 357736 [3111159][E](PTable): Top failed at: (178) Target pos: (187.600006) Avg pos: (182) + 357737 [3111170][E](PTable): Current Position moved up was valid! Current position: 187.600006 + 357738 [3111171][E](PTable): Existing entry averaged (1)(10)(181), readings(2) + 357739 [3111200][E](Custom_C): 01 27 05 <-Power Tab Data + 357740 [3111244][E](Custom_C): 01 27 06 <-Power Tab Data + 357741 [3111290][E](Custom_C): 01 27 07 <-Power Tab Data + 357742 [3111334][E](Custom_C): 01 27 08 <-Power Tab Data + 357743 [3111370][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357744 [3111426][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 224 | 226 | 228 | | | | | | | | | | | | 232 | | | | | | | | | | + 357745 [3111450][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 207 | 210 | | | | | | | 211 | 214 | 216 | 218 | 220 | 222 | 224 | 226 | 228 | | | | | | | | | | + 357746 [3111472][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 169 | 179 | 189 | 194 | 197 | | | | | 200 | 203 | 207 | 209 | 211 | 214 | 217 | 219 | 221 | 223 | 224 | | | | | | | | | | + 357747 [3111504][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 183 | 185 | | 190 | 191 | 194 | 197 | 200 | 203 | 204 | 206 | 210 | 214 | 215 | | 217 | 220 | | | | | | | | | | + 357748 [3111525][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | | 180 | 187 | 190 | 193 | 196 | 197 | 199 | 201 | 206 | 213 | 214 | 219 | | | | | | | | | | | | + 357749 [3111558][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 183 | 186 | 187 | 188 | 189 | 190 | 196 | 202 | 207 | 210 | 213 | 216 | 219 | | | | | | | | | | + 357750 [3111580][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 181 | 183 | 185 | 186 | 188 | 191 | 194 | 196 | 203 | 209 | 215 | | | | | | | | | | | + 357751 [3111611][E](PTable): 95 rpm | 0 | 12 | 76 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 160 | 164 | 172 | | 175 | 178 | 179 | | | 180 | 186 | 190 | 194 | 198 | 199 | | 204 | | | | | | | | | | + 357752 [3111633][E](PTable): 100 rpm | -12 | 11 | 72 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 174 | 181 | 185 | 189 | 193 | 194 | | 200 | | | | | | | | | | + 357753 [3111666][E](PTable): 105 rpm | -24 | 10 | 69 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 158 | 163 | 165 | 167 | | | | | 170 | 176 | 178 | 180 | 182 | 184 | | 196 | | | | | | | | | | + 357754 [3111687][E](PTable): Power Table Reset + 357755 [3111698][E](ERG_Mode): Proportional: 672.000000, Integral: 22.800001, Derivative: 0.600000 + 357756 [3111899][E](Custom_C): 01 19 <-targetPosition + 357757 [3112065][E](PTable): Success! + 357758 [3112766][E](PTable): Success! + 357759 [3112898][E](Custom_C): 01 19 <-targetPosition + 357760 [3113470][E](PTable): Success! + 357761 [3113887][E](Custom_C): 01 19 <-targetPosition + 357762 [3114171][E](PTable): Success! + 357763 [3114172][E](PTable): Clean Power Table + 357764 [3114172][E](PTable): Averaged Entry: watts=400.399994, cad=69.599998, targetPosition=1973.99994, (2)(13) + 357765 [3114184][E](PTable): Keep old targetPosition: (197.399994) + 357766 [3114184][E](PTable): New entry recorded (2)(13)(197) + 357767 [3114714][E](Custom_C): 01 27 02 <-Power Tab Data + 357768 [3114721][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357769 [3114743][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 357770 [3114775][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 213 | | | | | | | 214 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | | | | | | | | | | + 357771 [3114797][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 204 | | | | | 205 | 207 | 210 | 211 | 213 | 215 | 217 | 220 | | 223 | | | | | | | | | | + 357772 [3114831][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 187 | | 189 | 191 | 194 | 197 | 200 | 203 | 204 | 206 | 210 | 214 | 215 | | 217 | 220 | | | | | | | | | | + 357773 [3114852][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | | 180 | 187 | 190 | 193 | 196 | 197 | 199 | 201 | 206 | 213 | | 219 | | | | | | | | | | | | + 357774 [3114885][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 183 | 186 | 187 | 188 | 189 | 190 | 196 | 202 | 207 | | 218 | | | | | | | | | | | | + 357775 [3114926][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 181 | 183 | 185 | 186 | 188 | 191 | 194 | 196 | 203 | | 209 | 213 | | | | | | | | | | + 357776 [3114948][E](PTable): 95 rpm | 0 | 12 | 76 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 164 | 172 | | 175 | 178 | 179 | | | 180 | 186 | 190 | 194 | 201 | 217 | | | | | | | | | | | | + 357777 [3114970][E](PTable): 100 rpm | -12 | 11 | 72 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 174 | 181 | 185 | 189 | 199 | 216 | | | | | | | | | | | | + 357778 [3115002][E](PTable): 105 rpm | -24 | 10 | 69 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 158 | 163 | 165 | 167 | | | | | 170 | 176 | 178 | 180 | 182 | 184 | 208 | 212 | | | | | | | | | | + 357779 [3115023][E](PTable): Power Table Reset + 357780 [3115050][E](PTable): Success! + 357781 [3115753][E](PTable): Success! + 357782 [3115900][E](Custom_C): 01 2a <-hMin + 357783 [3115923][E](Custom_C): 01 19 <-targetPosition + 357784 [3115969][E](Custom_C): 01 2b <-hMax + 357785 [3116455][E](PTable): Success! + 357786 [3116890][E](Custom_C): 01 19 <-targetPosition + 357787 [3117156][E](PTable): Success! + 357788 [3117157][E](PTable): Clean Power Table + 357789 [3117157][E](PTable): Averaged Entry: watts=392.799988, cad=68.199997, targetPosition=2056.00006, (2)(13) + 357790 [3117168][E](PTable): cellValue: (197) wattDelta: (3.488370) cadDelta: (0.581395) allNeighborsPassed: (1) + 357791 [3117179][E](PTable): rightValue: (197.802658) leftValue: (196.197342) bottomValue: (193.903992) topValue: (200.096008) New averaged targetPosition: (197.000000) count: (4) + 357792 [3117191][E](PTable): Existing entry averaged (2)(13)(197), readings(1) + 357793 [3117715][E](Custom_C): 01 27 02 <-Power Tab Data + 357794 [3117721][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357795 [3117744][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | | | | | | | | | | + 357796 [3117776][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 213 | | | | | | | 214 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | | | | | | | | | | + 357797 [3117800][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 204 | | | | | 205 | 207 | 210 | 211 | 213 | 215 | 217 | 220 | | 223 | | | | | | | | | | + 357798 [3117823][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 187 | | 189 | 191 | 194 | 197 | 200 | 203 | 204 | 206 | 210 | 214 | 215 | | 217 | 220 | | | | | | | | | | + 357799 [3117855][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | | 180 | 187 | 190 | 193 | 196 | 197 | 199 | 201 | 206 | 213 | | 219 | | | | | | | | | | | | + 357800 [3117876][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | | 173 | 183 | 186 | 187 | 188 | 189 | 190 | 196 | 202 | 207 | | 218 | | | | | | | | | | | | + 357801 [3117923][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | | 179 | 181 | 183 | 185 | 186 | 188 | 191 | 194 | 196 | 203 | | 209 | 213 | | | | | | | | | | + 357802 [3117945][E](PTable): 95 rpm | 0 | 12 | 76 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 164 | 172 | | 175 | 178 | 179 | | | 180 | 186 | 190 | 194 | 201 | 217 | | | | | | | | | | | | + 357803 [3117977][E](PTable): 100 rpm | -12 | 11 | 72 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 174 | 181 | 185 | 189 | 199 | 216 | | | | | | | | | | | | + 357804 [3118002][E](PTable): 105 rpm | -24 | 10 | 69 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 158 | 163 | 165 | 167 | | | | | 170 | 176 | 178 | 180 | 182 | 184 | 208 | 212 | | | | | | | | | | + 357805 [3118023][E](PTable): Power Table Reset + 357806 [3118034][E](ERG_Mode): Proportional: 280.000000, Integral: 13.000000, Derivative: -3.000000 + 357807 [3118278][E](PTable): Success! + 357808 [3118779][E](FTMS_SERVER): 05 82 00 -> ERG Mode Target: 130 Current: 458 Incline: 211.764008 + 357809 [3118786][E](Custom_C): 01 28 <-targetWatts + 357810 [3118881][E](Custom_C): 01 19 <-targetPosition + 357811 [3118981][E](PTable): Success! + 357812 [3118982][E](PTable): Lookup debug 90 X1 150 X2 65 Y1 75 Y2 -0 + 357813 [3118983][E](PTable): Lookup used neighbors L 111 R 130 R1 124 + 357814 [3118994][E](PTable): Lookup used neighbors U 130 D 106 R2 118 + 357815 [3118994][E](PTable): Lookup used actual 121 R3 121 + 357816 [3119005][E](PTable): Lookup result: 130w 70cad 12000 + 357817 [3119005][E](ERG_Mode): SetPoint changed:130w PowerTable Result: 12000 + 357818 [3119016][E](ERG_Mode): Capping ERG seek time to 5 seconds + 357819 [3119022][E](PTable): Success! + 357820 [3119725][E](PTable): Success! + 357821 [3119726][E](PTable): Clean Power Table + 357822 [3119726][E](PTable): Averaged Entry: watts=455.200012, cad=70.199997, targetPosition=2091.99997, (2)(15) + 357823 [3119738][E](PTable): Keep old targetPosition: (209.199997) + 357824 [3119739][E](PTable): New entry recorded (2)(15)(209) + 357825 [3119884][E](Custom_C): 01 19 <-targetPosition + 357826 [3120153][E](Custom_C): 01 27 02 <-Power Tab Data + 357827 [3120159][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357828 [3120180][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 233 | 234 | | | | | | | 235 | 236 | | | | | | | | | | + 357829 [3120212][E](PTable): 65 rpm | 72 | 85 | 99 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | | | | | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | | | | | | | | | | + 357830 [3120234][E](PTable): 70 rpm | 60 | 80 | 95 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | | | | | 214 | 215 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | | | | | | | | | | + 357831 [3120266][E](PTable): 75 rpm | 48 | 64 | 91 | 100 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | | | 205 | 206 | 207 | | 208 | | | 209 | | 210 | | | | | | | | | | | + 357832 [3120288][E](PTable): 80 rpm | 36 | 58 | 88 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 178 | 191 | 195 | 197 | | 198 | 199 | | | 200 | 203 | 213 | | 219 | | | | | | | | | | | | + 357833 [3120320][E](PTable): 85 rpm | | 24 | 84 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 188 | 190 | 192 | 194 | 195 | 196 | 198 | 202 | 206 | 207 | 218 | | | | | | | | | | | | + 357834 [3120343][E](PTable): 90 rpm | 12 | 18 | 80 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | 179 | 182 | 185 | 186 | | | 187 | 191 | 195 | 196 | 206 | 217 | | 224 | | | | | | | | | | + 357835 [3120375][E](PTable): 95 rpm | 0 | 12 | 76 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 164 | 171 | 174 | 177 | 179 | | | | 180 | 181 | 192 | 193 | 205 | 216 | | 223 | | | | | | | | | | + 357836 [3120397][E](PTable): 100 rpm | -12 | 11 | 72 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 173 | 176 | 189 | 190 | 204 | 215 | | 222 | | | | | | | | | | + 357837 [3120429][E](PTable): 105 rpm | -24 | 10 | 69 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 158 | 163 | 165 | 167 | | | | 168 | 169 | 170 | 187 | | 203 | 214 | | 221 | | | | | | | | | | + 357838 [3120451][E](PTable): Power Table Reset + 357839 [3120654][E](PTable): Success! + 357840 [3120910][E](Custom_C): 01 2a <-hMin + 357841 [3120941][E](Custom_C): 01 19 <-targetPosition + 357842 [3120967][E](Custom_C): 01 2b <-hMax + 357843 [3121355][E](PTable): Power Table Reset + 357844 [3121888][E](Custom_C): 01 19 <-targetPosition + 357845 [3122059][E](PTable): Success! + 357846 [3122268][E](Custom_C): 01 25 <-Firmware Version + 357847 [3122767][E](PTable): Success! + 357848 [3122887][E](Custom_C): 01 19 <-targetPosition + 357849 [3123470][E](PTable): Success! + 357850 [3123472][E](ERG_Mode): Proportional: -808.000000, Integral: -26.200001, Derivative: -2.800000 + 357851 [3123888][E](Custom_C): 01 19 <-targetPosition + 357852 [3124173][E](PTable): Success! + 357853 [3124174][E](PTable): Clean Power Table + 357854 [3124174][E](PTable): Averaged Entry: watts=358.399994, cad=78.599998, targetPosition=1413.99994, (4)(12) + 357855 [3124185][E](PTable): cellValue: (168) wattDelta: (1.127819) cadDelta: (0.187970) allNeighborsPassed: (0) + 357856 [3124197][E](PTable): rightValue: (113.381317) leftValue: (0.000000) bottomValue: (0.000000) topValue: (122.248001) New averaged targetPosition: (117.814659) count: (2) + 357857 [3124208][E](PTable): Left failed at: (157) Target pos: (117.814659) Avg pos: (137) + 357858 [3124219][E](PTable): Was not in range failed left (4)(11)(157), readings (11) + 357859 [3124219][E](PTable): WEIGHTED DOWNVOTING: Target Value: (117), NeighborValue: (157) + 357860 [3124229][E](PTable): WEIGHTED DOWNVOTING: Delta: (40), Penalty: (8) + 357861 [3124240][E](PTable): PT failed (4)(11)(157), readings (3) + 357862 [3124240][E](PTable): Bottom failed at: (160) Target pos: (117.814659) Avg pos: (138) + 357863 [3124251][E](PTable): Was not in range failed bottom (5)(12)(160), readings (11) + 357864 [3124252][E](PTable): WEIGHTED DOWNVOTING: Target Value: (117), NeighborValue: (160) + 357865 [3124262][E](PTable): WEIGHTED DOWNVOTING: Delta: (43), Penalty: (8) + 357866 [3124273][E](PTable): PT failed (5)(12)(160), readings (3) + 357867 [3124275][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 357868 [3124297][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357869 [3124329][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357870 [3124351][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 357871 [3124383][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357872 [3124404][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 357873 [3124436][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 357874 [3124459][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 357875 [3124490][E](PTable): 95 rpm | | | | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 357876 [3124512][E](PTable): 100 rpm | | | 72 | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 357877 [3124544][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 357878 [3124565][E](PTable): Power Table Reset + 357879 [3124903][E](Custom_C): 01 19 <-targetPosition + 357880 [3125903][E](Custom_C): 01 27 00 <-Power Tab Data + 357881 [3125935][E](Custom_C): 01 2a <-hMin + 357882 [3125957][E](Custom_C): 01 19 <-targetPosition + 357883 [3126005][E](Custom_C): 01 27 01 <-Power Tab Data + 357884 [3126036][E](Custom_C): 01 2b <-hMax + 357885 [3126083][E](Custom_C): 01 27 02 <-Power Tab Data + 357886 [3126127][E](Custom_C): 01 27 03 <-Power Tab Data + 357887 [3126173][E](Custom_C): 01 27 04 <-Power Tab Data + 357888 [3126263][E](Custom_C): 01 27 05 <-Power Tab Data + 357889 [3126331][E](Custom_C): 01 27 06 <-Power Tab Data + 357890 [3126375][E](Custom_C): 01 27 07 <-Power Tab Data + 357891 [3126444][E](Custom_C): 01 27 08 <-Power Tab Data + 357892 [3126487][E](Custom_C): 01 27 09 <-Power Tab Data + 357893 [3126543][E](Custom_C): 01 25 <-Firmware Version + 357894 [3126881][E](Custom_C): 01 19 <-targetPosition + 357895 [3127882][E](Custom_C): 01 19 <-targetPosition + 357896 [3128884][E](Custom_C): 01 19 <-targetPosition + 357897 [3129895][E](Custom_C): 01 19 <-targetPosition + 357898 [3130886][E](Custom_C): 01 2a <-hMin + 357899 [3130930][E](Custom_C): 01 19 <-targetPosition + 357900 [3130952][E](Custom_C): 01 2b <-hMax + 357901 [3131887][E](Custom_C): 01 19 <-targetPosition + 357902 [3132888][E](Custom_C): 01 19 <-targetPosition + 357903 [3133900][E](Custom_C): 01 19 <-targetPosition + 357904 [3134891][E](Custom_C): 01 19 <-targetPosition + 357905 [3135881][E](Custom_C): 01 2a <-hMin + 357906 [3135902][E](Custom_C): 01 19 <-targetPosition + 357907 [3135936][E](Custom_C): 01 2b <-hMax + 357908 [3136884][E](Custom_C): 01 19 <-targetPosition + 357909 [3137883][E](Custom_C): 01 19 <-targetPosition + 357910 [3138907][E](Custom_C): 01 19 <-targetPosition + 357911 [3139886][E](Custom_C): 01 19 <-targetPosition + 357912 [3140899][E](Custom_C): 01 27 00 <-Power Tab Data + 357913 [3140932][E](Custom_C): 01 2a <-hMin + 357914 [3140988][E](Custom_C): 01 19 <-targetPosition + 357915 [3141046][E](Custom_C): 01 27 01 <-Power Tab Data + 357916 [3141067][E](Custom_C): 01 2b <-hMax + 357917 [3141112][E](Custom_C): 01 27 02 <-Power Tab Data + 357918 [3141169][E](Custom_C): 01 27 03 <-Power Tab Data + 357919 [3141214][E](Custom_C): 01 27 04 <-Power Tab Data + 357920 [3141270][E](Custom_C): 01 27 05 <-Power Tab Data + 357921 [3141304][E](Custom_C): 01 27 06 <-Power Tab Data + 357922 [3141348][E](Custom_C): 01 27 07 <-Power Tab Data + 357923 [3141394][E](Custom_C): 01 27 08 <-Power Tab Data + 357924 [3141439][E](Custom_C): 01 27 09 <-Power Tab Data + 357925 [3141888][E](Custom_C): 01 19 <-targetPosition + 357926 [3142282][E](Custom_C): 01 25 <-Firmware Version + 357927 [3142901][E](Custom_C): 01 19 <-targetPosition + 357928 [3143890][E](Custom_C): 01 19 <-targetPosition + 357929 [3145882][E](Custom_C): 01 2a <-hMin + 357930 [3145960][E](Custom_C): 01 2b <-hMax + 357931 [3145982][E](Custom_C): 01 25 <-Firmware Version + 357932 [3146906][E](Custom_C): 01 19 <-targetPosition + 357933 [3147896][E](Custom_C): 01 19 <-targetPosition + 357934 [3148886][E](Custom_C): 01 19 <-targetPosition + 357935 [3149898][E](Custom_C): 01 19 <-targetPosition + 357936 [3150888][E](Custom_C): 01 2a <-hMin + 357937 [3150921][E](Custom_C): 01 19 <-targetPosition + 357938 [3150955][E](Custom_C): 01 2b <-hMax + 357939 [3151900][E](Custom_C): 01 19 <-targetPosition + 357940 [3152890][E](Custom_C): 01 19 <-targetPosition + 357941 [3153881][E](Custom_C): 01 19 <-targetPosition + 357942 [3154894][E](Custom_C): 01 19 <-targetPosition + 357943 [3155918][E](Custom_C): 01 27 00 <-Power Tab Data + 357944 [3155950][E](Custom_C): 01 2a <-hMin + 357945 [3155972][E](Custom_C): 01 19 <-targetPosition + 357946 [3156019][E](Custom_C): 01 27 01 <-Power Tab Data + 357947 [3156051][E](Custom_C): 01 2b <-hMax + 357948 [3156098][E](Custom_C): 01 27 02 <-Power Tab Data + 357949 [3156142][E](Custom_C): 01 27 03 <-Power Tab Data + 357950 [3156187][E](Custom_C): 01 27 04 <-Power Tab Data + 357951 [3156244][E](Custom_C): 01 27 05 <-Power Tab Data + 357952 [3156288][E](Custom_C): 01 27 06 <-Power Tab Data + 357953 [3156334][E](Custom_C): 01 27 07 <-Power Tab Data + 357954 [3156378][E](Custom_C): 01 27 08 <-Power Tab Data + 357955 [3156435][E](Custom_C): 01 27 09 <-Power Tab Data + 357956 [3156895][E](Custom_C): 01 19 <-targetPosition + 357957 [3157885][E](Custom_C): 01 19 <-targetPosition + 357958 [3158886][E](Custom_C): 01 19 <-targetPosition + 357959 [3159888][E](Custom_C): 01 19 <-targetPosition + 357960 [3160900][E](Custom_C): 01 2a <-hMin + 357961 [3160945][E](Custom_C): 01 19 <-targetPosition + 357962 [3160967][E](Custom_C): 01 2b <-hMax + 357963 [3161890][E](Custom_C): 01 19 <-targetPosition + 357964 [3162273][E](Custom_C): 01 25 <-Firmware Version + 357965 [3162880][E](Custom_C): 01 19 <-targetPosition + 357966 [3163882][E](Custom_C): 01 19 <-targetPosition + 357967 [3164883][E](Custom_C): 01 19 <-targetPosition + 357968 [3165895][E](Custom_C): 01 2a <-hMin + 357969 [3165918][E](Custom_C): 01 19 <-targetPosition + 357970 [3165963][E](Custom_C): 01 2b <-hMax + 357971 [3165996][E](Custom_C): 01 25 <-Firmware Version + 357972 [3166886][E](Custom_C): 01 19 <-targetPosition + 357973 [3167886][E](Custom_C): 01 19 <-targetPosition + 357974 [3168910][E](Custom_C): 01 19 <-targetPosition + 357975 [3169900][E](Custom_C): 01 19 <-targetPosition + 357976 [3170903][E](Custom_C): 01 27 00 <-Power Tab Data + 357977 [3170935][E](Custom_C): 01 2a <-hMin + 357978 [3170980][E](Custom_C): 01 19 <-targetPosition + 357979 [3171037][E](Custom_C): 01 27 01 <-Power Tab Data + 357980 [3171070][E](Custom_C): 01 2b <-hMax + 357981 [3171127][E](Custom_C): 01 27 02 <-Power Tab Data + 357982 [3171173][E](Custom_C): 01 27 03 <-Power Tab Data + 357983 [3171218][E](Custom_C): 01 27 04 <-Power Tab Data + 357984 [3171275][E](Custom_C): 01 27 05 <-Power Tab Data + 357985 [3171319][E](Custom_C): 01 27 06 <-Power Tab Data + 357986 [3171375][E](Custom_C): 01 27 07 <-Power Tab Data + 357987 [3171409][E](Custom_C): 01 27 08 <-Power Tab Data + 357988 [3171455][E](Custom_C): 01 27 09 <-Power Tab Data + 357989 [3171880][E](Custom_C): 01 19 <-targetPosition + 357990 [3172915][E](Custom_C): 01 19 <-targetPosition + 357991 [3173883][E](Custom_C): 01 19 <-targetPosition + 357992 [3174895][E](Custom_C): 01 19 <-targetPosition + 357993 [3175886][E](Custom_C): 01 2a <-hMin + 357994 [3175907][E](Custom_C): 01 19 <-targetPosition + 357995 [3175941][E](Custom_C): 01 2b <-hMax + 357996 [3176898][E](Custom_C): 01 19 <-targetPosition + 357997 [3177888][E](Custom_C): 01 19 <-targetPosition + 357998 [3178900][E](Custom_C): 01 19 <-targetPosition + 357999 [3179890][E](Custom_C): 01 19 <-targetPosition + 358000 [3180892][E](Custom_C): 01 2a <-hMin + 358001 [3180925][E](Custom_C): 01 19 <-targetPosition + 358002 [3180947][E](Custom_C): 01 2b <-hMax + 358003 [3185910][E](Custom_C): 01 27 00 <-Power Tab Data + 358004 [3195910][E](Custom_C): 01 2a <-hMin + 358005 [3205900][E](Custom_C): 01 2a <-hMin + 358006 [3215914][E](Custom_C): 01 27 00 <-Power Tab Data + 358007 [3225892][E](Custom_C): 01 2a <-hMin + 358008 [3235881][E](Custom_C): 01 2a <-hMin + 358009 [3235971][E](Custom_C): 01 2b <-hMax + 358010 [3237769][E](Log_Handler): Exit writeLogs(). Messages remaining in buffer. + 358011 [3237794][E](PTable): Success! + 358012 [3237794][E](ERG_Mode): Proportional: -112.000000, Integral: -8.800000, Derivative: 17.400000 + 358013 [3237885][E](Custom_C): 01 19 <-targetPosition + 358014 [3238898][E](Custom_C): 01 19 <-targetPosition + 358015 [3238945][E](FTMS_SERVER): 11 00 00 64 00 28 33 -> Sim Mode Incline 1.000000 + 358016 [3238954][E](Custom_C): 01 10 <-FTMSMode + 358017 [3239887][E](Custom_C): 01 19 <-targetPosition + 358018 [3240911][E](Custom_C): 01 2a <-hMin + 358019 [3240944][E](Custom_C): 01 19 <-targetPosition + 358020 [3241012][E](Custom_C): 01 2b <-hMax + 358021 [3241889][E](Custom_C): 01 19 <-targetPosition + 358022 [3242271][E](Custom_C): 01 25 <-Firmware Version + 358023 [3242890][E](Custom_C): 01 19 <-targetPosition + 358024 [3243892][E](Custom_C): 01 19 <-targetPosition + 358025 [3244904][E](Custom_C): 01 19 <-targetPosition + 358026 [3245929][E](Custom_C): 01 27 00 <-Power Tab Data + 358027 [3245961][E](Custom_C): 01 2a <-hMin + 358028 [3246006][E](Custom_C): 01 19 <-targetPosition + 358029 [3246086][E](Custom_C): 01 27 01 <-Power Tab Data + 358030 [3246145][E](Custom_C): 01 2b <-hMax + 358031 [3246199][E](Custom_C): 01 27 02 <-Power Tab Data + 358032 [3246266][E](Custom_C): 01 27 03 <-Power Tab Data + 358033 [3246323][E](Custom_C): 01 27 04 <-Power Tab Data + 358034 [3246379][E](Custom_C): 01 27 05 <-Power Tab Data + 358035 [3246425][E](Custom_C): 01 27 06 <-Power Tab Data + 358036 [3246469][E](Custom_C): 01 27 07 <-Power Tab Data + 358037 [3246514][E](Custom_C): 01 27 08 <-Power Tab Data + 358038 [3246559][E](Custom_C): 01 27 09 <-Power Tab Data + 358039 [3246591][E](Custom_C): 01 25 <-Firmware Version + 358040 [3246884][E](Custom_C): 01 19 <-targetPosition + 358041 [3247896][E](Custom_C): 01 19 <-targetPosition + 358042 [3248887][E](Custom_C): 01 19 <-targetPosition + 358043 [3249910][E](Custom_C): 01 19 <-targetPosition + 358044 [3250889][E](Custom_C): 01 2a <-hMin + 358045 [3250956][E](Custom_C): 01 19 <-targetPosition + 358046 [3251001][E](Custom_C): 01 2b <-hMax + 358047 [3251152][E](PTable): Using detected travel limits during homing + 358048 [3251890][E](Custom_C): 01 19 <-targetPosition + 358049 [3252891][E](Custom_C): 01 19 <-targetPosition + 358050 [3253904][E](Custom_C): 01 19 <-targetPosition + 358051 [3254894][E](Custom_C): 01 19 <-targetPosition + 358052 [3255884][E](Custom_C): 01 2a <-hMin + 358053 [3255951][E](Custom_C): 01 19 <-targetPosition + 358054 [3255996][E](Custom_C): 01 2b <-hMax + 358055 [3256792][E](PTable): Power Table Reset + 358056 [3256896][E](Custom_C): 01 19 <-targetPosition + 358057 [3257495][E](PTable): Success! + 358058 [3257910][E](Custom_C): 01 19 <-targetPosition + 358059 [3258198][E](PTable): Success! + 358060 [3258903][E](PTable): Success! + 358061 [3258921][E](Custom_C): 01 19 <-targetPosition + 358062 [3259606][E](PTable): Success! + 358063 [3259607][E](PTable): Clean Power Table + 358064 [3259607][E](PTable): Averaged Entry: watts=57.200001, cad=62.200001, targetPosition=790.00000, (0)(2) + 358065 [3259620][E](PTable): cellValue: (103) wattDelta: (1.250000) cadDelta: (0.208333) allNeighborsPassed: (0) + 358066 [3259621][E](PTable): rightValue: (52.760002) leftValue: (0.000000) bottomValue: (65.560005) topValue: (44.439995) New averaged targetPosition: (54.253338) count: (3) + 358067 [3259643][E](PTable): Left failed at: (86) Target pos: (54.253338) Avg pos: (70) + 358068 [3259643][E](PTable): Was not in range failed left (0)(1)(86), readings (11) + 358069 [3259654][E](PTable): WEIGHTED DOWNVOTING: Target Value: (54), NeighborValue: (86) + 358070 [3259664][E](PTable): WEIGHTED DOWNVOTING: Delta: (32), Penalty: (6) + 358071 [3259664][E](PTable): PT failed (0)(1)(86), readings (5) + 358072 [3259675][E](PTable): Bottom failed at: (72) Target pos: (54.253338) Avg pos: (63) + 358073 [3259676][E](PTable): Was not in range failed bottom (8)(2)(72), readings (1) + 358074 [3259686][E](PTable): WEIGHTED DOWNVOTING: Target Value: (54), NeighborValue: (72) + 358075 [3259697][E](PTable): WEIGHTED DOWNVOTING: Delta: (18), Penalty: (3) + 358076 [3259697][E](PTable): PT failed (8)(2)(72), readings (0) + 358077 [3259709][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358078 [3259734][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 358079 [3259766][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 358080 [3259787][E](PTable): 70 rpm | 60 | 80 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 358081 [3259820][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 358082 [3259842][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 358083 [3259874][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 358084 [3259895][E](Custom_C): 01 19 <-targetPosition + 358085 [3259899][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 358086 [3259933][E](PTable): 95 rpm | | | | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 358087 [3259955][E](PTable): 100 rpm | | | 72 | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 358088 [3259977][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 358089 [3260096][E](PTable): Writing File: /PowerTable.txt + 358090 [3260499][E](PTable): Power table saved successfully with 97 readings + 358091 [3260499][E](PTable): Power Table Reset + 358092 [3260604][E](PTable): Success! + 358093 [3260903][E](Custom_C): 01 27 00 <-Power Tab Data + 358094 [3260969][E](Custom_C): 01 2a <-hMin + 358095 [3261014][E](Custom_C): 01 19 <-targetPosition + 358096 [3261083][E](Custom_C): 01 27 01 <-Power Tab Data + 358097 [3261126][E](Custom_C): 01 2b <-hMax + 358098 [3261206][E](Custom_C): 01 27 02 <-Power Tab Data + 358099 [3261264][E](Custom_C): 01 27 03 <-Power Tab Data + 358100 [3261309][E](PTable): Success! + 358101 [3261319][E](Custom_C): 01 27 04 <-Power Tab Data + 358102 [3261386][E](Custom_C): 01 27 05 <-Power Tab Data + 358103 [3261442][E](Custom_C): 01 27 06 <-Power Tab Data + 358104 [3261532][E](Custom_C): 01 27 07 <-Power Tab Data + 358105 [3261589][E](Custom_C): 01 27 08 <-Power Tab Data + 358106 [3261656][E](Custom_C): 01 27 09 <-Power Tab Data + 358107 [3261892][E](Custom_C): 01 19 <-targetPosition + 358108 [3262011][E](PTable): Success! + 358109 [3262275][E](Custom_C): 01 25 <-Firmware Version + 358110 [3262714][E](PTable): Success! + 358111 [3262715][E](PTable): Clean Power Table + 358112 [3262715][E](PTable): Averaged Entry: watts=49.599998, cad=70.800003, targetPosition=790.00000, (2)(2) + 358113 [3262726][E](PTable): Keep old targetPosition: (79.000000) + 358114 [3262727][E](PTable): Left failed at: (80) Target pos: (79.000000) Avg pos: (79) + 358115 [3262738][E](PTable): Current Position moved left was valid! Current position: 79.000000 + 358116 [3262749][E](PTable): Existing entry averaged (2)(1)(79), readings(9) + 358117 [3262881][E](Custom_C): 01 19 <-targetPosition + 358118 [3263089][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358119 [3263112][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 233 | 234 | | | | | | | 235 | 236 | | | | | | | | | | + 358120 [3263134][E](PTable): 65 rpm | 72 | 85 | 102 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | | | | | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | | | | | | | | | | + 358121 [3263166][E](PTable): 70 rpm | 60 | 79 | 101 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | | | | | 214 | 215 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | | | | | | | | | | + 358122 [3263188][E](PTable): 75 rpm | 48 | 64 | 100 | 102 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | | | 205 | 206 | 207 | | 208 | | | 209 | | 210 | | | | | | | | | | | + 358123 [3263220][E](PTable): 80 rpm | 36 | 58 | 99 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 178 | 191 | 195 | 197 | | 198 | 199 | | | 200 | 203 | 213 | | 219 | | | | | | | | | | | | + 358124 [3263242][E](PTable): 85 rpm | | 24 | 98 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 188 | 190 | 192 | 194 | 195 | 196 | 198 | 202 | 206 | 207 | 218 | | | | | | | | | | | | + 358125 [3263274][E](PTable): 90 rpm | 12 | 18 | 96 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | 179 | 182 | 185 | 186 | | | 187 | 191 | 195 | 196 | 206 | 217 | | 224 | | | | | | | | | | + 358126 [3263296][E](PTable): 95 rpm | 0 | 12 | 95 | 98 | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 164 | 171 | 174 | 177 | 179 | | | | 180 | 181 | 192 | 193 | 205 | 216 | | 223 | | | | | | | | | | + 358127 [3263328][E](PTable): 100 rpm | -12 | 11 | 93 | 96 | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 173 | 176 | 189 | 190 | 204 | 215 | | 222 | | | | | | | | | | + 358128 [3263350][E](PTable): 105 rpm | -24 | 10 | 91 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 158 | 163 | 165 | 167 | | | | 168 | 169 | 170 | 187 | | 203 | 214 | | 221 | | | | | | | | | | + 358129 [3263381][E](PTable): Power Table Reset + 358130 [3263419][E](PTable): Success! + 358131 [3263895][E](Custom_C): 01 19 <-targetPosition + 358132 [3264120][E](PTable): Success! + 358133 [3264825][E](PTable): Success! + 358134 [3264885][E](Custom_C): 01 19 <-targetPosition + 358135 [3265527][E](PTable): Success! + 358136 [3265528][E](PTable): Clean Power Table + 358137 [3265528][E](PTable): Averaged Entry: watts=43.599998, cad=87.800003, targetPosition=790.00000, (6)(1) + 358138 [3265540][E](PTable): Keep old targetPosition: (79.000000) + 358139 [3265540][E](PTable): Top failed at: (24) Target pos: (79.000000) Avg pos: (51) + 358140 [3265551][E](PTable): Was not in range failed top (5)(1)(24), readings (1) + 358141 [3265551][E](PTable): WEIGHTED DOWNVOTING: Target Value: (79), NeighborValue: (24) + 358142 [3265562][E](PTable): WEIGHTED DOWNVOTING: Delta: (55), Penalty: (11) + 358143 [3265572][E](PTable): PT failed (5)(1)(24), readings (0) + 358144 [3265575][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358145 [3265606][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 358146 [3265628][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 358147 [3265662][E](PTable): 70 rpm | 60 | 79 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 358148 [3265684][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 358149 [3265706][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 358150 [3265738][E](PTable): 85 rpm | | 24 | | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 358151 [3265771][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 358152 [3265793][E](PTable): 95 rpm | | | | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | | | | | | | | | | | | | | | | | | | | | | | | | | + 358153 [3265815][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 358154 [3265847][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 358155 [3265868][E](PTable): Power Table Reset + 358156 [3265930][E](Custom_C): 01 2a <-hMin + 358157 [3265988][E](Custom_C): 01 19 <-targetPosition + 358158 [3266054][E](Custom_C): 01 2b <-hMax + 358159 [3266122][E](Custom_C): 01 25 <-Firmware Version + 358160 [3266232][E](PTable): Success! + 358161 [3266932][E](Custom_C): 01 19 <-targetPosition + 358162 [3266936][E](PTable): Success! + 358163 [3267637][E](PTable): Success! + 358164 [3267921][E](Custom_C): 01 19 <-targetPosition + 358165 [3267969][E](Main): Shift +1 pos 7 tgt 9170 min 0 max 29285 r_min -2000 r_max 2000 + 358166 [3267970][E](Custom_C): 01 17 <-shifterPosition + 358167 [3268338][E](PTable): Success! + 358168 [3268339][E](PTable): Clean Power Table + 358169 [3268339][E](PTable): Averaged Entry: watts=73.199997, cad=93.400002, targetPosition=794.00002, (7)(2) + 358170 [3268350][E](PTable): Keep old targetPosition: (79.400002) + 358171 [3268351][E](PTable): New entry recorded (7)(2)(79) + 358172 [3268757][E](Custom_C): 01 27 07 <-Power Tab Data + 358173 [3268763][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358174 [3268785][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 233 | 234 | | | | | | | 235 | 236 | | | | | | | | | | + 358175 [3268817][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | | | | | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | | | | | | | | | | + 358176 [3268839][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | | | | | 214 | 215 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | | | | | | | | | | + 358177 [3268871][E](PTable): 75 rpm | 48 | 64 | 93 | 101 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | | | 205 | 206 | 207 | | 208 | | | 209 | | 210 | | | | | | | | | | | + 358178 [3268892][E](Custom_C): 01 19 <-targetPosition + 358179 [3268905][E](PTable): 80 rpm | 36 | 58 | 89 | 97 | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 178 | 191 | 195 | 197 | | 198 | 199 | | | 200 | 203 | 213 | | 219 | | | | | | | | | | | | + 358180 [3268927][E](PTable): 85 rpm | 24 | 55 | 86 | | 104 | 108 | 122 | 132 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 188 | 190 | 192 | 194 | 195 | 196 | 198 | 202 | 206 | 207 | 218 | | | | | | | | | | | | + 358181 [3268950][E](PTable): 90 rpm | 12 | 52 | 82 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | 179 | 182 | 185 | 186 | | | 187 | 191 | 195 | 196 | 206 | 217 | | 224 | | | | | | | | | | + 358182 [3268982][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 164 | 171 | 174 | 177 | 179 | | | | 180 | 181 | 192 | 193 | 205 | 216 | | 223 | | | | | | | | | | + 358183 [3269005][E](PTable): 100 rpm | -12 | 46 | 77 | 96 | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 173 | 176 | 189 | 190 | 204 | 215 | | 222 | | | | | | | | | | + 358184 [3269041][E](PTable): 105 rpm | -24 | 45 | 75 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 158 | 163 | 165 | 167 | | | | 168 | 169 | 170 | 187 | | 203 | 214 | | 221 | | | | | | | | | | + 358185 [3269063][E](PTable): Power Table Reset + 358186 [3269064][E](Main): Shift +2 pos 9 tgt 9170 min 0 max 29285 r_min -2000 r_max 2000 + 358187 [3269076][E](Custom_C): 01 17 <-shifterPosition + 358188 [3269222][E](Main): Shift +1 pos 10 tgt 12800 min 0 max 29285 r_min -2000 r_max 2000 + 358189 [3269225][E](Custom_C): 01 17 <-shifterPosition + 358190 [3269701][E](Main): Shift +1 pos 11 tgt 14010 min 0 max 29285 r_min -2000 r_max 2000 + 358191 [3269702][E](Custom_C): 01 17 <-shifterPosition + 358192 [3269867][E](PTable): Success! + 358193 [3269890][E](Custom_C): 01 19 <-targetPosition + 358194 [3270201][E](Main): Shift +1 pos 12 tgt 15220 min 0 max 29285 r_min -2000 r_max 2000 + 358195 [3270202][E](Custom_C): 01 17 <-shifterPosition + 358196 [3270570][E](PTable): Power Table Reset + 358197 [3270718][E](Main): Shift +1 pos 13 tgt 16430 min 0 max 29285 r_min -2000 r_max 2000 + 358198 [3270720][E](Custom_C): 01 17 <-shifterPosition + 358199 [3270914][E](Custom_C): 01 2a <-hMin + 358200 [3270970][E](Custom_C): 01 19 <-targetPosition + 358201 [3271027][E](Custom_C): 01 2b <-hMax + 358202 [3271273][E](PTable): Success! + 358203 [3271881][E](Custom_C): 01 19 <-targetPosition + 358204 [3271975][E](PTable): Power Table Reset + 358205 [3272676][E](PTable): Success! + 358206 [3272894][E](Custom_C): 01 19 <-targetPosition + 358207 [3273381][E](PTable): Success! + 358208 [3273884][E](Custom_C): 01 19 <-targetPosition + 358209 [3274085][E](PTable): Success! + 358210 [3274787][E](PTable): Success! + 358211 [3274788][E](PTable): Clean Power Table + 358212 [3274788][E](PTable): Averaged Entry: watts=205.199997, cad=84.199997, targetPosition=1640.00000, (5)(7) + 358213 [3274799][E](PTable): cellValue: (132) wattDelta: (0.937500) cadDelta: (0.156250) allNeighborsPassed: (0) + 358214 [3274810][E](PTable): rightValue: (0.000000) leftValue: (137.119995) bottomValue: (126.879982) topValue: (0.000000) New averaged targetPosition: (131.999985) count: (2) + 358215 [3274821][E](PTable): Existing entry averaged (5)(7)(131), readings(9) + 358216 [3274908][E](Custom_C): 01 19 <-targetPosition + 358217 [3275190][E](Custom_C): 01 27 05 <-Power Tab Data + 358218 [3275195][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358219 [3275217][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 233 | 234 | | | | | | | 235 | 236 | | | | | | | | | | + 358220 [3275250][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | | | | | 222 | 224 | 226 | 228 | 230 | 232 | 233 | 234 | | | | | | | | | | + 358221 [3275271][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | | | | | 214 | 215 | 216 | 217 | 218 | 219 | 221 | 223 | 225 | | | | | | | | | | + 358222 [3275304][E](PTable): 75 rpm | 48 | 64 | 93 | 101 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | | | 205 | 206 | 207 | | 208 | | | 209 | | 210 | | | | | | | | | | | + 358223 [3275325][E](PTable): 80 rpm | 36 | 58 | 89 | 97 | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 178 | 191 | 195 | 197 | | 198 | 199 | | | 200 | 203 | 213 | | 219 | | | | | | | | | | | | + 358224 [3275357][E](PTable): 85 rpm | 24 | 55 | 86 | | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 188 | 190 | 192 | 194 | 195 | 196 | 198 | 202 | 206 | 207 | 218 | | | | | | | | | | | | + 358225 [3275379][E](PTable): 90 rpm | 12 | 52 | 82 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 168 | 176 | 179 | 182 | 185 | 186 | | | 187 | 191 | 195 | 196 | 206 | 217 | | 224 | | | | | | | | | | + 358226 [3275411][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 164 | 171 | 174 | 177 | 179 | | | | 180 | 181 | 192 | 193 | 205 | 216 | | 223 | | | | | | | | | | + 358227 [3275433][E](PTable): 100 rpm | -12 | 46 | 77 | 96 | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 173 | 176 | 189 | 190 | 204 | 215 | | 222 | | | | | | | | | | + 358228 [3275465][E](PTable): 105 rpm | -24 | 45 | 75 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 158 | 163 | 165 | 167 | | | | 168 | 169 | 170 | 187 | | 203 | 214 | | 221 | | | | | | | | | | + 358229 [3275486][E](PTable): Power Table Reset + 358230 [3275568][E](PTable): Success! + 358231 [3275902][E](Custom_C): 01 27 00 <-Power Tab Data + 358232 [3275932][E](Custom_C): 01 2a <-hMin + 358233 [3275976][E](Custom_C): 01 19 <-targetPosition + 358234 [3276033][E](Custom_C): 01 27 01 <-Power Tab Data + 358235 [3276066][E](Custom_C): 01 2b <-hMax + 358236 [3276124][E](Custom_C): 01 27 02 <-Power Tab Data + 358237 [3276169][E](Custom_C): 01 27 03 <-Power Tab Data + 358238 [3276237][E](Custom_C): 01 27 04 <-Power Tab Data + 358239 [3276270][E](PTable): Success! + 358240 [3276281][E](Custom_C): 01 27 05 <-Power Tab Data + 358241 [3276382][E](Custom_C): 01 27 06 <-Power Tab Data + 358242 [3276439][E](Custom_C): 01 27 07 <-Power Tab Data + 358243 [3276484][E](Custom_C): 01 27 08 <-Power Tab Data + 358244 [3276563][E](Custom_C): 01 27 09 <-Power Tab Data + 358245 [3276611][E](Main): Shift +1 pos 14 tgt 17640 min 0 max 29285 r_min -2000 r_max 2000 + 358246 [3276615][E](Custom_C): 01 17 <-shifterPosition + 358247 [3276910][E](Custom_C): 01 19 <-targetPosition + 358248 [3276971][E](PTable): Success! + 358249 [3277675][E](PTable): Success! + 358250 [3277678][E](PTable): Clean Power Table + 358251 [3277678][E](PTable): Averaged Entry: watts=419.200012, cad=92.800003, targetPosition=1666.00006, (7)(14) + 358252 [3277690][E](PTable): Keep old targetPosition: (166.600006) + 358253 [3277691][E](PTable): New entry recorded (7)(14)(166) + 358254 [3277890][E](Custom_C): 01 19 <-targetPosition + 358255 [3278068][E](Custom_C): 01 27 07 <-Power Tab Data + 358256 [3278073][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358257 [3278096][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358258 [3278128][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358259 [3278149][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358260 [3278182][E](PTable): 75 rpm | 48 | 64 | 93 | 101 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358261 [3278204][E](PTable): 80 rpm | 36 | 58 | 89 | 97 | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358262 [3278236][E](PTable): 85 rpm | 24 | 55 | 86 | | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358263 [3278258][E](PTable): 90 rpm | 12 | 52 | 82 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358264 [3278290][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358265 [3278312][E](PTable): 100 rpm | -12 | 46 | 77 | 96 | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358266 [3278344][E](PTable): 105 rpm | -24 | 45 | 75 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358267 [3278365][E](PTable): Power Table Reset + 358268 [3278393][E](PTable): Success! + 358269 [3278901][E](Custom_C): 01 19 <-targetPosition + 358270 [3279096][E](PTable): Success! + 358271 [3279797][E](PTable): Success! + 358272 [3279914][E](Custom_C): 01 19 <-targetPosition + 358273 [3280498][E](PTable): Success! + 358274 [3280499][E](PTable): Clean Power Table + 358275 [3280499][E](PTable): Averaged Entry: watts=539.599976, cad=98.000000, targetPosition=1760.00000, (8)(18) + 358276 [3280512][E](PTable): cellValue: (164) wattDelta: (2.500000) cadDelta: (0.416667) allNeighborsPassed: (1) + 358277 [3280513][E](PTable): rightValue: (163.839996) leftValue: (164.160004) bottomValue: (159.199997) topValue: (168.800003) New averaged targetPosition: (164.000000) count: (4) + 358278 [3280535][E](PTable): Existing entry averaged (8)(18)(164), readings(2) + 358279 [3280881][E](Custom_C): 01 2a <-hMin + 358280 [3280885][E](Custom_C): 01 27 08 <-Power Tab Data + 358281 [3280889][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358282 [3280912][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358283 [3280944][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358284 [3280986][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358285 [3281008][E](PTable): 75 rpm | 48 | 64 | 93 | 101 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358286 [3281032][E](PTable): 80 rpm | 36 | 58 | 89 | 97 | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358287 [3281082][E](PTable): 85 rpm | 24 | 55 | 86 | | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358288 [3281104][E](PTable): 90 rpm | 12 | 52 | 82 | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358289 [3281128][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358290 [3281160][E](PTable): 100 rpm | -12 | 46 | 77 | 96 | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358291 [3281181][E](PTable): 105 rpm | -24 | 45 | 75 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358292 [3281213][E](PTable): Power Table Reset + 358293 [3281213][E](Main): Shift -1 pos 13 tgt 17640 min 0 max 29285 r_min -2000 r_max 2000 + 358294 [3281226][E](Custom_C): 01 17 <-shifterPosition + 358295 [3281310][E](PTable): Success! + 358296 [3281625][E](Main): Shift -1 pos 12 tgt 15220 min 0 max 29285 r_min -2000 r_max 2000 + 358297 [3281626][E](Custom_C): 01 17 <-shifterPosition + 358298 [3281894][E](Custom_C): 01 19 <-targetPosition + 358299 [3282011][E](PTable): Success! + 358300 [3282276][E](Custom_C): 01 25 <-Firmware Version + 358301 [3282327][E](Main): Shift -1 pos 11 tgt 14010 min 0 max 29285 r_min -2000 r_max 2000 + 358302 [3282330][E](Custom_C): 01 17 <-shifterPosition + 358303 [3282716][E](PTable): Power Table Reset + 358304 [3282885][E](Custom_C): 01 19 <-targetPosition + 358305 [3283417][E](PTable): Success! + 358306 [3283896][E](Custom_C): 01 19 <-targetPosition + 358307 [3284120][E](PTable): Success! + 358308 [3284134][E](Main): Shift -1 pos 10 tgt 12800 min 0 max 29285 r_min -2000 r_max 2000 + 358309 [3284135][E](Custom_C): 01 17 <-shifterPosition + 358310 [3284824][E](PTable): Success! + 358311 [3284886][E](Custom_C): 01 19 <-targetPosition + 358312 [3285101][E](Main): Shift -1 pos 9 tgt 11590 min 0 max 29285 r_min -2000 r_max 2000 + 358313 [3285103][E](Custom_C): 01 17 <-shifterPosition + 358314 [3285526][E](PTable): Power Table Reset + 358315 [3285910][E](Custom_C): 01 2a <-hMin + 358316 [3285945][E](Custom_C): 01 19 <-targetPosition + 358317 [3285989][E](Custom_C): 01 2b <-hMax + 358318 [3286057][E](Custom_C): 01 25 <-Firmware Version + 358319 [3286227][E](PTable): Success! + 358320 [3286889][E](Custom_C): 01 19 <-targetPosition + 358321 [3286928][E](PTable): Success! + 358322 [3287009][E](Main): Shift -1 pos 8 tgt 10380 min 0 max 29285 r_min -2000 r_max 2000 + 358323 [3287011][E](Custom_C): 01 17 <-shifterPosition + 358324 [3287631][E](PTable): Success! + 358325 [3287632][E](PTable): Using detected travel limits during homing + 358326 [3287890][E](Custom_C): 01 19 <-targetPosition + 358327 [3288332][E](PTable): Success! + 358328 [3288333][E](PTable): Clean Power Table + 358329 [3288333][E](PTable): Averaged Entry: watts=172.800003, cad=91.199997, targetPosition=1114.00002, (6)(6) + 358330 [3288344][E](PTable): cellValue: (117) wattDelta: (5.357144) cadDelta: (0.892857) allNeighborsPassed: (0) + 358331 [3288356][E](PTable): rightValue: (104.456001) leftValue: (107.144005) bottomValue: (0.000000) topValue: (104.456009) New averaged targetPosition: (105.352013) count: (3) + 358332 [3288367][E](PTable): Left failed at: (106) Target pos: (105.352013) Avg pos: (105) + 358333 [3288377][E](PTable): All test failed left (6)(5)(106), readings (11) + 358334 [3288378][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (106) + 358335 [3288388][E](PTable): WEIGHTED DOWNVOTING: Delta: (1), Penalty: (0) + 358336 [3288389][E](PTable): PT failed (6)(5)(106), readings (11) + 358337 [3288399][E](PTable): Bottom failed at: (114) Target pos: (105.352013) Avg pos: (109) + 358338 [3288411][E](PTable): All test failed bottom (5)(6)(122), readings (11) + 358339 [3288411][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (114) + 358340 [3288421][E](PTable): WEIGHTED DOWNVOTING: Delta: (9), Penalty: (1) + 358341 [3288421][E](PTable): PT failed (7)(6)(114), readings (4) + 358342 [3288434][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358343 [3288456][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 358344 [3288490][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 358345 [3288511][E](PTable): 70 rpm | 60 | 79 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 358346 [3288543][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 358347 [3288565][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 358348 [3288599][E](PTable): 85 rpm | | | | | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 358349 [3288621][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 358350 [3288653][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 358351 [3288675][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 358352 [3288707][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 358353 [3288728][E](PTable): Power Table Reset + 358354 [3288891][E](Custom_C): 01 19 <-targetPosition + 358355 [3289033][E](PTable): Success! + 358356 [3289736][E](PTable): Success! + 358357 [3289881][E](Custom_C): 01 19 <-targetPosition + 358358 [3290442][E](PTable): Success! + 358359 [3290929][E](Custom_C): 01 27 00 <-Power Tab Data + 358360 [3291006][E](Custom_C): 01 2a <-hMin + 358361 [3291074][E](Custom_C): 01 19 <-targetPosition + 358362 [3291142][E](Custom_C): 01 27 01 <-Power Tab Data + 358363 [3291145][E](PTable): Success! + 358364 [3291145][E](PTable): Clean Power Table + 358365 [3291156][E](PTable): Averaged Entry: watts=89.599998, cad=86.599998, targetPosition=1030.00000, (5)(3) + 358366 [3291160][E](PTable): Keep old targetPosition: (103.000000) + 358367 [3291171][E](PTable): New entry recorded (5)(3)(103) + 358368 [3291186][E](Custom_C): 01 2b <-hMax + 358369 [3291243][E](Custom_C): 01 27 02 <-Power Tab Data + 358370 [3291289][E](Custom_C): 01 27 03 <-Power Tab Data + 358371 [3291333][E](Custom_C): 01 27 04 <-Power Tab Data + 358372 [3291390][E](Custom_C): 01 27 05 <-Power Tab Data + 358373 [3291446][E](Custom_C): 01 27 06 <-Power Tab Data + 358374 [3291503][E](Custom_C): 01 27 07 <-Power Tab Data + 358375 [3291559][E](Custom_C): 01 27 08 <-Power Tab Data + 358376 [3291592][E](Custom_C): 01 27 05 <-Power Tab Data + 358377 [3291598][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358378 [3291620][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358379 [3291676][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358380 [3291707][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358381 [3291729][E](PTable): 75 rpm | 48 | 64 | 93 | 104 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358382 [3291761][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358383 [3291784][E](PTable): 85 rpm | 24 | 55 | 86 | 103 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358384 [3291816][E](PTable): 90 rpm | 12 | 52 | 82 | 100 | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358385 [3291838][E](PTable): 95 rpm | 0 | 49 | 79 | 98 | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358386 [3291870][E](PTable): 100 rpm | -12 | 46 | 77 | 96 | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358387 [3291891][E](Custom_C): 01 19 <-targetPosition + 358388 [3291904][E](PTable): 105 rpm | -24 | 45 | 75 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358389 [3291925][E](PTable): Power Table Reset + 358390 [3292025][E](PTable): Success! + 358391 [3292729][E](PTable): Success! + 358392 [3292930][E](Custom_C): 01 19 <-targetPosition + 358393 [3293431][E](PTable): Success! + 358394 [3293886][E](Custom_C): 01 19 <-targetPosition + 358395 [3294135][E](PTable): Success! + 358396 [3294136][E](PTable): Clean Power Table + 358397 [3294136][E](PTable): Averaged Entry: watts=88.800003, cad=85.599998, targetPosition=1030.00000, (5)(3) + 358398 [3294147][E](PTable): Keep old targetPosition: (103.000000) + 358399 [3294148][E](PTable): Existing entry averaged (5)(3)(103), readings(1) + 358400 [3294506][E](Custom_C): 01 27 05 <-Power Tab Data + 358401 [3294512][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358402 [3294534][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358403 [3294566][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358404 [3294588][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358405 [3294619][E](PTable): 75 rpm | 48 | 64 | 93 | 104 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358406 [3294643][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358407 [3294675][E](PTable): 85 rpm | 24 | 55 | 86 | 103 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358408 [3294697][E](PTable): 90 rpm | 12 | 52 | 82 | 100 | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358409 [3294729][E](PTable): 95 rpm | 0 | 49 | 79 | 98 | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358410 [3294751][E](PTable): 100 rpm | -12 | 46 | 77 | 96 | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358411 [3294783][E](PTable): 105 rpm | -24 | 45 | 75 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358412 [3294803][E](PTable): Power Table Reset + 358413 [3294838][E](PTable): Success! + 358414 [3294910][E](Custom_C): 01 19 <-targetPosition + 358415 [3295542][E](PTable): Success! + 358416 [3295889][E](Custom_C): 01 2a <-hMin + 358417 [3295933][E](Custom_C): 01 19 <-targetPosition + 358418 [3295990][E](Custom_C): 01 2b <-hMax + 358419 [3296247][E](PTable): Success! + 358420 [3296902][E](Custom_C): 01 19 <-targetPosition + 358421 [3296952][E](PTable): Success! + 358422 [3296953][E](PTable): Clean Power Table + 358423 [3296953][E](PTable): Averaged Entry: watts=88.400002, cad=85.400002, targetPosition=1030.00000, (5)(3) + 358424 [3296965][E](PTable): Keep old targetPosition: (103.000000) + 358425 [3296965][E](PTable): Existing entry averaged (5)(3)(103), readings(2) + 358426 [3297318][E](Custom_C): 01 27 05 <-Power Tab Data + 358427 [3297323][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358428 [3297345][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358429 [3297378][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358430 [3297399][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358431 [3297431][E](PTable): 75 rpm | 48 | 64 | 93 | 104 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358432 [3297453][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358433 [3297485][E](PTable): 85 rpm | 24 | 55 | 86 | 103 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358434 [3297508][E](PTable): 90 rpm | 12 | 52 | 82 | 100 | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358435 [3297540][E](PTable): 95 rpm | 0 | 49 | 79 | 98 | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358436 [3297562][E](PTable): 100 rpm | -12 | 46 | 77 | 96 | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358437 [3297594][E](PTable): 105 rpm | -24 | 45 | 75 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358438 [3297615][E](PTable): Power Table Reset + 358439 [3297626][E](Main): Shift +1 pos 9 tgt 10380 min 0 max 29285 r_min -2000 r_max 2000 + 358440 [3297627][E](Custom_C): 01 17 <-shifterPosition + 358441 [3297697][E](PTable): Success! + 358442 [3297891][E](Custom_C): 01 19 <-targetPosition + 358443 [3298399][E](PTable): Success! + 358444 [3298904][E](Custom_C): 01 19 <-targetPosition + 358445 [3299105][E](PTable): Success! + 358446 [3299806][E](PTable): Success! + 358447 [3299807][E](PTable): Clean Power Table + 358448 [3299807][E](PTable): Averaged Entry: watts=86.000000, cad=87.199997, targetPosition=1094.00002, (5)(3) + 358449 [3299819][E](PTable): cellValue: (103) wattDelta: (4.687499) cadDelta: (0.781250) allNeighborsPassed: (0) + 358450 [3299830][E](PTable): rightValue: (0.000000) leftValue: (103.853333) bottomValue: (105.815994) topValue: (100.184006) New averaged targetPosition: (103.284447) count: (3) + 358451 [3299841][E](PTable): Existing entry averaged (5)(3)(103), readings(3) + 358452 [3299894][E](Custom_C): 01 19 <-targetPosition + 358453 [3300234][E](Custom_C): 01 27 05 <-Power Tab Data + 358454 [3300240][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358455 [3300262][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358456 [3300295][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358457 [3300318][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358458 [3300350][E](PTable): 75 rpm | 48 | 64 | 93 | 104 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358459 [3300372][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358460 [3300396][E](PTable): 85 rpm | 24 | 55 | 86 | 103 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358461 [3300429][E](PTable): 90 rpm | 12 | 52 | 82 | 100 | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358462 [3300450][E](PTable): 95 rpm | 0 | 49 | 79 | 98 | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358463 [3300482][E](PTable): 100 rpm | -12 | 46 | 77 | 96 | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358464 [3300504][E](PTable): 105 rpm | -24 | 45 | 75 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358465 [3300535][E](PTable): Power Table Reset + 358466 [3300552][E](PTable): Success! + 358467 [3300907][E](Custom_C): 01 2a <-hMin + 358468 [3300951][E](Custom_C): 01 19 <-targetPosition + 358469 [3301031][E](Custom_C): 01 2b <-hMax + 358470 [3301255][E](PTable): Success! + 358471 [3301896][E](Custom_C): 01 19 <-targetPosition + 358472 [3301956][E](PTable): Success! + 358473 [3302290][E](Custom_C): 01 25 <-Firmware Version + 358474 [3302657][E](PTable): Success! + 358475 [3302658][E](PTable): Clean Power Table + 358476 [3302658][E](PTable): Averaged Entry: watts=110.800003, cad=86.199997, targetPosition=1150.00000, (5)(4) + 358477 [3302670][E](PTable): cellValue: (104) wattDelta: (2.727273) cadDelta: (0.454545) allNeighborsPassed: (0) + 358478 [3302681][E](PTable): rightValue: (0.000000) leftValue: (107.373329) bottomValue: (106.639992) topValue: (0.000000) New averaged targetPosition: (107.006660) count: (2) + 358479 [3302693][E](PTable): Top failed at: (105) Target pos: (107.006660) Avg pos: (106) + 358480 [3302703][E](PTable): All test failed top (4)(4)(105), readings (11) + 358481 [3302704][E](PTable): WEIGHTED DOWNVOTING: Target Value: (107), NeighborValue: (105) + 358482 [3302715][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 358483 [3302716][E](PTable): PT failed (4)(4)(105), readings (11) + 358484 [3302731][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358485 [3302753][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 358486 [3302775][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 358487 [3302806][E](PTable): 70 rpm | 60 | 79 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 358488 [3302839][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 358489 [3302860][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 358490 [3302891][E](Custom_C): 01 19 <-targetPosition + 358491 [3302896][E](PTable): 85 rpm | | | | 103 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 358492 [3302918][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 358493 [3302950][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 358494 [3302972][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 358495 [3303003][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 358496 [3303024][E](PTable): Power Table Reset + 358497 [3303360][E](PTable): Success! + 358498 [3303910][E](Custom_C): 01 19 <-targetPosition + 358499 [3304061][E](PTable): Success! + 358500 [3304122][E](FTMS_SERVER): 05 82 00 -> ERG Mode Target: 130 Current: 108 Incline: 1.000000 + 358501 [3304130][E](Custom_C): 01 10 <-FTMSMode + 358502 [3304762][E](PTable): Success! + 358503 [3304763][E](ERG_Mode): Proportional: 72.000000, Integral: -4.200000, Derivative: 4.600000 + 358504 [3304890][E](Custom_C): 01 19 <-targetPosition + 358505 [3305467][E](PTable): Success! + 358506 [3305468][E](PTable): Clean Power Table + 358507 [3305468][E](PTable): Averaged Entry: watts=113.599998, cad=85.000000, targetPosition=1151.99997, (5)(4) + 358508 [3305480][E](PTable): cellValue: (104) wattDelta: (2.678572) cadDelta: (0.446429) allNeighborsPassed: (0) + 358509 [3305491][E](PTable): rightValue: (0.000000) leftValue: (106.389336) bottomValue: (104.000000) topValue: (0.000000) New averaged targetPosition: (105.194672) count: (2) + 358510 [3305502][E](PTable): Top failed at: (105) Target pos: (105.194672) Avg pos: (105) + 358511 [3305513][E](PTable): Was not in range failed top (4)(4)(105), readings (11) + 358512 [3305513][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (105) + 358513 [3305524][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 358514 [3305524][E](PTable): PT failed (4)(4)(105), readings (11) + 358515 [3305536][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358516 [3305558][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 358517 [3305590][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 358518 [3305612][E](PTable): 70 rpm | 60 | 79 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 358519 [3305644][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 358520 [3305665][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 358521 [3305697][E](PTable): 85 rpm | | | | 103 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 358522 [3305720][E](PTable): 90 rpm | | | | | 103 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 358523 [3305751][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 358524 [3305773][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 358525 [3305805][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 358526 [3305826][E](PTable): Power Table Reset + 358527 [3305905][E](Custom_C): 01 27 00 <-Power Tab Data + 358528 [3305946][E](Custom_C): 01 2a <-hMin + 358529 [3305991][E](Custom_C): 01 19 <-targetPosition + 358530 [3306049][E](Custom_C): 01 27 01 <-Power Tab Data + 358531 [3306092][E](Custom_C): 01 2b <-hMax + 358532 [3306185][E](Custom_C): 01 27 02 <-Power Tab Data + 358533 [3306207][E](PTable): Success! + 358534 [3306276][E](Custom_C): 01 27 03 <-Power Tab Data + 358535 [3306323][E](Custom_C): 01 27 04 <-Power Tab Data + 358536 [3306388][E](Custom_C): 01 27 05 <-Power Tab Data + 358537 [3306443][E](Custom_C): 01 27 06 <-Power Tab Data + 358538 [3306499][E](Custom_C): 01 27 07 <-Power Tab Data + 358539 [3306544][E](Custom_C): 01 27 08 <-Power Tab Data + 358540 [3306589][E](Custom_C): 01 27 09 <-Power Tab Data + 358541 [3306645][E](Custom_C): 01 25 <-Firmware Version + 358542 [3306892][E](Custom_C): 01 19 <-targetPosition + 358543 [3306912][E](PTable): Success! + 358544 [3307613][E](PTable): Success! + 358545 [3307881][E](Custom_C): 01 19 <-targetPosition + 358546 [3308318][E](PTable): Success! + 358547 [3308319][E](PTable): Clean Power Table + 358548 [3308319][E](PTable): Averaged Entry: watts=111.599998, cad=82.599998, targetPosition=1168.00003, (5)(4) + 358549 [3308330][E](PTable): cellValue: (104) wattDelta: (2.343750) cadDelta: (0.390625) allNeighborsPassed: (0) + 358550 [3308341][E](PTable): rightValue: (0.000000) leftValue: (107.584000) bottomValue: (97.855995) topValue: (0.000000) New averaged targetPosition: (102.720001) count: (2) + 358551 [3308352][E](PTable): Left failed at: (103) Target pos: (102.720001) Avg pos: (102) + 358552 [3308363][E](PTable): Current Position moved left was valid! Current position: 102.720001 + 358553 [3308364][E](PTable): Existing entry averaged (5)(3)(102), readings(4) + 358554 [3308712][E](PTable): Bottom failed at: (103) Target pos: (102.720001) Avg pos: (102) + 358555 [3308714][E](PTable): Current Position moved down is valid! Current position: 102.720001 + 358556 [3308725][E](PTable): Existing entry averaged (6)(4)(102), readings(9) + 358557 [3308849][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358558 [3308871][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358559 [3308902][E](Custom_C): 01 19 <-targetPosition + 358560 [3308906][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358561 [3308928][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358562 [3308960][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358563 [3308983][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358564 [3309015][E](PTable): 85 rpm | 24 | 55 | 86 | 102 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358565 [3309036][E](PTable): 90 rpm | 12 | 52 | 82 | 100 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358566 [3309068][E](PTable): 95 rpm | 0 | 49 | 79 | 98 | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358567 [3309090][E](PTable): 100 rpm | -12 | 46 | 77 | 96 | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358568 [3309122][E](PTable): 105 rpm | -24 | 45 | 75 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358569 [3309143][E](PTable): Power Table Reset + 358570 [3309174][E](BLE_Client): HRM battery updated 100 + 358571 [3309190][E](PTable): Success! + 358572 [3309884][E](Custom_C): 01 19 <-targetPosition + 358573 [3309893][E](PTable): Success! + 358574 [3309894][E](ERG_Mode): Proportional: 40.000000, Integral: 2.800000, Derivative: 0.400000 + 358575 [3310596][E](PTable): Success! + 358576 [3310896][E](Custom_C): 01 2a <-hMin + 358577 [3310986][E](Custom_C): 01 19 <-targetPosition + 358578 [3311031][E](Custom_C): 01 2b <-hMax + 358579 [3311301][E](PTable): Success! + 358580 [3311302][E](PTable): Clean Power Table + 358581 [3311302][E](PTable): Averaged Entry: watts=120.000000, cad=82.599998, targetPosition=1185.99998, (5)(4) + 358582 [3311314][E](PTable): cellValue: (104) wattDelta: (2.054795) cadDelta: (0.342466) allNeighborsPassed: (0) + 358583 [3311324][E](PTable): rightValue: (0.000000) leftValue: (104.000000) bottomValue: (96.991997) topValue: (0.000000) New averaged targetPosition: (100.496002) count: (2) + 358584 [3311336][E](PTable): Left failed at: (102) Target pos: (100.496002) Avg pos: (101) + 358585 [3311347][E](PTable): Current Position moved left was valid! Current position: 100.496002 + 358586 [3311348][E](PTable): Existing entry averaged (5)(3)(101), readings(5) + 358587 [3311684][E](PTable): Bottom failed at: (102) Target pos: (100.496002) Avg pos: (101) + 358588 [3311685][E](PTable): All test failed bottom (4)(4)(105), readings (11) + 358589 [3311695][E](PTable): WEIGHTED DOWNVOTING: Target Value: (100), NeighborValue: (102) + 358590 [3311696][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 358591 [3311706][E](PTable): PT failed (6)(4)(102), readings (10) + 358592 [3311709][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358593 [3311741][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358594 [3311763][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358595 [3311795][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358596 [3311817][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358597 [3311849][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358598 [3311871][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358599 [3311919][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358600 [3311941][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358601 [3311973][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358602 [3311996][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358603 [3312027][E](PTable): Power Table Reset + 358604 [3312123][E](PTable): Success! + 358605 [3312827][E](PTable): Success! + 358606 [3312911][E](Custom_C): 01 19 <-targetPosition + 358607 [3313531][E](PTable): Success! + 358608 [3313934][E](Custom_C): 01 19 <-targetPosition + 358609 [3314234][E](PTable): Success! + 358610 [3314235][E](PTable): Clean Power Table + 358611 [3314235][E](PTable): Averaged Entry: watts=116.000000, cad=79.800003, targetPosition=1195.99998, (4)(4) + 358612 [3314247][E](PTable): cellValue: (105) wattDelta: (2.054795) cadDelta: (0.342466) allNeighborsPassed: (0) + 358613 [3314259][E](PTable): rightValue: (0.000000) leftValue: (106.946671) bottomValue: (104.416008) topValue: (0.000000) New averaged targetPosition: (105.681335) count: (2) + 358614 [3314270][E](PTable): Existing entry averaged (4)(4)(105), readings(11) + 358615 [3314615][E](Custom_C): 01 27 04 <-Power Tab Data + 358616 [3314620][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358617 [3314642][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358618 [3314675][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358619 [3314696][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358620 [3314729][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358621 [3314751][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358622 [3314783][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358623 [3314806][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358624 [3314838][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358625 [3314859][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358626 [3314890][E](Custom_C): 01 19 <-targetPosition + 358627 [3314894][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358628 [3314915][E](PTable): Power Table Reset + 358629 [3314927][E](ERG_Mode): Proportional: 40.000000, Integral: 7.000000, Derivative: -0.200000 + 358630 [3314947][E](PTable): Success! + 358631 [3315651][E](PTable): Success! + 358632 [3315891][E](Custom_C): 01 2a <-hMin + 358633 [3315970][E](Custom_C): 01 19 <-targetPosition + 358634 [3316003][E](Custom_C): 01 2b <-hMax + 358635 [3316354][E](PTable): Success! + 358636 [3316881][E](Custom_C): 01 19 <-targetPosition + 358637 [3317058][E](PTable): Success! + 358638 [3317059][E](PTable): Clean Power Table + 358639 [3317059][E](PTable): Averaged Entry: watts=108.400002, cad=76.800003, targetPosition=1211.99997, (3)(4) + 358640 [3317071][E](PTable): cellValue: (106) wattDelta: (1.973685) cadDelta: (0.328947) allNeighborsPassed: (0) + 358641 [3317082][E](PTable): rightValue: (100.122665) leftValue: (111.877335) bottomValue: (111.472008) topValue: (0.000000) New averaged targetPosition: (107.824005) count: (3) + 358642 [3317093][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 358643 [3317450][E](Custom_C): 01 27 03 <-Power Tab Data + 358644 [3317455][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358645 [3317478][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358646 [3317510][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358647 [3317533][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358648 [3317565][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358649 [3317587][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358650 [3317619][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358651 [3317641][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358652 [3317673][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358653 [3317695][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358654 [3317727][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358655 [3317748][E](PTable): Power Table Reset + 358656 [3317830][E](PTable): Success! + 358657 [3317917][E](Custom_C): 01 19 <-targetPosition + 358658 [3318535][E](PTable): Success! + 358659 [3318884][E](Custom_C): 01 19 <-targetPosition + 358660 [3319236][E](PTable): Success! + 358661 [3319897][E](Custom_C): 01 19 <-targetPosition + 358662 [3319938][E](PTable): Success! + 358663 [3319939][E](PTable): Clean Power Table + 358664 [3319940][E](PTable): Averaged Entry: watts=126.800003, cad=75.599998, targetPosition=1225.99998, (3)(4) + 358665 [3319952][E](PTable): cellValue: (106) wattDelta: (1.807229) cadDelta: (0.301205) allNeighborsPassed: (0) + 358666 [3319952][E](PTable): rightValue: (109.762665) leftValue: (102.237335) bottomValue: (107.991997) topValue: (0.000000) New averaged targetPosition: (106.664001) count: (3) + 358667 [3319973][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 358668 [3320317][E](Custom_C): 01 27 03 <-Power Tab Data + 358669 [3320323][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358670 [3320347][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358671 [3320379][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358672 [3320401][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358673 [3320433][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358674 [3320457][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358675 [3320479][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358676 [3320510][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358677 [3320532][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358678 [3320565][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358679 [3320587][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358680 [3320618][E](PTable): Power Table Reset + 358681 [3320618][E](ERG_Mode): Proportional: -96.000000, Integral: 3.600000, Derivative: -3.000000 + 358682 [3320651][E](PTable): Success! + 358683 [3320902][E](Custom_C): 01 27 00 <-Power Tab Data + 358684 [3320933][E](Custom_C): 01 2a <-hMin + 358685 [3321010][E](Custom_C): 01 19 <-targetPosition + 358686 [3321056][E](Custom_C): 01 27 01 <-Power Tab Data + 358687 [3321111][E](Custom_C): 01 2b <-hMax + 358688 [3321203][E](Custom_C): 01 27 02 <-Power Tab Data + 358689 [3321259][E](Custom_C): 01 27 03 <-Power Tab Data + 358690 [3321304][E](Custom_C): 01 27 04 <-Power Tab Data + 358691 [3321349][E](Custom_C): 01 27 05 <-Power Tab Data + 358692 [3321351][E](PTable): Success! + 358693 [3321416][E](Custom_C): 01 27 06 <-Power Tab Data + 358694 [3321462][E](Custom_C): 01 27 07 <-Power Tab Data + 358695 [3321529][E](Custom_C): 01 27 08 <-Power Tab Data + 358696 [3321573][E](Custom_C): 01 27 09 <-Power Tab Data + 358697 [3321910][E](Custom_C): 01 19 <-targetPosition + 358698 [3322052][E](PTable): Success! + 358699 [3322270][E](Custom_C): 01 25 <-Firmware Version + 358700 [3322757][E](PTable): Success! + 358701 [3322758][E](PTable): Clean Power Table + 358702 [3322758][E](PTable): Averaged Entry: watts=129.600006, cad=80.199997, targetPosition=1230.00000, (4)(4) + 358703 [3322769][E](PTable): cellValue: (105) wattDelta: (1.666667) cadDelta: (0.277778) allNeighborsPassed: (0) + 358704 [3322780][E](PTable): rightValue: (0.000000) leftValue: (99.239998) bottomValue: (105.719986) topValue: (0.000000) New averaged targetPosition: (102.479996) count: (2) + 358705 [3322791][E](PTable): Bottom failed at: (104) Target pos: (102.479996) Avg pos: (103) + 358706 [3322803][E](PTable): All test failed bottom (3)(4)(106), readings (11) + 358707 [3322804][E](PTable): WEIGHTED DOWNVOTING: Target Value: (102), NeighborValue: (104) + 358708 [3322814][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 358709 [3322814][E](PTable): PT failed (5)(4)(104), readings (11) + 358710 [3322826][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358711 [3322848][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 358712 [3322880][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 358713 [3322924][E](PTable): 70 rpm | 60 | 79 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 358714 [3322946][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 358715 [3322968][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 358716 [3323000][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 358717 [3323032][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 358718 [3323054][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 358719 [3323086][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 358720 [3323108][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 358721 [3323129][E](PTable): Power Table Reset + 358722 [3323460][E](PTable): Success! + 358723 [3323890][E](Custom_C): 01 19 <-targetPosition + 358724 [3324165][E](PTable): Success! + 358725 [3324166][E](PTable): Using detected travel limits during homing + 358726 [3324720][E](FTMS_SERVER): 05 a5 00 -> ERG Mode Target: 165 Current: 128 Incline: 125.489998 + 358727 [3324727][E](Custom_C): 01 28 <-targetWatts + 358728 [3324868][E](PTable): Success! + 358729 [3324869][E](PTable): Lookup debug 150 X1 210 X2 70 Y1 85 Y2 -28072604246195364063820075826250932951140220096738651177709611111789628805337813738277134655930821583266020455211250311654712986640939206168904234604429312 + 358730 [3324881][E](PTable): Lookup used neighbors L 124 R 146 R1 130 + 358731 [3324892][E](Custom_C): 01 19 <-targetPosition + 358732 [3324896][E](PTable): Lookup used neighbors U 143 D 122 R2 135 + 358733 [3324897][E](PTable): Lookup result: 165w 76cad 13100 + 358734 [3324908][E](ERG_Mode): SetPoint changed:165w PowerTable Result: 13100 + 358735 [3324914][E](PTable): Success! + 358736 [3324914][E](PTable): Clean Power Table + 358737 [3324914][E](PTable): Averaged Entry: watts=119.199997, cad=77.800003, targetPosition=1244.00002, (4)(4) + 358738 [3324925][E](PTable): cellValue: (105) wattDelta: (1.546392) cadDelta: (0.257732) allNeighborsPassed: (0) + 358739 [3324936][E](PTable): rightValue: (0.000000) leftValue: (105.517334) bottomValue: (96.464012) topValue: (0.000000) New averaged targetPosition: (100.990677) count: (2) + 358740 [3324948][E](PTable): Bottom failed at: (104) Target pos: (100.990677) Avg pos: (102) + 358741 [3324962][E](PTable): All test failed bottom (3)(4)(106), readings (11) + 358742 [3324963][E](PTable): WEIGHTED DOWNVOTING: Target Value: (100), NeighborValue: (104) + 358743 [3324973][E](PTable): WEIGHTED DOWNVOTING: Delta: (4), Penalty: (0) + 358744 [3324973][E](PTable): PT failed (5)(4)(104), readings (11) + 358745 [3324986][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358746 [3325007][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 358747 [3325039][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 358748 [3325061][E](PTable): 70 rpm | 60 | 79 | | 111 | 121 | 130 | 143 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 358749 [3325093][E](PTable): 75 rpm | 48 | 64 | | | 106 | 124 | | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 358750 [3325115][E](PTable): 80 rpm | | 58 | | | 105 | 118 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 358751 [3325149][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 358752 [3325171][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 358753 [3325203][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 358754 [3325225][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 358755 [3325259][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 358756 [3325280][E](PTable): Power Table Reset + 358757 [3325619][E](PTable): Success! + 358758 [3325620][E](ERG_Mode): Proportional: 212.000000, Integral: 11.300000, Derivative: 2.700000 + 358759 [3325881][E](Custom_C): 01 2a <-hMin + 358760 [3325926][E](Custom_C): 01 19 <-targetPosition + 358761 [3325994][E](Custom_C): 01 2b <-hMax + 358762 [3326027][E](Custom_C): 01 25 <-Firmware Version + 358763 [3326320][E](PTable): Success! + 358764 [3326916][E](Custom_C): 01 19 <-targetPosition + 358765 [3327025][E](PTable): Success! + 358766 [3327726][E](PTable): Success! + 358767 [3327727][E](PTable): Clean Power Table + 358768 [3327727][E](PTable): Averaged Entry: watts=118.400002, cad=75.400002, targetPosition=1316.00006, (3)(4) + 358769 [3327739][E](PTable): cellValue: (106) wattDelta: (1.171875) cadDelta: (0.195312) allNeighborsPassed: (0) + 358770 [3327750][E](PTable): rightValue: (0.000000) leftValue: (107.365334) bottomValue: (108.048004) topValue: (0.000000) New averaged targetPosition: (107.706665) count: (2) + 358771 [3327761][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 358772 [3327884][E](Custom_C): 01 19 <-targetPosition + 358773 [3328120][E](Custom_C): 01 27 03 <-Power Tab Data + 358774 [3328128][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358775 [3328150][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358776 [3328182][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358777 [3328204][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358778 [3328236][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 124 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358779 [3328258][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358780 [3328290][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358781 [3328311][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358782 [3328344][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358783 [3328365][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358784 [3328397][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358785 [3328418][E](PTable): Power Table Reset + 358786 [3328498][E](PTable): Success! + 358787 [3328896][E](Custom_C): 01 19 <-targetPosition + 358788 [3329201][E](PTable): Success! + 358789 [3329886][E](Custom_C): 01 19 <-targetPosition + 358790 [3329905][E](PTable): Success! + 358791 [3330610][E](PTable): Success! + 358792 [3330611][E](PTable): Clean Power Table + 358793 [3330611][E](PTable): Averaged Entry: watts=140.399994, cad=73.400002, targetPosition=1348.00003, (3)(5) + 358794 [3330623][E](PTable): cellValue: (124) wattDelta: (2.777777) cadDelta: (0.462963) allNeighborsPassed: (0) + 358795 [3330634][E](PTable): rightValue: (120.543999) leftValue: (127.456001) bottomValue: (120.544006) topValue: (0.000000) New averaged targetPosition: (122.848000) count: (3) + 358796 [3330645][E](PTable): Existing entry averaged (3)(5)(123), readings(11) + 358797 [3330921][E](Custom_C): 01 2a <-hMin + 358798 [3330966][E](Custom_C): 01 19 <-targetPosition + 358799 [3331034][E](Custom_C): 01 2b <-hMax + 358800 [3331053][E](Custom_C): 01 27 03 <-Power Tab Data + 358801 [3331059][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358802 [3331081][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358803 [3331113][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358804 [3331136][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358805 [3331168][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 123 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358806 [3331193][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358807 [3331215][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358808 [3331248][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358809 [3331269][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358810 [3331302][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358811 [3331325][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358812 [3331356][E](PTable): Power Table Reset + 358813 [3331356][E](ERG_Mode): Proportional: 92.000000, Integral: 8.300000, Derivative: -0.200000 + 358814 [3331385][E](PTable): Success! + 358815 [3331889][E](Custom_C): 01 19 <-targetPosition + 358816 [3332086][E](PTable): Success! + 358817 [3332788][E](PTable): Success! + 358818 [3332890][E](Custom_C): 01 19 <-targetPosition + 358819 [3333491][E](PTable): Success! + 358820 [3333492][E](PTable): Clean Power Table + 358821 [3333492][E](PTable): Averaged Entry: watts=159.600006, cad=72.400002, targetPosition=1363.99994, (2)(5) + 358822 [3333505][E](PTable): cellValue: (130) wattDelta: (4.687504) cadDelta: (0.781251) allNeighborsPassed: (1) + 358823 [3333515][E](PTable): rightValue: (132.048004) leftValue: (127.952003) bottomValue: (133.072006) topValue: (126.928001) New averaged targetPosition: (130.000000) count: (4) + 358824 [3333526][E](PTable): Existing entry averaged (2)(5)(130), readings(9) + 358825 [3333891][E](Custom_C): 01 19 <-targetPosition + 358826 [3333895][E](Custom_C): 01 27 02 <-Power Tab Data + 358827 [3333900][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358828 [3333932][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358829 [3333955][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358830 [3333977][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358831 [3334009][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 123 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358832 [3334031][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358833 [3334067][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358834 [3334089][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358835 [3334121][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358836 [3334143][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358837 [3334175][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358838 [3334196][E](PTable): Power Table Reset + 358839 [3334259][E](PTable): Success! + 358840 [3334904][E](Custom_C): 01 19 <-targetPosition + 358841 [3334963][E](PTable): Success! + 358842 [3335666][E](PTable): Success! + 358843 [3335908][E](Custom_C): 01 27 00 <-Power Tab Data + 358844 [3335950][E](Custom_C): 01 2a <-hMin + 358845 [3335983][E](Custom_C): 01 19 <-targetPosition + 358846 [3336064][E](Custom_C): 01 27 01 <-Power Tab Data + 358847 [3336096][E](Custom_C): 01 2b <-hMax + 358848 [3336165][E](Custom_C): 01 27 02 <-Power Tab Data + 358849 [3336221][E](Custom_C): 01 27 03 <-Power Tab Data + 358850 [3336267][E](Custom_C): 01 27 04 <-Power Tab Data + 358851 [3336334][E](Custom_C): 01 27 05 <-Power Tab Data + 358852 [3336369][E](PTable): Success! + 358853 [3336370][E](PTable): Clean Power Table + 358854 [3336370][E](PTable): Averaged Entry: watts=153.600006, cad=72.599998, targetPosition=1370.00000, (3)(5) + 358855 [3336381][E](PTable): cellValue: (123) wattDelta: (2.142857) cadDelta: (0.357143) allNeighborsPassed: (0) + 358856 [3336393][E](PTable): rightValue: (124.680000) leftValue: (121.320000) bottomValue: (116.279999) topValue: (0.000000) New averaged targetPosition: (120.760002) count: (3) + 358857 [3336441][E](PTable): Existing entry averaged (3)(5)(122), readings(11) + 358858 [3336502][E](Custom_C): 01 27 07 <-Power Tab Data + 358859 [3336582][E](Custom_C): 01 27 08 <-Power Tab Data + 358860 [3336626][E](Custom_C): 01 27 09 <-Power Tab Data + 358861 [3336880][E](Custom_C): 01 27 03 <-Power Tab Data + 358862 [3336885][E](Custom_C): 01 19 <-targetPosition + 358863 [3336892][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358864 [3336913][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358865 [3336946][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358866 [3336968][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358867 [3337000][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 122 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358868 [3337021][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358869 [3337055][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358870 [3337077][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358871 [3337109][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358872 [3337131][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358873 [3337164][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358874 [3337184][E](PTable): Power Table Reset + 358875 [3337185][E](ERG_Mode): Proportional: -12.000000, Integral: 5.700000, Derivative: -1.400000 + 358876 [3337211][E](PTable): Success! + 358877 [3337897][E](Custom_C): 01 19 <-targetPosition + 358878 [3337916][E](PTable): Success! + 358879 [3338618][E](PTable): Success! + 358880 [3338886][E](Custom_C): 01 19 <-targetPosition + 358881 [3339322][E](PTable): Success! + 358882 [3339323][E](PTable): Clean Power Table + 358883 [3339323][E](PTable): Averaged Entry: watts=162.399994, cad=73.199997, targetPosition=1380.00000, (3)(5) + 358884 [3339335][E](PTable): cellValue: (122) wattDelta: (1.875000) cadDelta: (0.312500) allNeighborsPassed: (0) + 358885 [3339346][E](PTable): rightValue: (128.613327) leftValue: (115.386673) bottomValue: (116.239990) topValue: (0.000000) New averaged targetPosition: (120.079994) count: (3) + 358886 [3339357][E](PTable): Existing entry averaged (3)(5)(121), readings(11) + 358887 [3339711][E](Custom_C): 01 27 03 <-Power Tab Data + 358888 [3339716][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358889 [3339738][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358890 [3339770][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 152 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358891 [3339792][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 143 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358892 [3339825][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 121 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358893 [3339847][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358894 [3339878][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358895 [3339923][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358896 [3339945][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358897 [3339967][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358898 [3339999][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358899 [3340020][E](PTable): Power Table Reset + 358900 [3340088][E](FTMS_SERVER): 05 a0 00 -> ERG Mode Target: 160 Current: 148 Incline: 139.110992 + 358901 [3340096][E](Custom_C): 01 28 <-targetWatts + 358902 [3340102][E](PTable): Success! + 358903 [3340805][E](PTable): Success! + 358904 [3340889][E](Custom_C): 01 2a <-hMin + 358905 [3340934][E](Custom_C): 01 19 <-targetPosition + 358906 [3340990][E](Custom_C): 01 2b <-hMax + 358907 [3341509][E](PTable): Success! + 358908 [3341891][E](Custom_C): 01 19 <-targetPosition + 358909 [3342212][E](PTable): Success! + 358910 [3342213][E](PTable): Clean Power Table + 358911 [3342213][E](PTable): Averaged Entry: watts=168.800003, cad=72.400002, targetPosition=1380.00000, (2)(6) + 358912 [3342225][E](PTable): cellValue: (143) wattDelta: (6.000000) cadDelta: (1.000000) allNeighborsPassed: (1) + 358913 [3342236][E](PTable): rightValue: (131.133331) leftValue: (134.866669) bottomValue: (135.399994) topValue: (130.600006) New averaged targetPosition: (133.000000) count: (4) + 358914 [3342247][E](PTable): Existing entry averaged (2)(6)(142), readings(11) + 358915 [3342306][E](Custom_C): 01 25 <-Firmware Version + 358916 [3342605][E](Custom_C): 01 27 02 <-Power Tab Data + 358917 [3342611][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358918 [3342632][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358919 [3342669][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358920 [3342691][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 142 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358921 [3342723][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 121 | 134 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358922 [3342744][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358923 [3342777][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358924 [3342798][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358925 [3342830][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358926 [3342852][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358927 [3342885][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358928 [3342927][E](PTable): Power Table Reset + 358929 [3342928][E](ERG_Mode): Proportional: -112.000000, Integral: 1.200000, Derivative: -0.800000 + 358930 [3342946][E](PTable): Success! + 358931 [3343649][E](PTable): Success! + 358932 [3343881][E](Custom_C): 01 19 <-targetPosition + 358933 [3344350][E](PTable): Success! + 358934 [3344905][E](Custom_C): 01 19 <-targetPosition + 358935 [3345051][E](PTable): Success! + 358936 [3345052][E](PTable): Clean Power Table + 358937 [3345052][E](PTable): Averaged Entry: watts=159.600006, cad=73.599998, targetPosition=1376.00006, (3)(5) + 358938 [3345064][E](PTable): cellValue: (121) wattDelta: (1.807228) cadDelta: (0.301205) allNeighborsPassed: (0) + 358939 [3345075][E](PTable): rightValue: (126.312004) leftValue: (115.687996) bottomValue: (116.351990) topValue: (0.000000) New averaged targetPosition: (119.450661) count: (3) + 358940 [3345086][E](PTable): Existing entry averaged (3)(5)(120), readings(11) + 358941 [3345443][E](Custom_C): 01 27 03 <-Power Tab Data + 358942 [3345448][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358943 [3345470][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358944 [3345502][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358945 [3345523][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 142 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358946 [3345555][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 120 | 134 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358947 [3345577][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358948 [3345609][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358949 [3345630][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358950 [3345662][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358951 [3345684][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358952 [3345716][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358953 [3345747][E](PTable): Power Table Reset + 358954 [3345815][E](PTable): Success! + 358955 [3345886][E](Custom_C): 01 2a <-hMin + 358956 [3345929][E](Custom_C): 01 19 <-targetPosition + 358957 [3345996][E](Custom_C): 01 2b <-hMax + 358958 [3346086][E](Custom_C): 01 25 <-Firmware Version + 358959 [3346519][E](PTable): Success! + 358960 [3346897][E](Custom_C): 01 19 <-targetPosition + 358961 [3347220][E](PTable): Success! + 358962 [3347910][E](Custom_C): 01 19 <-targetPosition + 358963 [3347923][E](PTable): Success! + 358964 [3347924][E](PTable): Clean Power Table + 358965 [3347924][E](PTable): Averaged Entry: watts=154.800003, cad=71.000000, targetPosition=1376.00006, (2)(5) + 358966 [3347937][E](PTable): cellValue: (130) wattDelta: (3.947365) cadDelta: (0.657894) allNeighborsPassed: (1) + 358967 [3347938][E](PTable): rightValue: (131.216003) leftValue: (128.783997) bottomValue: (131.520004) topValue: (128.479996) New averaged targetPosition: (130.000000) count: (4) + 358968 [3347959][E](PTable): Existing entry averaged (2)(5)(130), readings(10) + 358969 [3348316][E](Custom_C): 01 27 02 <-Power Tab Data + 358970 [3348320][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 358971 [3348343][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 358972 [3348375][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 358973 [3348396][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 142 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 358974 [3348429][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 120 | 134 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 358975 [3348450][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 358976 [3348482][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 358977 [3348504][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 358978 [3348536][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 358979 [3348558][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 358980 [3348589][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 358981 [3348610][E](PTable): Power Table Reset + 358982 [3348621][E](ERG_Mode): Proportional: -24.000000, Integral: 3.200000, Derivative: -2.000000 + 358983 [3348639][E](PTable): Success! + 358984 [3348926][E](Custom_C): 01 19 <-targetPosition + 358985 [3349341][E](PTable): Success! + 358986 [3349889][E](Custom_C): 01 19 <-targetPosition + 358987 [3350046][E](PTable): Success! + 358988 [3350747][E](PTable): Success! + 358989 [3350748][E](PTable): Clean Power Table + 358990 [3350748][E](PTable): Averaged Entry: watts=166.800003, cad=72.400002, targetPosition=1380.00000, (2)(6) + 358991 [3350759][E](PTable): cellValue: (142) wattDelta: (7.500000) cadDelta: (1.250000) allNeighborsPassed: (1) + 358992 [3350771][E](PTable): rightValue: (132.240005) leftValue: (135.759995) bottomValue: (135.919998) topValue: (132.080002) New averaged targetPosition: (134.000000) count: (4) + 358993 [3350782][E](PTable): Existing entry averaged (2)(6)(141), readings(11) + 358994 [3350903][E](Custom_C): 01 27 00 <-Power Tab Data + 358995 [3350946][E](Custom_C): 01 2a <-hMin + 358996 [3350991][E](Custom_C): 01 19 <-targetPosition + 358997 [3351059][E](Custom_C): 01 27 01 <-Power Tab Data + 358998 [3351081][E](Custom_C): 01 2b <-hMax + 358999 [3351138][E](Custom_C): 01 27 02 <-Power Tab Data + 359000 [3351184][E](Custom_C): 01 27 03 <-Power Tab Data + 359001 [3351206][E](Custom_C): 01 27 02 <-Power Tab Data + 359002 [3351211][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359003 [3351233][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359004 [3351270][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 150 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359005 [3351318][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359006 [3351353][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 120 | 133 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359007 [3351401][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 127 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359008 [3351434][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359009 [3351456][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359010 [3351519][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359011 [3351541][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359012 [3351578][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359013 [3351632][E](PTable): Power Table Reset + 359014 [3351673][E](Custom_C): 01 27 08 <-Power Tab Data + 359015 [3351739][E](PTable): Success! + 359016 [3351747][E](Custom_C): 01 27 09 <-Power Tab Data + 359017 [3351914][E](Custom_C): 01 19 <-targetPosition + 359018 [3352444][E](PTable): Success! + 359019 [3352881][E](Custom_C): 01 19 <-targetPosition + 359020 [3353148][E](PTable): Success! + 359021 [3353853][E](PTable): Success! + 359022 [3353854][E](PTable): Clean Power Table + 359023 [3353854][E](PTable): Averaged Entry: watts=175.199997, cad=73.400002, targetPosition=1371.99997, (3)(6) + 359024 [3353867][E](PTable): Keep old targetPosition: (137.199997) + 359025 [3353868][E](PTable): New entry recorded (3)(6)(137) + 359026 [3353894][E](Custom_C): 01 19 <-targetPosition + 359027 [3354227][E](Custom_C): 01 27 03 <-Power Tab Data + 359028 [3354234][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359029 [3354260][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359030 [3354282][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 149 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359031 [3354315][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359032 [3354336][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 120 | 137 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359033 [3354371][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 130 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359034 [3354393][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359035 [3354425][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359036 [3354446][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359037 [3354478][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359038 [3354500][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359039 [3354531][E](PTable): Power Table Reset + 359040 [3354531][E](ERG_Mode): Proportional: -8.000000, Integral: -2.200000, Derivative: 1.800000 + 359041 [3354560][E](FTMS_SERVER): 05 9b 00 -> ERG Mode Target: 155 Current: 170 Incline: 136.535995 + 359042 [3354569][E](Custom_C): 01 28 <-targetWatts + 359043 [3354571][E](PTable): Success! + 359044 [3354918][E](Custom_C): 01 19 <-targetPosition + 359045 [3355274][E](PTable): Success! + 359046 [3355897][E](Custom_C): 01 2a <-hMin + 359047 [3355941][E](Custom_C): 01 19 <-targetPosition + 359048 [3355978][E](PTable): Success! + 359049 [3356009][E](Custom_C): 01 2b <-hMax + 359050 [3356682][E](PTable): Success! + 359051 [3356683][E](PTable): Clean Power Table + 359052 [3356683][E](PTable): Averaged Entry: watts=166.399994, cad=73.800003, targetPosition=1353.99994, (3)(6) + 359053 [3356696][E](PTable): cellValue: (137) wattDelta: (18.749929) cadDelta: (3.124988) allNeighborsPassed: (1) + 359054 [3356697][E](PTable): rightValue: (133.074646) leftValue: (134.525330) bottomValue: (133.415985) topValue: (134.183990) New averaged targetPosition: (133.799988) count: (4) + 359055 [3356718][E](PTable): Existing entry averaged (3)(6)(135), readings(1) + 359056 [3356886][E](Custom_C): 01 19 <-targetPosition + 359057 [3357074][E](Custom_C): 01 27 03 <-Power Tab Data + 359058 [3357079][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359059 [3357101][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359060 [3357133][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 150 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359061 [3357155][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359062 [3357187][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 120 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359063 [3357210][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 118 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359064 [3357242][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359065 [3357264][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359066 [3357296][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359067 [3357320][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359068 [3357353][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359069 [3357374][E](PTable): Power Table Reset + 359070 [3357455][E](PTable): Success! + 359071 [3357910][E](Custom_C): 01 19 <-targetPosition + 359072 [3358158][E](PTable): Success! + 359073 [3358859][E](PTable): Success! + 359074 [3358890][E](Custom_C): 01 19 <-targetPosition + 359075 [3359562][E](PTable): Success! + 359076 [3359563][E](PTable): Clean Power Table + 359077 [3359564][E](PTable): Averaged Entry: watts=158.399994, cad=73.000000, targetPosition=1350.00000, (3)(5) + 359078 [3359576][E](PTable): cellValue: (120) wattDelta: (2.000000) cadDelta: (0.333333) allNeighborsPassed: (0) + 359079 [3359579][E](PTable): rightValue: (0.000000) leftValue: (115.800003) bottomValue: (114.000000) topValue: (0.000000) New averaged targetPosition: (114.900002) count: (2) + 359080 [3359600][E](PTable): Bottom failed at: (118) Target pos: (114.900002) Avg pos: (116) + 359081 [3359603][E](PTable): Current Position moved down is valid! Current position: 114.900002 + 359082 [3359614][E](PTable): Existing entry averaged (4)(5)(117), readings(11) + 359083 [3359891][E](Custom_C): 01 19 <-targetPosition + 359084 [3360004][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359085 [3360026][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359086 [3360058][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 150 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359087 [3360081][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359088 [3360103][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 120 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359089 [3360135][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 117 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359090 [3360156][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359091 [3360189][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359092 [3360210][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359093 [3360242][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359094 [3360265][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359095 [3360296][E](PTable): Power Table Reset + 359096 [3360297][E](ERG_Mode): Proportional: -36.000000, Integral: -5.600000, Derivative: -1.600000 + 359097 [3360327][E](PTable): Success! + 359098 [3360328][E](PTable): Using detected travel limits during homing + 359099 [3360914][E](Custom_C): 01 2a <-hMin + 359100 [3360981][E](Custom_C): 01 19 <-targetPosition + 359101 [3361030][E](PTable): Success! + 359102 [3361049][E](Custom_C): 01 2b <-hMax + 359103 [3361731][E](PTable): Success! + 359104 [3361882][E](Custom_C): 01 19 <-targetPosition + 359105 [3362264][E](Custom_C): 01 25 <-Firmware Version + 359106 [3362434][E](PTable): Success! + 359107 [3362435][E](PTable): Clean Power Table + 359108 [3362435][E](PTable): Averaged Entry: watts=155.199997, cad=73.800003, targetPosition=1351.99997, (3)(5) + 359109 [3362447][E](PTable): cellValue: (120) wattDelta: (1.973685) cadDelta: (0.328947) allNeighborsPassed: (0) + 359110 [3362457][E](PTable): rightValue: (0.000000) leftValue: (117.365334) bottomValue: (116.352005) topValue: (0.000000) New averaged targetPosition: (116.858673) count: (2) + 359111 [3362468][E](PTable): Bottom failed at: (117) Target pos: (116.858673) Avg pos: (116) + 359112 [3362479][E](PTable): Current Position moved down is valid! Current position: 116.858673 + 359113 [3362480][E](PTable): Existing entry averaged (4)(5)(116), readings(11) + 359114 [3362843][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359115 [3362865][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359116 [3362887][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 150 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359117 [3362938][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359118 [3362960][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 120 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359119 [3362982][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 116 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359120 [3363014][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359121 [3363036][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359122 [3363069][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359123 [3363090][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359124 [3363122][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359125 [3363143][E](PTable): Power Table Reset + 359126 [3363225][E](PTable): Success! + 359127 [3363884][E](Custom_C): 01 19 <-targetPosition + 359128 [3363928][E](PTable): Success! + 359129 [3364631][E](PTable): Success! + 359130 [3364930][E](Custom_C): 01 19 <-targetPosition + 359131 [3365332][E](PTable): Success! + 359132 [3365333][E](PTable): Clean Power Table + 359133 [3365333][E](PTable): Averaged Entry: watts=157.199997, cad=73.800003, targetPosition=1353.99994, (3)(5) + 359134 [3365338][E](PTable): cellValue: (120) wattDelta: (1.948053) cadDelta: (0.324675) allNeighborsPassed: (0) + 359135 [3365349][E](PTable): rightValue: (0.000000) leftValue: (116.304001) bottomValue: (116.304008) topValue: (0.000000) New averaged targetPosition: (116.304001) count: (2) + 359136 [3365370][E](PTable): Bottom failed at: (116) Target pos: (116.304001) Avg pos: (116) + 359137 [3365370][E](PTable): Was not in range failed bottom (4)(5)(116), readings (11) + 359138 [3365381][E](PTable): WEIGHTED DOWNVOTING: Target Value: (116), NeighborValue: (116) + 359139 [3365392][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 359140 [3365393][E](PTable): PT failed (4)(5)(116), readings (11) + 359141 [3365405][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359142 [3365427][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 359143 [3365460][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 359144 [3365481][E](PTable): 70 rpm | 60 | 79 | | 111 | 121 | 130 | 141 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 359145 [3365504][E](PTable): 75 rpm | 48 | 64 | | | 106 | 120 | 135 | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 359146 [3365536][E](PTable): 80 rpm | | 58 | | | 105 | 116 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 359147 [3365558][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 359148 [3365590][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 359149 [3365613][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 359150 [3365647][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 359151 [3365668][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 359152 [3365699][E](PTable): Power Table Reset + 359153 [3365700][E](ERG_Mode): Proportional: 20.000000, Integral: -4.300000, Derivative: 0.200000 + 359154 [3365899][E](Custom_C): 01 27 00 <-Power Tab Data + 359155 [3365954][E](Custom_C): 01 2a <-hMin + 359156 [3366033][E](PTable): Success! + 359157 [3366044][E](Custom_C): 01 19 <-targetPosition + 359158 [3366101][E](Custom_C): 01 27 01 <-Power Tab Data + 359159 [3366156][E](Custom_C): 01 2b <-hMax + 359160 [3366213][E](Custom_C): 01 27 02 <-Power Tab Data + 359161 [3366283][E](Custom_C): 01 27 03 <-Power Tab Data + 359162 [3366323][E](Custom_C): 01 27 04 <-Power Tab Data + 359163 [3366418][E](Custom_C): 01 27 05 <-Power Tab Data + 359164 [3366485][E](Custom_C): 01 27 06 <-Power Tab Data + 359165 [3366530][E](Custom_C): 01 27 07 <-Power Tab Data + 359166 [3366574][E](Custom_C): 01 27 08 <-Power Tab Data + 359167 [3366620][E](Custom_C): 01 27 09 <-Power Tab Data + 359168 [3366674][E](Custom_C): 01 25 <-Firmware Version + 359169 [3366734][E](PTable): Success! + 359170 [3366909][E](Custom_C): 01 19 <-targetPosition + 359171 [3367441][E](PTable): Success! + 359172 [3367889][E](Custom_C): 01 19 <-targetPosition + 359173 [3368145][E](PTable): Success! + 359174 [3368146][E](PTable): Clean Power Table + 359175 [3368146][E](PTable): Averaged Entry: watts=158.000000, cad=73.000000, targetPosition=1350.00000, (3)(5) + 359176 [3368157][E](PTable): cellValue: (120) wattDelta: (2.000000) cadDelta: (0.333333) allNeighborsPassed: (0) + 359177 [3368169][E](PTable): rightValue: (0.000000) leftValue: (116.000000) bottomValue: (114.000000) topValue: (0.000000) New averaged targetPosition: (115.000000) count: (2) + 359178 [3368180][E](PTable): Bottom failed at: (116) Target pos: (115.000000) Avg pos: (115) + 359179 [3368191][E](PTable): Current Position moved down is valid! Current position: 115.000000 + 359180 [3368191][E](PTable): Existing entry averaged (4)(5)(115), readings(11) + 359181 [3368548][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359182 [3368570][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359183 [3368603][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 150 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359184 [3368625][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359185 [3368656][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 120 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359186 [3368679][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 115 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359187 [3368710][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359188 [3368732][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359189 [3368764][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359190 [3368786][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359191 [3368808][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359192 [3368839][E](PTable): Power Table Reset + 359193 [3368905][E](Custom_C): 01 19 <-targetPosition + 359194 [3368925][E](PTable): Success! + 359195 [3369408][E](FTMS_SERVER): 05 96 00 -> ERG Mode Target: 150 Current: 154 Incline: 135.339996 + 359196 [3369414][E](Custom_C): 01 28 <-targetWatts + 359197 [3369629][E](PTable): Success! + 359198 [3369891][E](Custom_C): 01 19 <-targetPosition + 359199 [3369933][E](FTMS_SERVER): 05 91 00 -> ERG Mode Target: 145 Current: 154 Incline: 135.110001 + 359200 [3369945][E](Custom_C): 01 28 <-targetWatts + 359201 [3370333][E](PTable): Success! + 359202 [3370881][E](Custom_C): 01 2a <-hMin + 359203 [3370972][E](Custom_C): 01 19 <-targetPosition + 359204 [3371016][E](Custom_C): 01 2b <-hMax + 359205 [3371035][E](PTable): Success! + 359206 [3371036][E](PTable): Clean Power Table + 359207 [3371036][E](PTable): Averaged Entry: watts=154.000000, cad=72.800003, targetPosition=1348.00003, (3)(5) + 359208 [3371048][E](PTable): cellValue: (120) wattDelta: (2.027027) cadDelta: (0.337838) allNeighborsPassed: (0) + 359209 [3371059][E](PTable): rightValue: (121.973335) leftValue: (118.026665) bottomValue: (113.488007) topValue: (0.000000) New averaged targetPosition: (117.829338) count: (3) + 359210 [3371071][E](PTable): Existing entry averaged (3)(5)(119), readings(11) + 359211 [3371415][E](Custom_C): 01 27 03 <-Power Tab Data + 359212 [3371421][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359213 [3371444][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359214 [3371476][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 150 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359215 [3371498][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359216 [3371530][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 119 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359217 [3371553][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 115 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359218 [3371585][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359219 [3371607][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359220 [3371639][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359221 [3371661][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359222 [3371693][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359223 [3371714][E](PTable): Power Table Reset + 359224 [3371714][E](ERG_Mode): Proportional: -20.000000, Integral: -6.500000, Derivative: 0.400000 + 359225 [3371745][E](PTable): Success! + 359226 [3371894][E](Custom_C): 01 19 <-targetPosition + 359227 [3372448][E](PTable): Success! + 359228 [3372906][E](Custom_C): 01 19 <-targetPosition + 359229 [3373150][E](PTable): Success! + 359230 [3373852][E](PTable): Success! + 359231 [3373853][E](PTable): Clean Power Table + 359232 [3373853][E](PTable): Averaged Entry: watts=154.000000, cad=72.000000, targetPosition=1338.00003, (2)(5) + 359233 [3373865][E](PTable): cellValue: (130) wattDelta: (7.894731) cadDelta: (1.315788) allNeighborsPassed: (1) + 359234 [3373875][E](PTable): rightValue: (130.506668) leftValue: (129.493332) bottomValue: (131.520004) topValue: (128.479996) New averaged targetPosition: (130.000000) count: (4) + 359235 [3373886][E](PTable): Existing entry averaged (2)(5)(130), readings(11) + 359236 [3373930][E](Custom_C): 01 19 <-targetPosition + 359237 [3374245][E](Custom_C): 01 27 02 <-Power Tab Data + 359238 [3374251][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359239 [3374273][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359240 [3374307][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 150 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359241 [3374329][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359242 [3374361][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 119 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359243 [3374383][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 115 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359244 [3374415][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359245 [3374437][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359246 [3374468][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359247 [3374490][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359248 [3374523][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359249 [3374544][E](PTable): Power Table Reset + 359250 [3374599][E](PTable): Success! + 359251 [3374886][E](Custom_C): 01 19 <-targetPosition + 359252 [3375303][E](PTable): Success! + 359253 [3375910][E](Custom_C): 01 2a <-hMin + 359254 [3375966][E](Custom_C): 01 19 <-targetPosition + 359255 [3376005][E](PTable): Success! + 359256 [3376011][E](Custom_C): 01 2b <-hMax + 359257 [3376709][E](PTable): Success! + 359258 [3376710][E](PTable): Clean Power Table + 359259 [3376710][E](PTable): Averaged Entry: watts=154.399994, cad=73.199997, targetPosition=1328.00003, (3)(5) + 359260 [3376721][E](PTable): cellValue: (119) wattDelta: (2.173913) cadDelta: (0.362319) allNeighborsPassed: (0) + 359261 [3376732][E](PTable): rightValue: (121.023994) leftValue: (116.975998) bottomValue: (114.031990) topValue: (0.000000) New averaged targetPosition: (117.343994) count: (3) + 359262 [3376743][E](PTable): Existing entry averaged (3)(5)(118), readings(11) + 359263 [3376889][E](Custom_C): 01 19 <-targetPosition + 359264 [3377129][E](Custom_C): 01 27 03 <-Power Tab Data + 359265 [3377135][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359266 [3377156][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359267 [3377189][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 150 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359268 [3377211][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359269 [3377245][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 118 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359270 [3377266][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 115 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359271 [3377299][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359272 [3377322][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359273 [3377344][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359274 [3377376][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359275 [3377398][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359276 [3377429][E](PTable): Power Table Reset + 359277 [3377429][E](ERG_Mode): Proportional: -60.000000, Integral: -7.500000, Derivative: -0.400000 + 359278 [3377459][E](PTable): Success! + 359279 [3377924][E](Custom_C): 01 19 <-targetPosition + 359280 [3378160][E](PTable): Success! + 359281 [3378862][E](PTable): Success! + 359282 [3378891][E](Custom_C): 01 19 <-targetPosition + 359283 [3379565][E](PTable): Success! + 359284 [3379566][E](PTable): Clean Power Table + 359285 [3379566][E](PTable): Averaged Entry: watts=151.600006, cad=74.000000, targetPosition=1320.00000, (3)(5) + 359286 [3379577][E](PTable): cellValue: (118) wattDelta: (2.142857) cadDelta: (0.357143) allNeighborsPassed: (0) + 359287 [3379588][E](PTable): rightValue: (118.746666) leftValue: (117.253326) bottomValue: (115.199997) topValue: (0.000000) New averaged targetPosition: (117.066673) count: (3) + 359288 [3379600][E](PTable): Existing entry averaged (3)(5)(117), readings(11) + 359289 [3379882][E](Custom_C): 01 19 <-targetPosition + 359290 [3379960][E](Custom_C): 01 27 03 <-Power Tab Data + 359291 [3379965][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359292 [3379987][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359293 [3380019][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 150 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359294 [3380042][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359295 [3380074][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359296 [3380096][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 115 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359297 [3380128][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359298 [3380150][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359299 [3380183][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359300 [3380205][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359301 [3380237][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359302 [3380259][E](PTable): Power Table Reset + 359303 [3380327][E](PTable): Success! + 359304 [3380929][E](Custom_C): 01 27 00 <-Power Tab Data + 359305 [3380984][E](Custom_C): 01 2a <-hMin + 359306 [3381028][E](Custom_C): 01 19 <-targetPosition + 359307 [3381032][E](PTable): Success! + 359308 [3381086][E](Custom_C): 01 27 01 <-Power Tab Data + 359309 [3381129][E](Custom_C): 01 2b <-hMax + 359310 [3381221][E](Custom_C): 01 27 02 <-Power Tab Data + 359311 [3381265][E](Custom_C): 01 27 03 <-Power Tab Data + 359312 [3381323][E](Custom_C): 01 27 04 <-Power Tab Data + 359313 [3381402][E](Custom_C): 01 27 05 <-Power Tab Data + 359314 [3381470][E](Custom_C): 01 27 06 <-Power Tab Data + 359315 [3381536][E](Custom_C): 01 27 07 <-Power Tab Data + 359316 [3381584][E](Custom_C): 01 27 08 <-Power Tab Data + 359317 [3381649][E](Custom_C): 01 27 09 <-Power Tab Data + 359318 [3381735][E](PTable): Success! + 359319 [3381906][E](Custom_C): 01 19 <-targetPosition + 359320 [3382266][E](Custom_C): 01 25 <-Firmware Version + 359321 [3382438][E](PTable): Success! + 359322 [3382439][E](PTable): Clean Power Table + 359323 [3382440][E](PTable): Averaged Entry: watts=148.399994, cad=73.800003, targetPosition=1313.99994, (3)(5) + 359324 [3382452][E](PTable): cellValue: (117) wattDelta: (2.083334) cadDelta: (0.347222) allNeighborsPassed: (0) + 359325 [3382463][E](PTable): rightValue: (116.231995) leftValue: (117.768005) bottomValue: (113.544006) topValue: (0.000000) New averaged targetPosition: (115.848000) count: (3) + 359326 [3382474][E](PTable): Bottom failed at: (115) Target pos: (115.848000) Avg pos: (115) + 359327 [3382484][E](PTable): Was not in range failed bottom (4)(5)(115), readings (11) + 359328 [3382485][E](PTable): WEIGHTED DOWNVOTING: Target Value: (115), NeighborValue: (115) + 359329 [3382495][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 359330 [3382506][E](PTable): PT failed (4)(5)(115), readings (11) + 359331 [3382509][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359332 [3382530][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 359333 [3382562][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 359334 [3382584][E](PTable): 70 rpm | 60 | 79 | | 111 | 121 | 130 | 141 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 359335 [3382616][E](PTable): 75 rpm | 48 | 64 | | | 106 | 117 | 135 | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 359336 [3382638][E](PTable): 80 rpm | | 58 | | | 105 | 115 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 359337 [3382670][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 359338 [3382692][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 359339 [3382725][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 359340 [3382749][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 359341 [3382780][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 359342 [3382801][E](PTable): Power Table Reset + 359343 [3382802][E](ERG_Mode): Proportional: 28.000000, Integral: -4.600000, Derivative: 0.000000 + 359344 [3382896][E](Custom_C): 01 19 <-targetPosition + 359345 [3383143][E](PTable): Success! + 359346 [3383847][E](PTable): Success! + 359347 [3383886][E](Custom_C): 01 19 <-targetPosition + 359348 [3384440][E](FTMS_SERVER): 05 8c 00 -> ERG Mode Target: 140 Current: 148 Incline: 131.742996 + 359349 [3384453][E](Custom_C): 01 28 <-targetWatts + 359350 [3384554][E](PTable): Success! + 359351 [3384921][E](Custom_C): 01 19 <-targetPosition + 359352 [3385259][E](PTable): Success! + 359353 [3385260][E](PTable): Clean Power Table + 359354 [3385260][E](PTable): Averaged Entry: watts=142.800003, cad=73.000000, targetPosition=1310.00000, (3)(5) + 359355 [3385272][E](PTable): cellValue: (117) wattDelta: (2.142857) cadDelta: (0.357143) allNeighborsPassed: (0) + 359356 [3385283][E](PTable): rightValue: (113.639999) leftValue: (120.360001) bottomValue: (111.400002) topValue: (0.000000) New averaged targetPosition: (115.133331) count: (3) + 359357 [3385294][E](PTable): Bottom failed at: (115) Target pos: (115.133331) Avg pos: (115) + 359358 [3385305][E](PTable): Was not in range failed bottom (4)(5)(115), readings (11) + 359359 [3385305][E](PTable): WEIGHTED DOWNVOTING: Target Value: (115), NeighborValue: (115) + 359360 [3385315][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 359361 [3385326][E](PTable): PT failed (4)(5)(115), readings (11) + 359362 [3385328][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359363 [3385350][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 359364 [3385382][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 359365 [3385403][E](PTable): 70 rpm | 60 | 79 | | 111 | 121 | 130 | 141 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 359366 [3385435][E](PTable): 75 rpm | 48 | 64 | | | 106 | 117 | 135 | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 359367 [3385469][E](PTable): 80 rpm | | 58 | | | 105 | 115 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 359368 [3385491][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 359369 [3385523][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 359370 [3385545][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 359371 [3385577][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 359372 [3385599][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 359373 [3385630][E](PTable): Power Table Reset + 359374 [3385911][E](Custom_C): 01 2a <-hMin + 359375 [3385958][E](Custom_C): 01 19 <-targetPosition + 359376 [3385965][E](PTable): Success! + 359377 [3386046][E](Custom_C): 01 2b <-hMax + 359378 [3386114][E](Custom_C): 01 25 <-Firmware Version + 359379 [3386669][E](PTable): Success! + 359380 [3386890][E](Custom_C): 01 19 <-targetPosition + 359381 [3387371][E](PTable): Success! + 359382 [3387891][E](Custom_C): 01 19 <-targetPosition + 359383 [3388076][E](PTable): Success! + 359384 [3388077][E](PTable): Clean Power Table + 359385 [3388077][E](PTable): Averaged Entry: watts=149.199997, cad=73.000000, targetPosition=1303.99994, (3)(5) + 359386 [3388088][E](PTable): cellValue: (117) wattDelta: (2.238807) cadDelta: (0.373134) allNeighborsPassed: (0) + 359387 [3388099][E](PTable): rightValue: (116.642662) leftValue: (117.357330) bottomValue: (111.639999) topValue: (0.000000) New averaged targetPosition: (115.213341) count: (3) + 359388 [3388110][E](PTable): Bottom failed at: (115) Target pos: (115.213341) Avg pos: (115) + 359389 [3388121][E](PTable): Was not in range failed bottom (4)(5)(115), readings (11) + 359390 [3388121][E](PTable): WEIGHTED DOWNVOTING: Target Value: (115), NeighborValue: (115) + 359391 [3388132][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 359392 [3388142][E](PTable): PT failed (4)(5)(115), readings (11) + 359393 [3388144][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359394 [3388176][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 359395 [3388198][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 359396 [3388230][E](PTable): 70 rpm | 60 | 79 | | 111 | 121 | 130 | 141 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 359397 [3388252][E](PTable): 75 rpm | 48 | 64 | | | 106 | 117 | 135 | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 359398 [3388284][E](PTable): 80 rpm | | 58 | | | 105 | 115 | | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 359399 [3388305][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 359400 [3388338][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 359401 [3388359][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 359402 [3388391][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 359403 [3388413][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 359404 [3388444][E](PTable): Power Table Reset + 359405 [3388444][E](ERG_Mode): Proportional: -40.000000, Integral: -7.000000, Derivative: 0.200000 + 359406 [3388814][E](PTable): Success! + 359407 [3388904][E](Custom_C): 01 19 <-targetPosition + 359408 [3389519][E](PTable): Success! + 359409 [3389906][E](Custom_C): 01 19 <-targetPosition + 359410 [3390221][E](PTable): Success! + 359411 [3390884][E](Custom_C): 01 2a <-hMin + 359412 [3390926][E](PTable): Success! + 359413 [3390928][E](PTable): Clean Power Table + 359414 [3390928][E](PTable): Averaged Entry: watts=138.800003, cad=73.800003, targetPosition=1290.00000, (3)(5) + 359415 [3390940][E](PTable): cellValue: (117) wattDelta: (2.500000) cadDelta: (0.416667) allNeighborsPassed: (1) + 359416 [3390952][E](Custom_C): 01 19 <-targetPosition + 359417 [3390955][E](PTable): rightValue: (112.520004) leftValue: (121.479996) bottomValue: (114.120010) topValue: (119.879990) New averaged targetPosition: (117.000000) count: (4) + 359418 [3390966][E](PTable): Existing entry averaged (3)(5)(117), readings(11) + 359419 [3391043][E](Custom_C): 01 2b <-hMax + 359420 [3391335][E](Custom_C): 01 27 03 <-Power Tab Data + 359421 [3391340][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359422 [3391362][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359423 [3391394][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 150 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359424 [3391417][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359425 [3391449][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359426 [3391470][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 115 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359427 [3391503][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359428 [3391525][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359429 [3391556][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359430 [3391578][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359431 [3391610][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359432 [3391630][E](PTable): Power Table Reset + 359433 [3391658][E](PTable): Success! + 359434 [3391896][E](Custom_C): 01 19 <-targetPosition + 359435 [3392360][E](PTable): Success! + 359436 [3392887][E](Custom_C): 01 19 <-targetPosition + 359437 [3393061][E](PTable): Success! + 359438 [3393765][E](PTable): Success! + 359439 [3393766][E](PTable): Clean Power Table + 359440 [3393766][E](PTable): Averaged Entry: watts=132.000000, cad=71.400002, targetPosition=1291.99997, (2)(4) + 359441 [3393778][E](PTable): cellValue: (121) wattDelta: (3.658538) cadDelta: (0.609756) allNeighborsPassed: (1) + 359442 [3393789][E](PTable): rightValue: (124.279999) leftValue: (117.720001) bottomValue: (123.296005) topValue: (118.703995) New averaged targetPosition: (121.000000) count: (4) + 359443 [3393800][E](PTable): Existing entry averaged (2)(4)(121), readings(11) + 359444 [3393910][E](Custom_C): 01 19 <-targetPosition + 359445 [3394156][E](Custom_C): 01 27 02 <-Power Tab Data + 359446 [3394161][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359447 [3394183][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359448 [3394216][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 150 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359449 [3394240][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 121 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359450 [3394272][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359451 [3394294][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 115 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359452 [3394325][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359453 [3394347][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359454 [3394380][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359455 [3394402][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359456 [3394434][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359457 [3394454][E](PTable): Power Table Reset + 359458 [3394455][E](ERG_Mode): Proportional: 32.000000, Integral: -1.400000, Derivative: -1.200000 + 359459 [3394547][E](PTable): Success! + 359460 [3394911][E](Custom_C): 01 19 <-targetPosition + 359461 [3395251][E](PTable): Success! + 359462 [3395902][E](Custom_C): 01 27 00 <-Power Tab Data + 359463 [3395946][E](Custom_C): 01 2a <-hMin + 359464 [3395955][E](PTable): Success! + 359465 [3395991][E](Custom_C): 01 19 <-targetPosition + 359466 [3396083][E](Custom_C): 01 27 01 <-Power Tab Data + 359467 [3396149][E](Custom_C): 01 2b <-hMax + 359468 [3396206][E](Custom_C): 01 27 02 <-Power Tab Data + 359469 [3396276][E](Custom_C): 01 27 03 <-Power Tab Data + 359470 [3396319][E](Custom_C): 01 27 04 <-Power Tab Data + 359471 [3396376][E](Custom_C): 01 27 05 <-Power Tab Data + 359472 [3396442][E](Custom_C): 01 27 06 <-Power Tab Data + 359473 [3396498][E](Custom_C): 01 27 07 <-Power Tab Data + 359474 [3396544][E](Custom_C): 01 27 08 <-Power Tab Data + 359475 [3396626][E](Custom_C): 01 27 09 <-Power Tab Data + 359476 [3396659][E](PTable): Success! + 359477 [3396660][E](PTable): Clean Power Table + 359478 [3396660][E](PTable): Averaged Entry: watts=123.599998, cad=68.400002, targetPosition=1310.00000, (2)(4) + 359479 [3396672][E](PTable): cellValue: (121) wattDelta: (3.000000) cadDelta: (0.500000) allNeighborsPassed: (0) + 359480 [3396674][E](PTable): rightValue: (0.000000) leftValue: (119.800003) bottomValue: (117.800003) topValue: (0.000000) New averaged targetPosition: (118.800003) count: (2) + 359481 [3396695][E](PTable): Existing entry averaged (2)(4)(120), readings(11) + 359482 [3396891][E](Custom_C): 01 19 <-targetPosition + 359483 [3397075][E](Custom_C): 01 27 02 <-Power Tab Data + 359484 [3397081][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359485 [3397103][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359486 [3397135][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 150 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359487 [3397157][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359488 [3397189][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 135 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359489 [3397211][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 115 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359490 [3397245][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359491 [3397267][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359492 [3397299][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359493 [3397321][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359494 [3397353][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359495 [3397374][E](PTable): Power Table Reset + 359496 [3397375][E](PTable): Using detected travel limits during homing + 359497 [3397402][E](PTable): Success! + 359498 [3397881][E](Custom_C): 01 19 <-targetPosition + 359499 [3398103][E](PTable): Success! + 359500 [3398805][E](PTable): Success! + 359501 [3398894][E](Custom_C): 01 19 <-targetPosition + 359502 [3399423][E](FTMS_SERVER): 05 87 00 -> ERG Mode Target: 135 Current: 178 Incline: 130.149994 + 359503 [3399430][E](Custom_C): 01 28 <-targetWatts + 359504 [3399508][E](PTable): Success! + 359505 [3399509][E](PTable): Clean Power Table + 359506 [3399509][E](PTable): Averaged Entry: watts=186.800003, cad=74.000000, targetPosition=1311.99997, (3)(6) + 359507 [3399521][E](PTable): cellValue: (135) wattDelta: (7.894731) cadDelta: (1.315788) allNeighborsPassed: (1) + 359508 [3399532][E](PTable): rightValue: (128.261322) leftValue: (126.538658) bottomValue: (126.639992) topValue: (128.159988) New averaged targetPosition: (127.399986) count: (4) + 359509 [3399543][E](PTable): Existing entry averaged (3)(6)(132), readings(2) + 359510 [3399883][E](Custom_C): 01 19 <-targetPosition + 359511 [3399900][E](Custom_C): 01 27 03 <-Power Tab Data + 359512 [3399908][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359513 [3399930][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359514 [3399962][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359515 [3399983][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359516 [3400016][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359517 [3400037][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 115 | 126 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359518 [3400069][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359519 [3400091][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359520 [3400123][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359521 [3400145][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359522 [3400176][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359523 [3400197][E](PTable): Power Table Reset + 359524 [3400208][E](ERG_Mode): Proportional: -172.000000, Integral: -8.300000, Derivative: -3.300000 + 359525 [3400292][E](PTable): Success! + 359526 [3400896][E](Custom_C): 01 2a <-hMin + 359527 [3400963][E](Custom_C): 01 19 <-targetPosition + 359528 [3400996][E](PTable): Success! + 359529 [3401009][E](Custom_C): 01 2b <-hMax + 359530 [3401701][E](PTable): Success! + 359531 [3401886][E](Custom_C): 01 19 <-targetPosition + 359532 [3402269][E](Custom_C): 01 25 <-Firmware Version + 359533 [3402406][E](PTable): Success! + 359534 [3402407][E](PTable): Clean Power Table + 359535 [3402407][E](PTable): Averaged Entry: watts=180.800003, cad=77.599998, targetPosition=1280.00000, (4)(6) + 359536 [3402419][E](PTable): Keep old targetPosition: (128.000000) + 359537 [3402420][E](PTable): New entry recorded (4)(6)(128) + 359538 [3402783][E](Custom_C): 01 27 04 <-Power Tab Data + 359539 [3402788][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359540 [3402810][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359541 [3402842][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359542 [3402863][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359543 [3402896][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359544 [3402916][E](Custom_C): 01 19 <-targetPosition + 359545 [3402942][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359546 [3402965][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359547 [3402987][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359548 [3403019][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359549 [3403041][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359550 [3403073][E](PTable): Power Table Reset + 359551 [3403108][E](PTable): Success! + 359552 [3403809][E](PTable): Success! + 359553 [3403889][E](Custom_C): 01 19 <-targetPosition + 359554 [3404515][E](PTable): Success! + 359555 [3404879][E](Custom_C): 01 19 <-targetPosition + 359556 [3405220][E](PTable): Success! + 359557 [3405221][E](PTable): Clean Power Table + 359558 [3405221][E](PTable): Averaged Entry: watts=162.800003, cad=78.599998, targetPosition=1250.00000, (4)(5) + 359559 [3405233][E](PTable): cellValue: (115) wattDelta: (3.000000) cadDelta: (0.500000) allNeighborsPassed: (0) + 359560 [3405245][E](PTable): rightValue: (119.266670) leftValue: (110.733330) bottomValue: (112.199997) topValue: (0.000000) New averaged targetPosition: (114.066673) count: (3) + 359561 [3405256][E](PTable): Existing entry averaged (4)(5)(114), readings(11) + 359562 [3405612][E](Custom_C): 01 27 04 <-Power Tab Data + 359563 [3405618][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359564 [3405643][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359565 [3405666][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359566 [3405698][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359567 [3405720][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359568 [3405752][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 114 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359569 [3405774][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359570 [3405806][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359571 [3405827][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359572 [3405859][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359573 [3405881][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359574 [3405923][E](PTable): Power Table Reset + 359575 [3405924][E](ERG_Mode): Proportional: -108.000000, Integral: -8.700000, Derivative: 0.400000 + 359576 [3405983][E](Custom_C): 01 19 <-targetPosition + 359577 [3406026][E](Custom_C): 01 2b <-hMax + 359578 [3406030][E](PTable): Success! + 359579 [3406117][E](Custom_C): 01 25 <-Firmware Version + 359580 [3406735][E](PTable): Success! + 359581 [3406904][E](Custom_C): 01 19 <-targetPosition + 359582 [3407437][E](PTable): Success! + 359583 [3407916][E](Custom_C): 01 19 <-targetPosition + 359584 [3408140][E](PTable): Success! + 359585 [3408140][E](PTable): Clean Power Table + 359586 [3408141][E](PTable): Averaged Entry: watts=124.000000, cad=79.199997, targetPosition=1240.00000, (4)(4) + 359587 [3408153][E](PTable): cellValue: (105) wattDelta: (1.578947) cadDelta: (0.263158) allNeighborsPassed: (0) + 359588 [3408164][E](PTable): rightValue: (0.000000) leftValue: (102.466667) bottomValue: (101.959991) topValue: (0.000000) New averaged targetPosition: (102.213333) count: (2) + 359589 [3408176][E](PTable): Bottom failed at: (104) Target pos: (102.213333) Avg pos: (103) + 359590 [3408176][E](PTable): All test failed bottom (3)(4)(106), readings (11) + 359591 [3408187][E](PTable): WEIGHTED DOWNVOTING: Target Value: (102), NeighborValue: (104) + 359592 [3408197][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 359593 [3408198][E](PTable): PT failed (5)(4)(104), readings (11) + 359594 [3408210][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359595 [3408232][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 359596 [3408264][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 359597 [3408286][E](PTable): 70 rpm | 60 | 79 | | 111 | 120 | 130 | 141 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 359598 [3408318][E](PTable): 75 rpm | 48 | 64 | | | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 359599 [3408340][E](PTable): 80 rpm | | 58 | | | 105 | 114 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 359600 [3408372][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 359601 [3408394][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 359602 [3408428][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 359603 [3408450][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 359604 [3408472][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 359605 [3408503][E](PTable): Power Table Reset + 359606 [3408765][E](BLE_Server): Bluetooth Remote Client Connected: 56:4c:22:c4:e0:42 Connected Clients: 3 + 359607 [3408766][E](BLE_Server): Max Remote Client Connections Reached + 359608 [3408840][E](PTable): Success! + 359609 [3408991][E](Custom_C): 01 19 <-targetPosition + 359610 [3409382][E](BLE_Server): MTU updated: 515 for connection ID: 4 + 359611 [3409544][E](PTable): Success! + 359612 [3409896][E](Custom_C): 01 19 <-targetPosition + 359613 [3410249][E](PTable): Success! + 359614 [3410899][E](Custom_C): 01 27 00 <-Power Tab Data + 359615 [3410931][E](Custom_C): 01 2a <-hMin + 359616 [3410953][E](PTable): Success! + 359617 [3410954][E](PTable): Clean Power Table + 359618 [3410954][E](PTable): Averaged Entry: watts=114.000000, cad=72.199997, targetPosition=1258.00003, (2)(4) + 359619 [3410966][E](PTable): cellValue: (120) wattDelta: (5.172411) cadDelta: (0.862069) allNeighborsPassed: (1) + 359620 [3410978][E](Custom_C): 01 19 <-targetPosition + 359621 [3410981][E](PTable): rightValue: (118.839996) leftValue: (121.160004) bottomValue: (122.551994) topValue: (117.448006) New averaged targetPosition: (120.000000) count: (4) + 359622 [3410993][E](PTable): Existing entry averaged (2)(4)(120), readings(11) + 359623 [3411034][E](Custom_C): 01 27 01 <-Power Tab Data + 359624 [3411089][E](Custom_C): 01 2b <-hMax + 359625 [3411146][E](Custom_C): 01 27 02 <-Power Tab Data + 359626 [3411203][E](Custom_C): 01 27 03 <-Power Tab Data + 359627 [3411259][E](Custom_C): 01 27 04 <-Power Tab Data + 359628 [3411326][E](Custom_C): 01 27 05 <-Power Tab Data + 359629 [3411383][E](Custom_C): 01 27 06 <-Power Tab Data + 359630 [3411439][E](Custom_C): 01 27 07 <-Power Tab Data + 359631 [3411456][E](Custom_C): 01 27 02 <-Power Tab Data + 359632 [3411479][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359633 [3411518][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359634 [3411552][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359635 [3411607][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359636 [3411629][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359637 [3411663][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 114 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359638 [3411685][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359639 [3411707][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359640 [3411739][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359641 [3411761][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359642 [3411794][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359643 [3411815][E](PTable): Power Table Reset + 359644 [3411826][E](ERG_Mode): Proportional: 44.000000, Integral: 4.100000, Derivative: -0.200000 + 359645 [3411927][E](Custom_C): 01 19 <-targetPosition + 359646 [3411940][E](PTable): Success! + 359647 [3412645][E](PTable): Success! + 359648 [3412889][E](Custom_C): 01 19 <-targetPosition + 359649 [3413346][E](PTable): Success! + 359650 [3413890][E](Custom_C): 01 19 <-targetPosition + 359651 [3413912][E](Custom_C): Subscribe from 56:4c:22:c4:e0:42 + 359652 [3414048][E](PTable): Success! + 359653 [3414049][E](PTable): Clean Power Table + 359654 [3414049][E](PTable): Averaged Entry: watts=122.400002, cad=69.599998, targetPosition=1275.99998, (2)(4) + 359655 [3414061][E](PTable): cellValue: (120) wattDelta: (3.947369) cadDelta: (0.657895) allNeighborsPassed: (1) + 359656 [3414072][E](PTable): rightValue: (120.608002) leftValue: (119.391998) bottomValue: (119.391998) topValue: (120.608002) New averaged targetPosition: (120.000000) count: (4) + 359657 [3414083][E](PTable): Existing entry averaged (2)(4)(120), readings(11) + 359658 [3414094][E](BLE_Server): Client ID: 4 Address: 56:4c:22:c4:e0:42 Subscribed to notifications for 0x2ad9 + 359659 [3414183][E](BLE_Server): Client ID: 4 Address: 56:4c:22:c4:e0:42 Subscribed to notifications for 0x2ad2 + 359660 [3414483][E](Custom_C): 01 27 02 <-Power Tab Data + 359661 [3414490][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359662 [3414512][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359663 [3414544][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359664 [3414565][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359665 [3414615][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359666 [3414637][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 114 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359667 [3414669][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359668 [3414693][E](Custom_C): 01 15 <-connectedPowerMete + 359669 [3414696][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359670 [3414720][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359671 [3414752][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359672 [3414774][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359673 [3414805][E](PTable): Power Table Reset + 359674 [3414822][E](FTMS_SERVER): 05 82 00 -> ERG Mode Target: 130 Current: 126 Incline: 128.889008 + 359675 [3414833][E](Custom_C): 01 28 <-targetWatts + 359676 [3414838][E](PTable): Success! + 359677 [3414875][E](Custom_C): 01 16 <-connectedHeartMonitor + 359678 [3414893][E](Custom_C): 01 19 <-targetPosition + 359679 [3414964][E](Custom_C): 01 14 <-foundDevices + 359680 [3415173][E](Custom_C): 01 08 <-shiftStep + 359681 [3415326][E](Custom_C): 01 20 <-ShiftDir + 359682 [3415443][E](Custom_C): 01 18 <-saveToLittleFS + 359683 [3415503][E](Custom_C): 01 0b <-inclineMultiplier + 359684 [3415542][E](PTable): Success! + 359685 [3415563][E](Custom_C): 01 1f <-ERGSensitivity + 359686 [3415654][E](Custom_C): 01 01 <-Firmware Update URL + 359687 [3415713][E](Custom_C): 01 02 <-incline + 359688 [3415773][E](Custom_C): 01 03 <-simulatedWatts + 359689 [3415863][E](Custom_C): 01 04 <-simulatedHr + 359690 [3415904][E](Custom_C): 01 2a <-hMin + 359691 [3415948][E](Custom_C): 01 19 <-targetPosition + 359692 [3415994][E](Custom_C): 01 2b <-hMax + 359693 [3416013][E](Custom_C): 01 28 <-targetWatts + 359694 [3416163][E](Custom_C): 01 05 <-simulatedCad + 359695 [3416244][E](PTable): Success! + 359696 [3416285][E](Custom_C): 01 06 <-simulatedSpeed + 359697 [3416373][E](Custom_C): 01 07 <-deviceName + 359698 [3416463][E](Custom_C): 01 09 <-stepperPower + 359699 [3416583][E](Custom_C): 01 0a <-stealthChop + 359700 [3416703][E](Custom_C): 01 0c <-powerCorrectionFactor + 359701 [3416793][E](Custom_C): 01 0d <-simulateHr + 359702 [3416853][E](Custom_C): 01 0e <-simulateWatts + 359703 [3416893][E](Custom_C): 01 19 <-targetPosition + 359704 [3416947][E](PTable): Success! + 359705 [3416950][E](PTable): Clean Power Table + 359706 [3416950][E](PTable): Averaged Entry: watts=129.199997, cad=71.199997, targetPosition=1283.99994, (2)(4) + 359707 [3416961][E](PTable): cellValue: (120) wattDelta: (3.571431) cadDelta: (0.595239) allNeighborsPassed: (1) + 359708 [3416972][E](PTable): rightValue: (122.575996) leftValue: (117.424004) bottomValue: (122.015991) topValue: (117.984009) New averaged targetPosition: (120.000000) count: (4) + 359709 [3416983][E](PTable): Existing entry averaged (2)(4)(120), readings(11) + 359710 [3417063][E](Custom_C): 01 29 <-simulatetargetwatts + 359711 [3417123][E](Custom_C): 01 0f <-simulateCad + 359712 [3417183][E](Custom_C): 01 10 <-FTMSMode + 359713 [3417303][E](Custom_C): 01 11 <-autoUpdate + 359714 [3417393][E](Custom_C): 01 12 <-ssid + 359715 [3417398][E](Custom_C): 01 27 02 <-Power Tab Data + 359716 [3417403][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359717 [3417425][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359718 [3417456][E](Custom_C): 01 13 <-password + 359719 [3417462][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359720 [3417484][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359721 [3417515][E](Custom_C): 01 17 <-shifterPosition + 359722 [3417522][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359723 [3417545][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 114 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359724 [3417567][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359725 [3417615][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359726 [3417638][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359727 [3417660][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359728 [3417713][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359729 [3417735][E](PTable): Power Table Reset + 359730 [3417735][E](ERG_Mode): Proportional: -16.000000, Integral: 5.200000, Derivative: 0.000000 + 359731 [3417846][E](Custom_C): 01 1e <-stepperSpeed + 359732 [3417884][E](Custom_C): 01 19 <-targetPosition + 359733 [3417887][E](PTable): Success! + 359734 [3418027][E](Custom_C): 01 1b <-syncMode + 359735 [3418174][E](Custom_C): 01 21 <-MinWatts + 359736 [3418263][E](Custom_C): 01 22 <-MaxWatts + 359737 [3418323][E](Custom_C): 01 23 <-restart BLE + 359738 [3418413][E](Custom_C): 01 24 <-scan BLE + 359739 [3418590][E](PTable): Success! + 359740 [3418623][E](Custom_C): 01 1c <-reboot + 359741 [3418713][E](Custom_C): 01 1d <-reset to defaults + 359742 [3418833][E](Custom_C): 01 26 <-Reset PTab + 359743 [3418930][E](Custom_C): 01 19 <-targetPosition + 359744 [3418997][E](Custom_C): 01 27 <-Power Tab Data + 359745 [3419194][E](Custom_C): 01 28 <-targetWatts + 359746 [3419254][E](Custom_C): 01 29 <-simulatetargetwatts + 359747 [3419291][E](PTable): Success! + 359748 [3419374][E](Custom_C): 01 2a <-hMin + 359749 [3419433][E](Custom_C): 01 2b <-hMax + 359750 [3419553][E](Custom_C): 01 2c <-homingSensitivity + 359751 [3419886][E](Custom_C): 01 19 <-targetPosition + 359752 [3419993][E](PTable): Success! + 359753 [3419994][E](PTable): Clean Power Table + 359754 [3419994][E](PTable): Averaged Entry: watts=141.600006, cad=73.400002, targetPosition=1280.00000, (3)(5) + 359755 [3420007][E](PTable): cellValue: (117) wattDelta: (2.727273) cadDelta: (0.454545) allNeighborsPassed: (1) + 359756 [3420008][E](PTable): rightValue: (113.919998) leftValue: (120.080002) bottomValue: (113.480003) topValue: (120.519997) New averaged targetPosition: (117.000000) count: (4) + 359757 [3420029][E](PTable): Existing entry averaged (3)(5)(117), readings(11) + 359758 [3420273][E](Custom_C): 01 25 <-Firmware Version + 359759 [3420363][E](Custom_C): 01 19 <-targetPosition + 359760 [3420450][E](Custom_C): 01 27 03 <-Power Tab Data + 359761 [3420457][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359762 [3420479][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359763 [3420513][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359764 [3420535][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359765 [3420567][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359766 [3420593][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 114 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359767 [3420615][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359768 [3420647][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359769 [3420669][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359770 [3420701][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359771 [3420724][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359772 [3420755][E](PTable): Power Table Reset + 359773 [3420778][E](PTable): Success! + 359774 [3420910][E](Custom_C): 01 2a <-hMin + 359775 [3420966][E](Custom_C): 01 19 <-targetPosition + 359776 [3421034][E](Custom_C): 01 2b <-hMax + 359777 [3421473][E](Custom_C): 01 19 <-targetPosition + 359778 [3421482][E](PTable): Success! + 359779 [3421533][E](Custom_C): 01 2a <-hMin + 359780 [3421593][E](Custom_C): 01 19 <-targetPosition + 359781 [3421743][E](Custom_C): 01 2b <-hMax + 359782 [3421803][E](Custom_C): 01 19 <-targetPosition + 359783 [3421888][E](Custom_C): 01 19 <-targetPosition + 359784 [3421953][E](Custom_C): 01 19 <-targetPosition + 359785 [3422103][E](Custom_C): 01 19 <-targetPosition + 359786 [3422183][E](PTable): Success! + 359787 [3422225][E](Custom_C): 01 19 <-targetPosition + 359788 [3422271][E](Custom_C): 01 25 <-Firmware Version + 359789 [3422284][E](Custom_C): 01 2a <-hMin + 359790 [3422344][E](Custom_C): 01 19 <-targetPosition + 359791 [3422403][E](Custom_C): 01 2b <-hMax + 359792 [3422523][E](Custom_C): 01 25 <-Firmware Version + 359793 [3422583][E](Custom_C): 01 19 <-targetPosition + 359794 [3422886][E](PTable): Success! + 359795 [3422887][E](PTable): Clean Power Table + 359796 [3422890][E](Custom_C): 01 19 <-targetPosition + 359797 [3422894][E](PTable): Averaged Entry: watts=130.800003, cad=73.599998, targetPosition=1280.00000, (3)(4) + 359798 [3422906][E](PTable): cellValue: (106) wattDelta: (1.363636) cadDelta: (0.227273) allNeighborsPassed: (0) + 359799 [3422906][E](PTable): rightValue: (0.000000) leftValue: (98.080002) bottomValue: (99.839996) topValue: (0.000000) New averaged targetPosition: (98.959999) count: (2) + 359800 [3422927][E](PTable): Bottom failed at: (105) Target pos: (98.959999) Avg pos: (101) + 359801 [3422928][E](PTable): All test failed bottom (2)(4)(120), readings (11) + 359802 [3422939][E](PTable): WEIGHTED DOWNVOTING: Target Value: (98), NeighborValue: (105) + 359803 [3422950][E](PTable): WEIGHTED DOWNVOTING: Delta: (7), Penalty: (1) + 359804 [3422951][E](PTable): PT failed (4)(4)(105), readings (10) + 359805 [3422963][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359806 [3422999][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 359807 [3423021][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 359808 [3423053][E](PTable): 70 rpm | 60 | 79 | | 111 | 120 | 130 | 141 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 359809 [3423075][E](PTable): 75 rpm | 48 | 64 | | | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 359810 [3423107][E](PTable): 80 rpm | | 58 | | | 105 | 114 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 359811 [3423129][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 359812 [3423163][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 359813 [3423184][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 359814 [3423216][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 359815 [3423238][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 359816 [3423269][E](PTable): Power Table Reset + 359817 [3423270][E](ERG_Mode): Proportional: -32.000000, Integral: 2.200000, Derivative: -1.200000 + 359818 [3423588][E](PTable): Success! + 359819 [3423892][E](Custom_C): 01 19 <-targetPosition + 359820 [3423964][E](Custom_C): 01 19 <-targetPosition + 359821 [3424292][E](PTable): Success! + 359822 [3424881][E](Custom_C): 01 19 <-targetPosition + 359823 [3424924][E](Custom_C): 01 19 <-targetPosition + 359824 [3424996][E](PTable): Success! + 359825 [3425699][E](PTable): Success! + 359826 [3425700][E](PTable): Clean Power Table + 359827 [3425700][E](PTable): Averaged Entry: watts=140.800003, cad=73.800003, targetPosition=1275.99998, (3)(5) + 359828 [3425712][E](PTable): cellValue: (117) wattDelta: (2.830189) cadDelta: (0.471698) allNeighborsPassed: (1) + 359829 [3425724][E](PTable): rightValue: (113.749336) leftValue: (120.250664) bottomValue: (114.456009) topValue: (119.543991) New averaged targetPosition: (117.000000) count: (4) + 359830 [3425734][E](PTable): Existing entry averaged (3)(5)(117), readings(11) + 359831 [3425906][E](Custom_C): 01 27 00 <-Power Tab Data + 359832 [3425957][E](Custom_C): 01 27 00 <-Power Tab Data + 359833 [3425963][E](Custom_C): 01 2a <-hMin + 359834 [3426029][E](Custom_C): 01 19 <-targetPosition + 359835 [3426064][E](Custom_C): 01 2a <-hMin + 359836 [3426086][E](Custom_C): 01 27 01 <-Power Tab Data + 359837 [3426142][E](Custom_C): 01 2b <-hMax + 359838 [3426172][E](Custom_C): 01 27 03 <-Power Tab Data + 359839 [3426178][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359840 [3426226][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359841 [3426280][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359842 [3426304][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359843 [3426327][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359844 [3426360][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 114 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359845 [3426418][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359846 [3426467][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359847 [3426519][E](Custom_C): 01 2b <-hMax + 359848 [3426527][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359849 [3426549][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359850 [3426616][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359851 [3426661][E](PTable): Power Table Reset + 359852 [3426717][E](Custom_C): 01 27 06 <-Power Tab Data + 359853 [3426770][E](Custom_C): 01 27 03 <-Power Tab Data + 359854 [3426787][E](PTable): Success! + 359855 [3426789][E](Custom_C): 01 27 07 <-Power Tab Data + 359856 [3426900][E](Custom_C): 01 27 08 <-Power Tab Data + 359857 [3426964][E](Custom_C): 01 27 09 <-Power Tab Data + 359858 [3427007][E](Custom_C): 01 27 04 <-Power Tab Data + 359859 [3427010][E](Custom_C): 01 19 <-targetPosition + 359860 [3427063][E](Custom_C): 01 25 <-Firmware Version + 359861 [3427186][E](Custom_C): 01 27 05 <-Power Tab Data + 359862 [3427248][E](Custom_C): 01 27 06 <-Power Tab Data + 359863 [3427335][E](Custom_C): 01 27 07 <-Power Tab Data + 359864 [3427486][E](Custom_C): 01 27 08 <-Power Tab Data + 359865 [3427495][E](PTable): Success! + 359866 [3427606][E](Custom_C): 01 27 09 <-Power Tab Data + 359867 [3427713][E](Custom_C): 01 19 <-targetPosition + 359868 [3427897][E](Custom_C): 01 19 <-targetPosition + 359869 [3427923][E](Custom_C): 01 19 <-targetPosition + 359870 [3428199][E](PTable): Success! + 359871 [3428823][E](Custom_C): 01 25 <-Firmware Version + 359872 [3428904][E](PTable): Success! + 359873 [3428905][E](PTable): Clean Power Table + 359874 [3428905][E](PTable): Averaged Entry: watts=140.000000, cad=75.800003, targetPosition=1264.00002, (3)(5) + 359875 [3428917][E](Custom_C): 01 19 <-targetPosition + 359876 [3428921][E](PTable): cellValue: (117) wattDelta: (3.191489) cadDelta: (0.531915) allNeighborsPassed: (1) + 359877 [3428932][E](PTable): rightValue: (113.866669) leftValue: (120.133331) bottomValue: (118.504005) topValue: (115.495995) New averaged targetPosition: (117.000000) count: (4) + 359878 [3428943][E](Custom_C): 01 19 <-targetPosition + 359879 [3428946][E](PTable): Existing entry averaged (3)(5)(117), readings(11) + 359880 [3429382][E](Custom_C): 01 27 03 <-Power Tab Data + 359881 [3429387][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359882 [3429413][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359883 [3429445][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359884 [3429466][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359885 [3429502][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359886 [3429525][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 114 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359887 [3429548][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359888 [3429580][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359889 [3429605][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359890 [3429637][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359891 [3429658][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359892 [3429689][E](PTable): Power Table Reset + 359893 [3429689][E](ERG_Mode): Proportional: 8.000000, Integral: -3.400000, Derivative: 0.600000 + 359894 [3429717][E](FTMS_SERVER): 05 7d 00 -> ERG Mode Target: 125 Current: 140 Incline: 126.712006 + 359895 [3429726][E](Custom_C): 01 28 <-targetWatts + 359896 [3429731][E](PTable): Success! + 359897 [3429925][E](Custom_C): 01 19 <-targetPosition + 359898 [3429963][E](Custom_C): 01 19 <-targetPosition + 359899 [3430436][E](PTable): Success! + 359900 [3430889][E](Custom_C): 01 2a <-hMin + 359901 [3430923][E](Custom_C): 01 2a <-hMin + 359902 [3430957][E](Custom_C): 01 19 <-targetPosition + 359903 [3431001][E](Custom_C): 01 2b <-hMax + 359904 [3431013][E](Custom_C): 01 19 <-targetPosition + 359905 [3431134][E](Custom_C): 01 2b <-hMax + 359906 [3431142][E](PTable): Success! + 359907 [3431193][E](Custom_C): 01 25 <-Firmware Version + 359908 [3431846][E](PTable): Success! + 359909 [3431848][E](PTable): Clean Power Table + 359910 [3431848][E](PTable): Averaged Entry: watts=137.600006, cad=75.000000, targetPosition=1254.00002, (3)(5) + 359911 [3431860][E](PTable): cellValue: (117) wattDelta: (3.571428) cadDelta: (0.595238) allNeighborsPassed: (1) + 359912 [3431871][E](PTable): rightValue: (113.528000) leftValue: (120.472000) bottomValue: (117.000000) topValue: (117.000000) New averaged targetPosition: (117.000000) count: (4) + 359913 [3431882][E](PTable): Existing entry averaged (3)(5)(117), readings(11) + 359914 [3431893][E](Custom_C): 01 19 <-targetPosition + 359915 [3432004][E](Custom_C): 01 19 <-targetPosition + 359916 [3432283][E](Custom_C): 01 27 03 <-Power Tab Data + 359917 [3432292][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359918 [3432315][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359919 [3432347][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359920 [3432372][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359921 [3432395][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359922 [3432427][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 114 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359923 [3432448][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359924 [3432473][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359925 [3432505][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359926 [3432526][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359927 [3432558][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359928 [3432589][E](PTable): Power Table Reset + 359929 [3432678][E](PTable): Success! + 359930 [3432891][E](Custom_C): 01 19 <-targetPosition + 359931 [3432963][E](Custom_C): 01 19 <-targetPosition + 359932 [3433380][E](PTable): Success! + 359933 [3433881][E](Custom_C): 01 19 <-targetPosition + 359934 [3434013][E](Custom_C): 01 19 <-targetPosition + 359935 [3434083][E](PTable): Success! + 359936 [3434084][E](PTable): Using detected travel limits during homing + 359937 [3434785][E](PTable): Success! + 359938 [3434786][E](PTable): Clean Power Table + 359939 [3434786][E](PTable): Averaged Entry: watts=161.199997, cad=79.599998, targetPosition=1238.00003, (4)(5) + 359940 [3434797][E](PTable): cellValue: (114) wattDelta: (3.061224) cadDelta: (0.510204) allNeighborsPassed: (0) + 359941 [3434808][E](PTable): rightValue: (117.658669) leftValue: (110.341331) bottomValue: (113.215996) topValue: (0.000000) New averaged targetPosition: (113.738670) count: (3) + 359942 [3434820][E](PTable): Existing entry averaged (4)(5)(113), readings(11) + 359943 [3434894][E](Custom_C): 01 19 <-targetPosition + 359944 [3434973][E](Custom_C): 01 19 <-targetPosition + 359945 [3435206][E](Custom_C): 01 27 04 <-Power Tab Data + 359946 [3435212][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359947 [3435237][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 359948 [3435269][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 359949 [3435293][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 359950 [3435315][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 359951 [3435346][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 359952 [3435368][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 359953 [3435400][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 359954 [3435422][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 359955 [3435455][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 359956 [3435477][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 359957 [3435508][E](PTable): Power Table Reset + 359958 [3435508][E](ERG_Mode): Proportional: -12.000000, Integral: -6.300000, Derivative: 0.400000 + 359959 [3435546][E](PTable): Success! + 359960 [3435884][E](Custom_C): 01 2a <-hMin + 359961 [3435928][E](Custom_C): 01 19 <-targetPosition + 359962 [3435963][E](Custom_C): 01 2a <-hMin + 359963 [3435996][E](Custom_C): 01 2b <-hMax + 359964 [3436084][E](Custom_C): 01 19 <-targetPosition + 359965 [3436203][E](Custom_C): 01 2b <-hMax + 359966 [3436249][E](PTable): Success! + 359967 [3436897][E](Custom_C): 01 19 <-targetPosition + 359968 [3436953][E](PTable): Success! + 359969 [3436984][E](Custom_C): 01 19 <-targetPosition + 359970 [3437658][E](PTable): Success! + 359971 [3437659][E](PTable): Clean Power Table + 359972 [3437659][E](PTable): Averaged Entry: watts=128.399994, cad=76.000000, targetPosition=1224.00002, (3)(4) + 359973 [3437671][E](PTable): cellValue: (106) wattDelta: (1.829268) cadDelta: (0.304878) allNeighborsPassed: (0) + 359974 [3437683][E](PTable): rightValue: (0.000000) leftValue: (101.408005) bottomValue: (109.279999) topValue: (0.000000) New averaged targetPosition: (105.344002) count: (2) + 359975 [3437696][E](PTable): Bottom failed at: (105) Target pos: (105.344002) Avg pos: (105) + 359976 [3437697][E](PTable): Was not in range failed bottom (4)(4)(105), readings (10) + 359977 [3437707][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (105) + 359978 [3437718][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 359979 [3437719][E](PTable): PT failed (4)(4)(105), readings (10) + 359980 [3437731][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 359981 [3437753][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 359982 [3437785][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 359983 [3437806][E](PTable): 70 rpm | 60 | 79 | | 111 | 120 | 130 | 141 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 359984 [3437839][E](PTable): 75 rpm | 48 | 64 | | | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 359985 [3437861][E](PTable): 80 rpm | | 58 | | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 359986 [3437892][E](Custom_C): 01 19 <-targetPosition + 359987 [3437900][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 359988 [3437922][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 359989 [3437953][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 359990 [3437975][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 359991 [3438008][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 359992 [3438029][E](PTable): Power Table Reset + 359993 [3438033][E](Custom_C): 01 19 <-targetPosition + 359994 [3438363][E](PTable): Success! + 359995 [3438910][E](Custom_C): 01 19 <-targetPosition + 359996 [3438933][E](Custom_C): 01 19 <-targetPosition + 359997 [3439070][E](PTable): Success! + 359998 [3439770][E](PTable): Success! + 359999 [3439889][E](Custom_C): 01 19 <-targetPosition + 360000 [3439923][E](Custom_C): 01 19 <-targetPosition + 360001 [3440472][E](PTable): Success! + 360002 [3440473][E](PTable): Clean Power Table + 360003 [3440473][E](PTable): Averaged Entry: watts=128.399994, cad=75.400002, targetPosition=1218.00003, (3)(4) + 360004 [3440485][E](PTable): cellValue: (106) wattDelta: (1.898734) cadDelta: (0.316456) allNeighborsPassed: (0) + 360005 [3440496][E](PTable): rightValue: (0.000000) leftValue: (101.576004) bottomValue: (107.264008) topValue: (0.000000) New averaged targetPosition: (104.420006) count: (2) + 360006 [3440507][E](PTable): Bottom failed at: (105) Target pos: (104.420006) Avg pos: (104) + 360007 [3440518][E](PTable): All test failed bottom (2)(4)(120), readings (11) + 360008 [3440518][E](PTable): WEIGHTED DOWNVOTING: Target Value: (104), NeighborValue: (105) + 360009 [3440528][E](PTable): WEIGHTED DOWNVOTING: Delta: (1), Penalty: (0) + 360010 [3440539][E](PTable): PT failed (4)(4)(105), readings (10) + 360011 [3440540][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360012 [3440563][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360013 [3440595][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360014 [3440617][E](PTable): 70 rpm | 60 | 79 | | 111 | 120 | 130 | 141 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 360015 [3440649][E](PTable): 75 rpm | 48 | 64 | | | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360016 [3440672][E](PTable): 80 rpm | | 58 | | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360017 [3440704][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 360018 [3440725][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 360019 [3440758][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 360020 [3440779][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 360021 [3440811][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 360022 [3440832][E](PTable): Power Table Reset + 360023 [3440913][E](Custom_C): 01 27 00 <-Power Tab Data + 360024 [3440956][E](Custom_C): 01 27 00 <-Power Tab Data + 360025 [3440959][E](Custom_C): 01 2a <-hMin + 360026 [3441014][E](Custom_C): 01 19 <-targetPosition + 360027 [3441072][E](Custom_C): 01 27 01 <-Power Tab Data + 360028 [3441075][E](Custom_C): 01 2a <-hMin + 360029 [3441103][E](Custom_C): 01 2b <-hMax + 360030 [3441123][E](Custom_C): 01 19 <-targetPosition + 360031 [3441162][E](Custom_C): 01 27 02 <-Power Tab Data + 360032 [3441230][E](Custom_C): 01 27 01 <-Power Tab Data + 360033 [3441235][E](PTable): Success! + 360034 [3441235][E](ERG_Mode): Proportional: 20.000000, Integral: -5.500000, Derivative: 1.200000 + 360035 [3441259][E](Custom_C): 01 27 03 <-Power Tab Data + 360036 [3441341][E](Custom_C): 01 27 04 <-Power Tab Data + 360037 [3441343][E](Custom_C): 01 2b <-hMax + 360038 [3441409][E](Custom_C): 01 27 05 <-Power Tab Data + 360039 [3441467][E](Custom_C): 01 27 02 <-Power Tab Data + 360040 [3441495][E](Custom_C): 01 27 06 <-Power Tab Data + 360041 [3441544][E](Custom_C): 01 27 07 <-Power Tab Data + 360042 [3441590][E](Custom_C): 01 27 08 <-Power Tab Data + 360043 [3441634][E](Custom_C): 01 27 09 <-Power Tab Data + 360044 [3441736][E](Custom_C): 01 27 03 <-Power Tab Data + 360045 [3441913][E](Custom_C): 01 19 <-targetPosition + 360046 [3441937][E](PTable): Success! + 360047 [3442126][E](Custom_C): 01 27 04 <-Power Tab Data + 360048 [3442216][E](Custom_C): 01 27 05 <-Power Tab Data + 360049 [3442277][E](Custom_C): 01 27 06 <-Power Tab Data + 360050 [3442280][E](Custom_C): 01 25 <-Firmware Version + 360051 [3442398][E](Custom_C): 01 27 07 <-Power Tab Data + 360052 [3442576][E](Custom_C): 01 27 08 <-Power Tab Data + 360053 [3442635][E](Custom_C): 01 27 09 <-Power Tab Data + 360054 [3442641][E](PTable): Success! + 360055 [3442714][E](Custom_C): 01 19 <-targetPosition + 360056 [3442881][E](Custom_C): 01 19 <-targetPosition + 360057 [3442954][E](Custom_C): 01 19 <-targetPosition + 360058 [3443346][E](PTable): Success! + 360059 [3443347][E](PTable): Clean Power Table + 360060 [3443347][E](PTable): Averaged Entry: watts=122.000000, cad=75.000000, targetPosition=1211.99997, (3)(4) + 360061 [3443359][E](PTable): cellValue: (106) wattDelta: (1.973685) cadDelta: (0.328947) allNeighborsPassed: (0) + 360062 [3443370][E](PTable): rightValue: (0.000000) leftValue: (104.986664) bottomValue: (106.000000) topValue: (0.000000) New averaged targetPosition: (105.493332) count: (2) + 360063 [3443382][E](PTable): Bottom failed at: (105) Target pos: (105.493332) Avg pos: (105) + 360064 [3443393][E](PTable): Was not in range failed bottom (4)(4)(105), readings (10) + 360065 [3443393][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (105) + 360066 [3443403][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 360067 [3443404][E](PTable): PT failed (4)(4)(105), readings (10) + 360068 [3443416][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360069 [3443438][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360070 [3443471][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360071 [3443492][E](PTable): 70 rpm | 60 | 79 | | 111 | 120 | 130 | 141 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 360072 [3443524][E](PTable): 75 rpm | 48 | 64 | | | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360073 [3443546][E](PTable): 80 rpm | | 58 | | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360074 [3443578][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 360075 [3443599][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 360076 [3443633][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 360077 [3443655][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 360078 [3443686][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 360079 [3443707][E](PTable): Power Table Reset + 360080 [3443893][E](Custom_C): 01 19 <-targetPosition + 360081 [3444003][E](Custom_C): 01 19 <-targetPosition + 360082 [3444048][E](PTable): Success! + 360083 [3444745][E](FTMS_SERVER): 05 78 00 -> ERG Mode Target: 120 Current: 128 Incline: 121.699997 + 360084 [3444754][E](Custom_C): 01 28 <-targetWatts + 360085 [3444759][E](PTable): Success! + 360086 [3444885][E](Custom_C): 01 19 <-targetPosition + 360087 [3444933][E](Custom_C): 01 19 <-targetPosition + 360088 [3445461][E](PTable): Success! + 360089 [3445896][E](Custom_C): 01 2a <-hMin + 360090 [3445940][E](Custom_C): 01 19 <-targetPosition + 360091 [3446008][E](Custom_C): 01 2b <-hMax + 360092 [3446053][E](Custom_C): 01 25 <-Firmware Version + 360093 [3446073][E](Custom_C): 01 2a <-hMin + 360094 [3446164][E](PTable): Success! + 360095 [3446165][E](PTable): Clean Power Table + 360096 [3446165][E](PTable): Averaged Entry: watts=128.800003, cad=75.599998, targetPosition=1210.00000, (3)(4) + 360097 [3446176][E](PTable): cellValue: (106) wattDelta: (2.000000) cadDelta: (0.333333) allNeighborsPassed: (0) + 360098 [3446187][E](PTable): rightValue: (0.000000) leftValue: (101.599998) bottomValue: (107.799995) topValue: (0.000000) New averaged targetPosition: (104.699997) count: (2) + 360099 [3446198][E](PTable): Bottom failed at: (105) Target pos: (104.699997) Avg pos: (104) + 360100 [3446210][E](PTable): All test failed bottom (2)(4)(120), readings (11) + 360101 [3446210][E](PTable): WEIGHTED DOWNVOTING: Target Value: (104), NeighborValue: (105) + 360102 [3446220][E](PTable): WEIGHTED DOWNVOTING: Delta: (1), Penalty: (0) + 360103 [3446220][E](PTable): PT failed (4)(4)(105), readings (10) + 360104 [3446233][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360105 [3446254][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360106 [3446286][E](Custom_C): 01 19 <-targetPosition + 360107 [3446291][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360108 [3446313][E](PTable): 70 rpm | 60 | 79 | | 111 | 120 | 130 | 141 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 360109 [3446344][E](Custom_C): 01 2b <-hMax + 360110 [3446349][E](PTable): 75 rpm | 48 | 64 | | | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360111 [3446371][E](PTable): 80 rpm | | 58 | | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360112 [3446403][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 360113 [3446425][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 360114 [3446457][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 360115 [3446478][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 360116 [3446511][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 360117 [3446531][E](PTable): Power Table Reset + 360118 [3446542][E](ERG_Mode): Proportional: -48.000000, Integral: -7.200000, Derivative: -0.400000 + 360119 [3446866][E](PTable): Success! + 360120 [3446886][E](Custom_C): 01 19 <-targetPosition + 360121 [3446945][E](Custom_C): 01 19 <-targetPosition + 360122 [3447568][E](PTable): Success! + 360123 [3447898][E](Custom_C): 01 19 <-targetPosition + 360124 [3447993][E](Custom_C): 01 19 <-targetPosition + 360125 [3448270][E](PTable): Success! + 360126 [3448803][E](Custom_C): 01 25 <-Firmware Version + 360127 [3448889][E](Custom_C): 01 19 <-targetPosition + 360128 [3448923][E](Custom_C): 01 19 <-targetPosition + 360129 [3448973][E](PTable): Success! + 360130 [3448974][E](PTable): Clean Power Table + 360131 [3448975][E](PTable): Averaged Entry: watts=123.199997, cad=75.199997, targetPosition=1200.00000, (3)(4) + 360132 [3448986][E](PTable): cellValue: (106) wattDelta: (2.142857) cadDelta: (0.357143) allNeighborsPassed: (0) + 360133 [3448997][E](PTable): rightValue: (0.000000) leftValue: (104.506668) bottomValue: (106.559990) topValue: (0.000000) New averaged targetPosition: (105.533325) count: (2) + 360134 [3449008][E](PTable): Bottom failed at: (105) Target pos: (105.533325) Avg pos: (105) + 360135 [3449020][E](PTable): Was not in range failed bottom (4)(4)(105), readings (10) + 360136 [3449020][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (105) + 360137 [3449030][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 360138 [3449041][E](PTable): PT failed (4)(4)(105), readings (10) + 360139 [3449044][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360140 [3449066][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360141 [3449098][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360142 [3449120][E](PTable): 70 rpm | 60 | 79 | | 111 | 120 | 130 | 141 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 360143 [3449151][E](PTable): 75 rpm | 48 | 64 | | | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360144 [3449173][E](PTable): 80 rpm | | 58 | | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360145 [3449205][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 360146 [3449227][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 360147 [3449259][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 360148 [3449282][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 360149 [3449314][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 360150 [3449335][E](PTable): Power Table Reset + 360151 [3449738][E](PTable): Success! + 360152 [3449902][E](Custom_C): 01 19 <-targetPosition + 360153 [3449944][E](Custom_C): 01 19 <-targetPosition + 360154 [3450441][E](PTable): Success! + 360155 [3450890][E](Custom_C): 01 2a <-hMin + 360156 [3450958][E](Custom_C): 01 19 <-targetPosition + 360157 [3450963][E](Custom_C): 01 2a <-hMin + 360158 [3451026][E](Custom_C): 01 2b <-hMax + 360159 [3451054][E](Custom_C): 01 19 <-targetPosition + 360160 [3451144][E](Custom_C): 01 2b <-hMax + 360161 [3451152][E](PTable): Success! + 360162 [3451263][E](Custom_C): 01 25 <-Firmware Version + 360163 [3451857][E](PTable): Success! + 360164 [3451858][E](PTable): Clean Power Table + 360165 [3451858][E](PTable): Averaged Entry: watts=119.599998, cad=76.000000, targetPosition=1190.00000, (3)(4) + 360166 [3451870][E](PTable): cellValue: (106) wattDelta: (2.307692) cadDelta: (0.384615) allNeighborsPassed: (0) + 360167 [3451882][E](Custom_C): 01 19 <-targetPosition + 360168 [3451886][E](PTable): rightValue: (0.000000) leftValue: (106.173332) bottomValue: (108.599998) topValue: (103.400002) New averaged targetPosition: (106.057777) count: (3) + 360169 [3451897][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 360170 [3451953][E](Custom_C): 01 19 <-targetPosition + 360171 [3452262][E](Custom_C): 01 27 03 <-Power Tab Data + 360172 [3452267][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360173 [3452289][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 360174 [3452321][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 360175 [3452344][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 360176 [3452376][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 360177 [3452397][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 360178 [3452431][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 360179 [3452453][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 360180 [3452485][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 360181 [3452507][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 360182 [3452541][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 360183 [3452562][E](PTable): Power Table Reset + 360184 [3452582][E](PTable): Success! + 360185 [3452584][E](ERG_Mode): Proportional: -40.000000, Integral: -6.400000, Derivative: -1.600000 + 360186 [3452916][E](Custom_C): 01 19 <-targetPosition + 360187 [3452945][E](Custom_C): 01 19 <-targetPosition + 360188 [3453285][E](PTable): Success! + 360189 [3453907][E](Custom_C): 01 19 <-targetPosition + 360190 [3453933][E](Custom_C): 01 19 <-targetPosition + 360191 [3453989][E](PTable): Success! + 360192 [3454692][E](PTable): Success! + 360193 [3454693][E](PTable): Clean Power Table + 360194 [3454693][E](PTable): Averaged Entry: watts=127.199997, cad=77.000000, targetPosition=1190.00000, (3)(4) + 360195 [3454705][E](PTable): cellValue: (106) wattDelta: (2.307692) cadDelta: (0.384615) allNeighborsPassed: (0) + 360196 [3454715][E](PTable): rightValue: (0.000000) leftValue: (102.880005) bottomValue: (111.199997) topValue: (100.800003) New averaged targetPosition: (104.959999) count: (3) + 360197 [3454726][E](PTable): Bottom failed at: (105) Target pos: (104.959999) Avg pos: (104) + 360198 [3454737][E](PTable): All test failed bottom (2)(4)(120), readings (11) + 360199 [3454738][E](PTable): WEIGHTED DOWNVOTING: Target Value: (104), NeighborValue: (105) + 360200 [3454748][E](PTable): WEIGHTED DOWNVOTING: Delta: (1), Penalty: (0) + 360201 [3454759][E](PTable): PT failed (4)(4)(105), readings (10) + 360202 [3454760][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360203 [3454782][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360204 [3454815][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360205 [3454837][E](PTable): 70 rpm | 60 | 79 | | 111 | 120 | 130 | 141 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 360206 [3454869][E](PTable): 75 rpm | 48 | 64 | | | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360207 [3454890][E](PTable): 80 rpm | | 58 | | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360208 [3454921][E](Custom_C): 01 19 <-targetPosition + 360209 [3454924][E](Custom_C): 01 19 <-targetPosition + 360210 [3454928][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 360211 [3454961][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 360212 [3454983][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 360213 [3455006][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 360214 [3455038][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 360215 [3455058][E](PTable): Power Table Reset + 360216 [3455395][E](PTable): Success! + 360217 [3455899][E](Custom_C): 01 27 00 <-Power Tab Data + 360218 [3455931][E](Custom_C): 01 2a <-hMin + 360219 [3455986][E](Custom_C): 01 27 00 <-Power Tab Data + 360220 [3455989][E](Custom_C): 01 19 <-targetPosition + 360221 [3456063][E](Custom_C): 01 2a <-hMin + 360222 [3456079][E](Custom_C): 01 27 01 <-Power Tab Data + 360223 [3456099][E](PTable): Success! + 360224 [3456111][E](Custom_C): 01 2b <-hMax + 360225 [3456173][E](Custom_C): 01 27 02 <-Power Tab Data + 360226 [3456260][E](Custom_C): 01 27 03 <-Power Tab Data + 360227 [3456303][E](Custom_C): 01 19 <-targetPosition + 360228 [3456372][E](Custom_C): 01 27 04 <-Power Tab Data + 360229 [3456416][E](Custom_C): 01 27 05 <-Power Tab Data + 360230 [3456506][E](Custom_C): 01 27 06 <-Power Tab Data + 360231 [3456551][E](Custom_C): 01 27 07 <-Power Tab Data + 360232 [3456595][E](Custom_C): 01 27 08 <-Power Tab Data + 360233 [3456617][E](Custom_C): 01 27 01 <-Power Tab Data + 360234 [3456643][E](Custom_C): 01 27 09 <-Power Tab Data + 360235 [3456800][E](PTable): Success! + 360236 [3456898][E](Custom_C): 01 19 <-targetPosition + 360237 [3457324][E](Custom_C): 01 2b <-hMax + 360238 [3457501][E](PTable): Success! + 360239 [3457503][E](PTable): Clean Power Table + 360240 [3457504][E](PTable): Averaged Entry: watts=125.599998, cad=77.400002, targetPosition=1185.99998, (3)(4) + 360241 [3457515][E](PTable): cellValue: (106) wattDelta: (2.380953) cadDelta: (0.396825) allNeighborsPassed: (0) + 360242 [3457526][E](PTable): rightValue: (0.000000) leftValue: (103.648003) bottomValue: (112.048004) topValue: (99.951996) New averaged targetPosition: (105.216003) count: (3) + 360243 [3457537][E](PTable): Bottom failed at: (105) Target pos: (105.216003) Avg pos: (105) + 360244 [3457547][E](PTable): Was not in range failed bottom (4)(4)(105), readings (10) + 360245 [3457548][E](PTable): WEIGHTED DOWNVOTING: Target Value: (105), NeighborValue: (105) + 360246 [3457558][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 360247 [3457569][E](PTable): PT failed (4)(4)(105), readings (10) + 360248 [3457571][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360249 [3457593][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360250 [3457625][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360251 [3457646][E](PTable): 70 rpm | 60 | 79 | | 111 | 120 | 130 | 141 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 360252 [3457678][E](PTable): 75 rpm | 48 | 64 | | | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360253 [3457701][E](PTable): 80 rpm | | 58 | | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360254 [3457733][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 360255 [3457756][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 360256 [3457810][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 360257 [3457843][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 360258 [3457867][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 360259 [3457914][E](PTable): Power Table Reset + 360260 [3457925][E](Custom_C): 01 27 03 <-Power Tab Data + 360261 [3457996][E](Custom_C): 01 27 04 <-Power Tab Data + 360262 [3458056][E](Custom_C): 01 27 05 <-Power Tab Data + 360263 [3458203][E](PTable): Success! + 360264 [3458204][E](ERG_Mode): Proportional: 16.000000, Integral: -5.600000, Derivative: 1.000000 + 360265 [3458237][E](Custom_C): 01 27 06 <-Power Tab Data + 360266 [3458332][E](Custom_C): 01 27 07 <-Power Tab Data + 360267 [3458446][E](Custom_C): 01 27 08 <-Power Tab Data + 360268 [3458596][E](Custom_C): 01 27 09 <-Power Tab Data + 360269 [3458703][E](Custom_C): 01 19 <-targetPosition + 360270 [3458793][E](Custom_C): 01 19 <-targetPosition + 360271 [3458901][E](Custom_C): 01 19 <-targetPosition + 360272 [3458905][E](PTable): Success! + 360273 [3458945][E](Custom_C): 01 19 <-targetPosition + 360274 [3459457][E](FTMS_SERVER): 05 73 00 -> ERG Mode Target: 115 Current: 110 Incline: 118.980003 + 360275 [3459464][E](Custom_C): 01 28 <-targetWatts + 360276 [3459607][E](PTable): Success! + 360277 [3459891][E](Custom_C): 01 19 <-targetPosition + 360278 [3459963][E](Custom_C): 01 19 <-targetPosition + 360279 [3460310][E](PTable): Success! + 360280 [3460311][E](PTable): Clean Power Table + 360281 [3460311][E](PTable): Averaged Entry: watts=112.400002, cad=76.000000, targetPosition=1181.99997, (3)(4) + 360282 [3460323][E](PTable): cellValue: (106) wattDelta: (2.459017) cadDelta: (0.409836) allNeighborsPassed: (0) + 360283 [3460334][E](PTable): rightValue: (0.000000) leftValue: (109.090668) bottomValue: (108.440002) topValue: (103.559998) New averaged targetPosition: (107.030220) count: (3) + 360284 [3460345][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 360285 [3460697][E](Custom_C): 01 27 03 <-Power Tab Data + 360286 [3460703][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360287 [3460726][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 360288 [3460758][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 360289 [3460780][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 360290 [3460812][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 360291 [3460837][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 360292 [3460860][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 360293 [3460910][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 360294 [3460931][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 360295 [3460976][E](Custom_C): 01 2a <-hMin + 360296 [3460981][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 360297 [3461004][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 360298 [3461048][E](Custom_C): 01 19 <-targetPosition + 360299 [3461052][E](PTable): Power Table Reset + 360300 [3461130][E](PTable): Success! + 360301 [3461195][E](Custom_C): 01 2b <-hMax + 360302 [3461832][E](PTable): Success! + 360303 [3461894][E](Custom_C): 01 19 <-targetPosition + 360304 [3461973][E](Custom_C): 01 19 <-targetPosition + 360305 [3462298][E](Custom_C): 01 25 <-Firmware Version + 360306 [3462535][E](PTable): Success! + 360307 [3462907][E](Custom_C): 01 19 <-targetPosition + 360308 [3462933][E](Custom_C): 01 19 <-targetPosition + 360309 [3463240][E](PTable): Success! + 360310 [3463241][E](PTable): Clean Power Table + 360311 [3463242][E](PTable): Averaged Entry: watts=105.199997, cad=73.599998, targetPosition=1194.00002, (3)(4) + 360312 [3463253][E](PTable): cellValue: (106) wattDelta: (2.238806) cadDelta: (0.373134) allNeighborsPassed: (0) + 360313 [3463264][E](PTable): rightValue: (0.000000) leftValue: (112.610672) bottomValue: (102.247993) topValue: (109.752007) New averaged targetPosition: (108.203552) count: (3) + 360314 [3463275][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 360315 [3463640][E](Custom_C): 01 27 03 <-Power Tab Data + 360316 [3463647][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360317 [3463670][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 360318 [3463703][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 360319 [3463725][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 360320 [3463757][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 360321 [3463779][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 360322 [3463811][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 360323 [3463832][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 360324 [3463864][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 360325 [3463886][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 360326 [3463932][E](Custom_C): 01 19 <-targetPosition + 360327 [3463937][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 360328 [3463958][E](PTable): Power Table Reset + 360329 [3463959][E](ERG_Mode): Proportional: -28.000000, Integral: -2.000000, Derivative: -1.800000 + 360330 [3463987][E](PTable): Success! + 360331 [3464688][E](PTable): Success! + 360332 [3464886][E](Custom_C): 01 19 <-targetPosition + 360333 [3464975][E](Custom_C): 01 19 <-targetPosition + 360334 [3465390][E](PTable): Success! + 360335 [3465898][E](Custom_C): 01 2a <-hMin + 360336 [3465933][E](Custom_C): 01 2a <-hMin + 360337 [3465943][E](Custom_C): 01 19 <-targetPosition + 360338 [3465989][E](Custom_C): 01 2b <-hMax + 360339 [3466024][E](Custom_C): 01 19 <-targetPosition + 360340 [3466033][E](Custom_C): 01 25 <-Firmware Version + 360341 [3466092][E](PTable): Success! + 360342 [3466093][E](PTable): Clean Power Table + 360343 [3466093][E](PTable): Averaged Entry: watts=123.599998, cad=77.599998, targetPosition=1194.00002, (4)(4) + 360344 [3466105][E](PTable): cellValue: (105) wattDelta: (2.083333) cadDelta: (0.347222) allNeighborsPassed: (0) + 360345 [3466116][E](Custom_C): 01 2b <-hMax + 360346 [3466119][E](PTable): rightValue: (0.000000) leftValue: (103.272003) bottomValue: (98.087997) topValue: (0.000000) New averaged targetPosition: (100.680000) count: (2) + 360347 [3466131][E](PTable): Bottom failed at: (104) Target pos: (100.680000) Avg pos: (102) + 360348 [3466142][E](PTable): All test failed bottom (3)(4)(106), readings (11) + 360349 [3466142][E](PTable): WEIGHTED DOWNVOTING: Target Value: (100), NeighborValue: (104) + 360350 [3466152][E](PTable): WEIGHTED DOWNVOTING: Delta: (4), Penalty: (0) + 360351 [3466153][E](PTable): PT failed (5)(4)(104), readings (11) + 360352 [3466165][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360353 [3466187][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360354 [3466219][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360355 [3466241][E](PTable): 70 rpm | 60 | 79 | | 111 | 120 | 130 | 141 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 360356 [3466273][E](PTable): 75 rpm | 48 | 64 | | | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360357 [3466295][E](PTable): 80 rpm | | 58 | | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360358 [3466327][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 360359 [3466348][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 360360 [3466380][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 360361 [3466402][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 360362 [3466435][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 360363 [3466456][E](PTable): Power Table Reset + 360364 [3466794][E](PTable): Success! + 360365 [3466889][E](Custom_C): 01 19 <-targetPosition + 360366 [3466923][E](Custom_C): 01 19 <-targetPosition + 360367 [3467495][E](PTable): Success! + 360368 [3467923][E](Custom_C): 01 19 <-targetPosition + 360369 [3468094][E](Custom_C): 01 19 <-targetPosition + 360370 [3468197][E](PTable): Success! + 360371 [3468754][E](Custom_C): 01 25 <-Firmware Version + 360372 [3468891][E](Custom_C): 01 19 <-targetPosition + 360373 [3468900][E](PTable): Success! + 360374 [3468901][E](PTable): Clean Power Table + 360375 [3468901][E](PTable): Averaged Entry: watts=118.800003, cad=77.800003, targetPosition=1188.00003, (4)(4) + 360376 [3468913][E](PTable): cellValue: (105) wattDelta: (2.173913) cadDelta: (0.362319) allNeighborsPassed: (0) + 360377 [3468925][E](PTable): rightValue: (0.000000) leftValue: (105.552002) bottomValue: (98.928009) topValue: (0.000000) New averaged targetPosition: (102.240005) count: (2) + 360378 [3468936][E](Custom_C): 01 19 <-targetPosition + 360379 [3468940][E](PTable): Bottom failed at: (104) Target pos: (102.240005) Avg pos: (103) + 360380 [3468951][E](PTable): All test failed bottom (3)(4)(106), readings (11) + 360381 [3468952][E](PTable): WEIGHTED DOWNVOTING: Target Value: (102), NeighborValue: (104) + 360382 [3468963][E](PTable): WEIGHTED DOWNVOTING: Delta: (2), Penalty: (0) + 360383 [3468963][E](PTable): PT failed (5)(4)(104), readings (11) + 360384 [3468975][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360385 [3468997][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360386 [3469030][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360387 [3469052][E](PTable): 70 rpm | 60 | 79 | | 111 | 120 | 130 | 141 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 360388 [3469084][E](PTable): 75 rpm | 48 | 64 | | | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360389 [3469105][E](PTable): 80 rpm | | 58 | | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360390 [3469138][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 360391 [3469159][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 360392 [3469191][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 360393 [3469213][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 360394 [3469245][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 360395 [3469266][E](PTable): Power Table Reset + 360396 [3469266][E](ERG_Mode): Proportional: -36.000000, Integral: -5.800000, Derivative: 0.400000 + 360397 [3469623][E](PTable): Success! + 360398 [3469881][E](Custom_C): 01 19 <-targetPosition + 360399 [3469923][E](Custom_C): 01 19 <-targetPosition + 360400 [3470328][E](PTable): Success! + 360401 [3470330][E](PTable): Using detected travel limits during homing + 360402 [3470906][E](Custom_C): 01 27 00 <-Power Tab Data + 360403 [3470938][E](Custom_C): 01 2a <-hMin + 360404 [3470956][E](Custom_C): 01 27 00 <-Power Tab Data + 360405 [3470985][E](Custom_C): 01 19 <-targetPosition + 360406 [3471030][E](PTable): Success! + 360407 [3471040][E](Custom_C): 01 27 01 <-Power Tab Data + 360408 [3471119][E](Custom_C): 01 2b <-hMax + 360409 [3471126][E](Custom_C): 01 2a <-hMin + 360410 [3471178][E](Custom_C): 01 27 02 <-Power Tab Data + 360411 [3471221][E](Custom_C): 01 27 03 <-Power Tab Data + 360412 [3471265][E](Custom_C): 01 27 04 <-Power Tab Data + 360413 [3471274][E](Custom_C): 01 19 <-targetPosition + 360414 [3471335][E](Custom_C): 01 27 05 <-Power Tab Data + 360415 [3471401][E](Custom_C): 01 27 06 <-Power Tab Data + 360416 [3471445][E](Custom_C): 01 27 07 <-Power Tab Data + 360417 [3471491][E](Custom_C): 01 27 08 <-Power Tab Data + 360418 [3471536][E](Custom_C): 01 27 09 <-Power Tab Data + 360419 [3471678][E](Custom_C): 01 27 01 <-Power Tab Data + 360420 [3471735][E](PTable): Success! + 360421 [3471736][E](PTable): Clean Power Table + 360422 [3471736][E](PTable): Averaged Entry: watts=112.000000, cad=79.000000, targetPosition=1181.99997, (4)(4) + 360423 [3471748][E](PTable): cellValue: (105) wattDelta: (2.272728) cadDelta: (0.378788) allNeighborsPassed: (0) + 360424 [3471759][E](PTable): rightValue: (0.000000) leftValue: (108.519997) bottomValue: (102.360001) topValue: (0.000000) New averaged targetPosition: (105.440002) count: (2) + 360425 [3471769][E](PTable): Existing entry averaged (4)(4)(105), readings(10) + 360426 [3471883][E](Custom_C): 01 19 <-targetPosition + 360427 [3472146][E](Custom_C): 01 27 04 <-Power Tab Data + 360428 [3472152][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360429 [3472174][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 360430 [3472207][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 360431 [3472229][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 360432 [3472277][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 360433 [3472299][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 360434 [3472332][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 360435 [3472354][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 360436 [3472386][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 360437 [3472408][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 360438 [3472430][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 360439 [3472461][E](PTable): Power Table Reset + 360440 [3472481][E](PTable): Success! + 360441 [3472546][E](Custom_C): 01 27 02 <-Power Tab Data + 360442 [3472667][E](Custom_C): 01 27 03 <-Power Tab Data + 360443 [3472759][E](Custom_C): 01 27 04 <-Power Tab Data + 360444 [3472817][E](Custom_C): 01 27 05 <-Power Tab Data + 360445 [3472896][E](Custom_C): 01 19 <-targetPosition + 360446 [3472967][E](Custom_C): 01 27 06 <-Power Tab Data + 360447 [3473027][E](Custom_C): 01 27 07 <-Power Tab Data + 360448 [3473177][E](Custom_C): 01 27 08 <-Power Tab Data + 360449 [3473186][E](PTable): Success! + 360450 [3473356][E](Custom_C): 01 27 09 <-Power Tab Data + 360451 [3473494][E](Custom_C): 01 25 <-Firmware Version + 360452 [3473553][E](Custom_C): 01 19 <-targetPosition + 360453 [3473643][E](Custom_C): 01 19 <-targetPosition + 360454 [3473887][E](Custom_C): 01 19 <-targetPosition + 360455 [3473892][E](PTable): Success! + 360456 [3473945][E](Custom_C): 01 19 <-targetPosition + 360457 [3474500][E](FTMS_SERVER): 05 6e 00 -> ERG Mode Target: 110 Current: 110 Incline: 119.445999 + 360458 [3474509][E](Custom_C): 01 28 <-targetWatts + 360459 [3474597][E](PTable): Success! + 360460 [3474598][E](PTable): Clean Power Table + 360461 [3474598][E](PTable): Averaged Entry: watts=112.400002, cad=76.000000, targetPosition=1190.00000, (3)(4) + 360462 [3474611][E](PTable): cellValue: (106) wattDelta: (2.307692) cadDelta: (0.384615) allNeighborsPassed: (0) + 360463 [3474612][E](PTable): rightValue: (0.000000) leftValue: (109.293335) bottomValue: (108.599998) topValue: (103.400002) New averaged targetPosition: (107.097778) count: (3) + 360464 [3474633][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 360465 [3474898][E](Custom_C): 01 19 <-targetPosition + 360466 [3474933][E](Custom_C): 01 19 <-targetPosition + 360467 [3475010][E](Custom_C): 01 27 03 <-Power Tab Data + 360468 [3475016][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360469 [3475037][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 360470 [3475070][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 360471 [3475091][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 360472 [3475123][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 360473 [3475145][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 360474 [3475177][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 360475 [3475199][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 360476 [3475231][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 360477 [3475253][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 360478 [3475286][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 360479 [3475306][E](PTable): Power Table Reset + 360480 [3475317][E](ERG_Mode): Proportional: 0.000000, Integral: -2.800000, Derivative: -0.500000 + 360481 [3475400][E](PTable): Success! + 360482 [3475911][E](Custom_C): 01 2a <-hMin + 360483 [3475954][E](Custom_C): 01 2a <-hMin + 360484 [3475956][E](Custom_C): 01 19 <-targetPosition + 360485 [3476001][E](Custom_C): 01 2b <-hMax + 360486 [3476104][E](Custom_C): 01 19 <-targetPosition + 360487 [3476108][E](PTable): Success! + 360488 [3476224][E](Custom_C): 01 2b <-hMax + 360489 [3476810][E](PTable): Success! + 360490 [3476902][E](Custom_C): 01 19 <-targetPosition + 360491 [3476944][E](Custom_C): 01 19 <-targetPosition + 360492 [3477510][E](PTable): Success! + 360493 [3477511][E](PTable): Clean Power Table + 360494 [3477512][E](PTable): Averaged Entry: watts=112.400002, cad=76.599998, targetPosition=1190.00000, (3)(4) + 360495 [3477523][E](PTable): cellValue: (106) wattDelta: (2.307692) cadDelta: (0.384615) allNeighborsPassed: (0) + 360496 [3477535][E](PTable): rightValue: (0.000000) leftValue: (109.293335) bottomValue: (110.159996) topValue: (101.840004) New averaged targetPosition: (107.097778) count: (3) + 360497 [3477546][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 360498 [3477891][E](Custom_C): 01 19 <-targetPosition + 360499 [3477933][E](Custom_C): 01 27 03 <-Power Tab Data + 360500 [3477941][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360501 [3477964][E](Custom_C): 01 19 <-targetPosition + 360502 [3477968][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 360503 [3477991][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 360504 [3478023][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 360505 [3478045][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 360506 [3478077][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 360507 [3478098][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 360508 [3478130][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 360509 [3478152][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 360510 [3478185][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 360511 [3478206][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 360512 [3478238][E](PTable): Power Table Reset + 360513 [3478258][E](PTable): Success! + 360514 [3478903][E](Custom_C): 01 19 <-targetPosition + 360515 [3478960][E](PTable): Success! + 360516 [3478984][E](Custom_C): 01 19 <-targetPosition + 360517 [3479663][E](PTable): Success! + 360518 [3479893][E](Custom_C): 01 19 <-targetPosition + 360519 [3479943][E](Custom_C): 01 19 <-targetPosition + 360520 [3480366][E](PTable): Success! + 360521 [3480367][E](PTable): Clean Power Table + 360522 [3480367][E](PTable): Averaged Entry: watts=124.000000, cad=77.599998, targetPosition=1180.00000, (4)(4) + 360523 [3480379][E](PTable): cellValue: (105) wattDelta: (2.307692) cadDelta: (0.384615) allNeighborsPassed: (0) + 360524 [3480390][E](PTable): rightValue: (0.000000) leftValue: (103.266663) bottomValue: (98.759995) topValue: (0.000000) New averaged targetPosition: (101.013329) count: (2) + 360525 [3480404][E](PTable): Bottom failed at: (104) Target pos: (101.013329) Avg pos: (102) + 360526 [3480405][E](PTable): All test failed bottom (3)(4)(106), readings (11) + 360527 [3480415][E](PTable): WEIGHTED DOWNVOTING: Target Value: (101), NeighborValue: (104) + 360528 [3480426][E](PTable): WEIGHTED DOWNVOTING: Delta: (3), Penalty: (0) + 360529 [3480426][E](PTable): PT failed (5)(4)(104), readings (11) + 360530 [3480438][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360531 [3480460][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360532 [3480492][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360533 [3480514][E](PTable): 70 rpm | 60 | 79 | | 111 | 120 | 130 | 141 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 360534 [3480546][E](PTable): 75 rpm | 48 | 64 | | | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360535 [3480567][E](PTable): 80 rpm | | 58 | | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360536 [3480602][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 360537 [3480624][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 360538 [3480656][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 360539 [3480677][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 360540 [3480704][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 360541 [3480735][E](PTable): Power Table Reset + 360542 [3480736][E](ERG_Mode): Proportional: -8.000000, Integral: -6.200000, Derivative: 1.000000 + 360543 [3480884][E](Custom_C): 01 2a <-hMin + 360544 [3480934][E](Custom_C): 01 2a <-hMin + 360545 [3480973][E](Custom_C): 01 19 <-targetPosition + 360546 [3480994][E](Custom_C): 01 19 <-targetPosition + 360547 [3481042][E](Custom_C): 01 2b <-hMax + 360548 [3481069][E](PTable): Success! + 360549 [3481144][E](Custom_C): 01 2b <-hMax + 360550 [3481770][E](PTable): Success! + 360551 [3481896][E](Custom_C): 01 19 <-targetPosition + 360552 [3481954][E](Custom_C): 01 19 <-targetPosition + 360553 [3482278][E](Custom_C): 01 25 <-Firmware Version + 360554 [3482475][E](PTable): Success! + 360555 [3482887][E](Custom_C): 01 19 <-targetPosition + 360556 [3482943][E](Custom_C): 01 19 <-targetPosition + 360557 [3483176][E](PTable): Success! + 360558 [3483177][E](PTable): Clean Power Table + 360559 [3483177][E](PTable): Averaged Entry: watts=111.599998, cad=77.000000, targetPosition=1170.00000, (3)(4) + 360560 [3483188][E](PTable): cellValue: (106) wattDelta: (2.727273) cadDelta: (0.454545) allNeighborsPassed: (0) + 360561 [3483199][E](PTable): rightValue: (0.000000) leftValue: (109.080002) bottomValue: (110.400002) topValue: (101.599998) New averaged targetPosition: (107.026665) count: (3) + 360562 [3483210][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 360563 [3483553][E](Custom_C): 01 27 03 <-Power Tab Data + 360564 [3483561][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360565 [3483583][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 360566 [3483616][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 360567 [3483637][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 360568 [3483671][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 360569 [3483693][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 360570 [3483715][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 360571 [3483747][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 360572 [3483780][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 360573 [3483801][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 360574 [3483833][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 360575 [3483854][E](PTable): Power Table Reset + 360576 [3483900][E](Custom_C): 01 19 <-targetPosition + 360577 [3483934][E](Custom_C): 01 19 <-targetPosition + 360578 [3483950][E](PTable): Success! + 360579 [3484651][E](PTable): Success! + 360580 [3484888][E](Custom_C): 01 19 <-targetPosition + 360581 [3485014][E](Custom_C): 01 19 <-targetPosition + 360582 [3485353][E](PTable): Success! + 360583 [3485913][E](Custom_C): 01 27 00 <-Power Tab Data + 360584 [3485958][E](Custom_C): 01 27 00 <-Power Tab Data + 360585 [3485992][E](Custom_C): 01 2a <-hMin + 360586 [3486035][E](Custom_C): 01 2a <-hMin + 360587 [3486055][E](PTable): Success! + 360588 [3486055][E](PTable): Clean Power Table + 360589 [3486055][E](PTable): Averaged Entry: watts=105.199997, cad=77.199997, targetPosition=1170.00000, (3)(4) + 360590 [3486084][E](PTable): cellValue: (106) wattDelta: (2.727273) cadDelta: (0.454545) allNeighborsPassed: (0) + 360591 [3486085][E](PTable): rightValue: (0.000000) leftValue: (111.426666) bottomValue: (110.839996) topValue: (101.160004) New averaged targetPosition: (107.808891) count: (3) + 360592 [3486106][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 360593 [3486161][E](Custom_C): 01 27 01 <-Power Tab Data + 360594 [3486164][E](Custom_C): 01 19 <-targetPosition + 360595 [3486216][E](Custom_C): 01 2b <-hMax + 360596 [3486256][E](Custom_C): 01 27 01 <-Power Tab Data + 360597 [3486274][E](Custom_C): 01 27 02 <-Power Tab Data + 360598 [3486335][E](Custom_C): 01 2b <-hMax + 360599 [3486363][E](Custom_C): 01 27 03 <-Power Tab Data + 360600 [3486406][E](Custom_C): 01 27 02 <-Power Tab Data + 360601 [3486431][E](Custom_C): 01 27 04 <-Power Tab Data + 360602 [3486476][E](Custom_C): 01 27 05 <-Power Tab Data + 360603 [3486520][E](Custom_C): 01 27 06 <-Power Tab Data + 360604 [3486557][E](Custom_C): 01 27 03 <-Power Tab Data + 360605 [3486581][E](Custom_C): 01 27 07 <-Power Tab Data + 360606 [3486596][E](Custom_C): 01 27 03 <-Power Tab Data + 360607 [3486611][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360608 [3486634][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 360609 [3486699][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 360610 [3486755][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 360611 [3486811][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 360612 [3486834][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 360613 [3486882][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 360614 [3486936][E](Custom_C): 01 19 <-targetPosition + 360615 [3486943][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 360616 [3486965][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 360617 [3486999][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 360618 [3487042][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 360619 [3487073][E](PTable): Power Table Reset + 360620 [3487074][E](ERG_Mode): Proportional: 0.000000, Integral: -4.800000, Derivative: -0.800000 + 360621 [3487183][E](PTable): Success! + 360622 [3487217][E](Custom_C): 01 27 07 <-Power Tab Data + 360623 [3487396][E](Custom_C): 01 27 08 <-Power Tab Data + 360624 [3487486][E](Custom_C): 01 27 09 <-Power Tab Data + 360625 [3487534][E](Custom_C): 01 19 <-targetPosition + 360626 [3487881][E](Custom_C): 01 19 <-targetPosition + 360627 [3487887][E](PTable): Success! + 360628 [3487924][E](Custom_C): 01 19 <-targetPosition + 360629 [3488589][E](PTable): Success! + 360630 [3488885][E](Custom_C): 01 25 <-Firmware Version + 360631 [3488916][E](Custom_C): 01 19 <-targetPosition + 360632 [3488974][E](Custom_C): 01 19 <-targetPosition + 360633 [3489296][E](PTable): Success! + 360634 [3489297][E](PTable): Clean Power Table + 360635 [3489298][E](PTable): Averaged Entry: watts=114.800003, cad=77.400002, targetPosition=1170.00000, (3)(4) + 360636 [3489309][E](PTable): cellValue: (106) wattDelta: (2.727273) cadDelta: (0.454545) allNeighborsPassed: (0) + 360637 [3489320][E](PTable): rightValue: (0.000000) leftValue: (107.906662) bottomValue: (111.280006) topValue: (100.720001) New averaged targetPosition: (106.635559) count: (3) + 360638 [3489331][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 360639 [3489686][E](Custom_C): 01 27 03 <-Power Tab Data + 360640 [3489693][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360641 [3489716][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 360642 [3489748][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 360643 [3489769][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 360644 [3489801][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 360645 [3489825][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 360646 [3489857][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 360647 [3489879][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 360648 [3489926][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 360649 [3489968][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 360650 [3489990][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 360651 [3490021][E](PTable): Power Table Reset + 360652 [3490038][E](FTMS_SERVER): 05 69 00 -> ERG Mode Target: 105 Current: 110 Incline: 116.724007 + 360653 [3490045][E](Custom_C): 01 28 <-targetWatts + 360654 [3490047][E](PTable): Success! + 360655 [3490752][E](PTable): Success! + 360656 [3490896][E](Custom_C): 01 2a <-hMin + 360657 [3490923][E](Custom_C): 01 2a <-hMin + 360658 [3490963][E](Custom_C): 01 19 <-targetPosition + 360659 [3491008][E](Custom_C): 01 2b <-hMax + 360660 [3491013][E](Custom_C): 01 19 <-targetPosition + 360661 [3491134][E](Custom_C): 01 2b <-hMax + 360662 [3491194][E](Custom_C): 01 25 <-Firmware Version + 360663 [3491457][E](PTable): Success! + 360664 [3491886][E](Custom_C): 01 19 <-targetPosition + 360665 [3491944][E](Custom_C): 01 19 <-targetPosition + 360666 [3492161][E](PTable): Success! + 360667 [3492162][E](PTable): Clean Power Table + 360668 [3492162][E](PTable): Averaged Entry: watts=109.199997, cad=77.000000, targetPosition=1164.00002, (3)(4) + 360669 [3492175][E](PTable): cellValue: (106) wattDelta: (2.884615) cadDelta: (0.480769) allNeighborsPassed: (1) + 360670 [3492177][E](PTable): rightValue: (102.255997) leftValue: (109.744003) bottomValue: (110.160004) topValue: (101.839996) New averaged targetPosition: (106.000000) count: (4) + 360671 [3492198][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 360672 [3492534][E](Custom_C): 01 27 03 <-Power Tab Data + 360673 [3492540][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360674 [3492562][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 360675 [3492594][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 360676 [3492616][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 360677 [3492648][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 360678 [3492669][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 360679 [3492701][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 360680 [3492723][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 360681 [3492755][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 360682 [3492776][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 360683 [3492809][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 360684 [3492830][E](PTable): Power Table Reset + 360685 [3492840][E](ERG_Mode): Proportional: -20.000000, Integral: -6.500000, Derivative: -0.200000 + 360686 [3492913][E](PTable): Success! + 360687 [3492921][E](Custom_C): 01 19 <-targetPosition + 360688 [3492934][E](Custom_C): 01 19 <-targetPosition + 360689 [3493616][E](PTable): Success! + 360690 [3493888][E](Custom_C): 01 19 <-targetPosition + 360691 [3493924][E](Custom_C): 01 19 <-targetPosition + 360692 [3494321][E](PTable): Success! + 360693 [3494878][E](Custom_C): 01 19 <-targetPosition + 360694 [3494977][E](Custom_C): 01 19 <-targetPosition + 360695 [3495026][E](PTable): Success! + 360696 [3495027][E](PTable): Clean Power Table + 360697 [3495027][E](PTable): Averaged Entry: watts=114.400002, cad=77.199997, targetPosition=1158.00003, (3)(4) + 360698 [3495031][E](PTable): cellValue: (106) wattDelta: (3.061224) cadDelta: (0.510204) allNeighborsPassed: (1) + 360699 [3495043][E](PTable): rightValue: (104.170670) leftValue: (107.829330) bottomValue: (110.311996) topValue: (101.688004) New averaged targetPosition: (106.000000) count: (4) + 360700 [3495065][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 360701 [3495403][E](Custom_C): 01 27 03 <-Power Tab Data + 360702 [3495409][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360703 [3495431][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 360704 [3495463][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 360705 [3495485][E](PTable): 70 rpm | 60 | 79 | 96 | 111 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 360706 [3495517][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 360707 [3495539][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 360708 [3495572][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 360709 [3495595][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 360710 [3495626][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 360711 [3495648][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 360712 [3495680][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 360713 [3495701][E](PTable): Power Table Reset + 360714 [3495729][E](PTable): Success! + 360715 [3495891][E](Custom_C): 01 2a <-hMin + 360716 [3495935][E](Custom_C): 01 19 <-targetPosition + 360717 [3496000][E](Custom_C): 01 2a <-hMin + 360718 [3496037][E](Custom_C): 01 2b <-hMax + 360719 [3496114][E](Custom_C): 01 19 <-targetPosition + 360720 [3496294][E](Custom_C): 01 2b <-hMax + 360721 [3496433][E](PTable): Success! + 360722 [3496903][E](Custom_C): 01 19 <-targetPosition + 360723 [3496924][E](Custom_C): 01 19 <-targetPosition + 360724 [3497136][E](PTable): Success! + 360725 [3497841][E](PTable): Success! + 360726 [3497842][E](PTable): Clean Power Table + 360727 [3497842][E](PTable): Averaged Entry: watts=108.800003, cad=78.000000, targetPosition=1148.00003, (4)(4) + 360728 [3497854][E](PTable): cellValue: (105) wattDelta: (3.061224) cadDelta: (0.510204) allNeighborsPassed: (0) + 360729 [3497865][E](PTable): rightValue: (0.000000) leftValue: (108.658669) bottomValue: (101.080002) topValue: (0.000000) New averaged targetPosition: (104.869339) count: (2) + 360730 [3497876][E](PTable): Bottom failed at: (104) Target pos: (104.869339) Avg pos: (104) + 360731 [3497886][E](PTable): Was not in range failed bottom (5)(4)(104), readings (11) + 360732 [3497887][E](PTable): WEIGHTED DOWNVOTING: Target Value: (104), NeighborValue: (104) + 360733 [3497897][E](Custom_C): 01 19 <-targetPosition + 360734 [3497900][E](PTable): WEIGHTED DOWNVOTING: Delta: (0), Penalty: (0) + 360735 [3497905][E](PTable): PT failed (5)(4)(104), readings (11) + 360736 [3497918][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360737 [3497940][E](PTable): 60 rpm | | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360738 [3497974][E](Custom_C): 01 19 <-targetPosition + 360739 [3497978][E](PTable): 65 rpm | | 85 | | 124 | 130 | 139 | | 153 | 162 | 169 | 181 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360740 [3498000][E](PTable): 70 rpm | 60 | 79 | | 111 | 120 | 130 | 141 | 147 | 158 | | | 179 | 189 | 197 | | 209 | | | | | | | | | | | | | | | | | | | | | | | | + 360741 [3498033][E](PTable): 75 rpm | 48 | 64 | | | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | | | | | | | | | | | | | | | | | | | | | | | | | | | | + 360742 [3498055][E](PTable): 80 rpm | | 58 | | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | | | | | | | | | | | | | | | | | | | | | | | | | | + 360743 [3498086][E](PTable): 85 rpm | | | | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | | 171 | | | | | | | | | | | | | | | | | | | | | | | | | + 360744 [3498108][E](PTable): 90 rpm | | | | | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | | 176 | | | | | | | | | | | | | | | | | | | | | | | | + 360745 [3498142][E](PTable): 95 rpm | | | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | | 166 | | | | | | | | | | | | | | | | | | | | | | | | | + 360746 [3498164][E](PTable): 100 rpm | | | | | 99 | | 113 | 118 | | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | | | | | | | | | | | | | | | | | | | | | + 360747 [3498195][E](PTable): 105 rpm | | | | | | | 107 | | 122 | 138 | | 143 | | 152 | | 163 | | | | | | | | | | | | | | | | | | | | | | | | + 360748 [3498216][E](PTable): Power Table Reset + 360749 [3498217][E](ERG_Mode): Proportional: 60.000000, Integral: -4.500000, Derivative: 1.600000 + 360750 [3498543][E](PTable): Success! + 360751 [3498883][E](Custom_C): 01 19 <-targetPosition + 360752 [3498964][E](Custom_C): 01 19 <-targetPosition + 360753 [3499244][E](PTable): Success! + 360754 [3499896][E](Custom_C): 01 19 <-targetPosition + 360755 [3499923][E](Custom_C): 01 19 <-targetPosition + 360756 [3499946][E](PTable): Success! + 360757 [3500651][E](PTable): Success! + 360758 [3500652][E](PTable): Clean Power Table + 360759 [3500652][E](PTable): Averaged Entry: watts=95.199997, cad=76.800003, targetPosition=1150.00000, (3)(3) + 360760 [3500663][E](PTable): Keep old targetPosition: (115.000000) + 360761 [3500664][E](PTable): Right failed at: (106) Target pos: (115.000000) Avg pos: (110) + 360762 [3500675][E](PTable): Current Position moved right was valid! Current position: 115.000000 + 360763 [3500686][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 360764 [3500909][E](Custom_C): 01 27 00 <-Power Tab Data + 360765 [3500956][E](Custom_C): 01 27 00 <-Power Tab Data + 360766 [3500959][E](Custom_C): 01 2a <-hMin + 360767 [3500998][E](Custom_C): 01 19 <-targetPosition + 360768 [3501032][E](PTable): Top failed at: (111) Target pos: (115.000000) Avg pos: (113) + 360769 [3501034][E](PTable): Current Position moved up was valid! Current position: 115.000000 + 360770 [3501046][E](PTable): Existing entry averaged (2)(3)(112), readings(3) + 360771 [3501086][E](Custom_C): 01 2a <-hMin + 360772 [3501124][E](Custom_C): 01 19 <-targetPosition + 360773 [3501133][E](Custom_C): 01 2b <-hMax + 360774 [3501214][E](Custom_C): 01 27 02 <-Power Tab Data + 360775 [3501257][E](Custom_C): 01 27 01 <-Power Tab Data + 360776 [3501260][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360777 [3501326][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 360778 [3501369][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 360779 [3501426][E](PTable): 70 rpm | 60 | 79 | 96 | 112 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 360780 [3501451][E](PTable): 75 rpm | 48 | 64 | 93 | 103 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 360781 [3501513][E](PTable): 80 rpm | 36 | 58 | 89 | | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 360782 [3501536][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 360783 [3501595][E](PTable): 90 rpm | 12 | 52 | 82 | 99 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 360784 [3501649][E](PTable): 95 rpm | 0 | 49 | 79 | | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 360785 [3501710][E](PTable): 100 rpm | -12 | 46 | 77 | | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 360786 [3501731][E](PTable): 105 rpm | -24 | 45 | 75 | 98 | | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 360787 [3501774][E](Custom_C): 01 27 08 <-Power Tab Data + 360788 [3501798][E](Custom_C): 01 27 03 <-Power Tab Data + 360789 [3501821][E](Custom_C): 01 27 09 <-Power Tab Data + 360790 [3501886][E](Custom_C): 01 19 <-targetPosition + 360791 [3501916][E](Custom_C): 01 27 04 <-Power Tab Data + 360792 [3501934][E](PTable): Writing File: /PowerTable.txt + 360793 [3501976][E](Custom_C): 01 27 05 <-Power Tab Data + 360794 [3502074][E](Custom_C): 01 27 06 <-Power Tab Data + 360795 [3502196][E](Custom_C): 01 27 07 <-Power Tab Data + 360796 [3502282][E](Custom_C): 01 27 08 <-Power Tab Data + 360797 [3502284][E](Custom_C): 01 25 <-Firmware Version + 360798 [3502337][E](Custom_C): 01 27 09 <-Power Tab Data + 360799 [3502414][E](Custom_C): 01 19 <-targetPosition + 360800 [3502425][E](PTable): Power table saved successfully with 101 readings + 360801 [3502425][E](PTable): Power Table Reset + 360802 [3502581][E](PTable): Success! + 360803 [3502888][E](Custom_C): 01 19 <-targetPosition + 360804 [3502954][E](Custom_C): 01 19 <-targetPosition + 360805 [3503285][E](PTable): Success! + 360806 [3503901][E](Custom_C): 01 19 <-targetPosition + 360807 [3503974][E](Custom_C): 01 19 <-targetPosition + 360808 [3503988][E](PTable): Success! + 360809 [3503989][E](ERG_Mode): Proportional: 52.000000, Integral: -0.700000, Derivative: 0.200000 + 360810 [3504692][E](PTable): Success! + 360811 [3504693][E](PTable): Clean Power Table + 360812 [3504693][E](PTable): Averaged Entry: watts=94.800003, cad=76.000000, targetPosition=1155.99998, (3)(3) + 360813 [3504705][E](PTable): Keep old targetPosition: (115.599998) + 360814 [3504706][E](PTable): Right failed at: (106) Target pos: (115.599998) Avg pos: (110) + 360815 [3504717][E](PTable): Current Position moved right was valid! Current position: 115.599998 + 360816 [3504728][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 360817 [3504891][E](Custom_C): 01 19 <-targetPosition + 360818 [3504994][E](Custom_C): 01 19 <-targetPosition + 360819 [3505092][E](PTable): Top failed at: (112) Target pos: (115.599998) Avg pos: (113) + 360820 [3505094][E](PTable): Current Position moved up was valid! Current position: 115.599998 + 360821 [3505105][E](PTable): Existing entry averaged (2)(3)(112), readings(4) + 360822 [3505224][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360823 [3505246][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 360824 [3505279][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 360825 [3505300][E](PTable): 70 rpm | 60 | 79 | 96 | 112 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 360826 [3505332][E](PTable): 75 rpm | 48 | 64 | 93 | 104 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 360827 [3505353][E](PTable): 80 rpm | 36 | 58 | 89 | 102 | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 360828 [3505385][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 104 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 360829 [3505407][E](PTable): 90 rpm | 12 | 52 | 82 | 98 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 360830 [3505439][E](PTable): 95 rpm | 0 | 49 | 79 | 97 | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 360831 [3505462][E](PTable): 100 rpm | -12 | 46 | 77 | 96 | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 360832 [3505485][E](PTable): 105 rpm | -24 | 45 | 75 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 360833 [3505516][E](PTable): Power Table Reset + 360834 [3505533][E](FTMS_SERVER): 11 00 00 f7 ff 28 33 -> Sim Mode Incline -0.090000 + 360835 [3505540][E](Custom_C): 01 10 <-FTMSMode + 360836 [3505544][E](PTable): Success! + 360837 [3505881][E](Custom_C): 01 2a <-hMin + 360838 [3505937][E](Custom_C): 01 19 <-targetPosition + 360839 [3505954][E](Custom_C): 01 2a <-hMin + 360840 [3505971][E](Custom_C): 01 2b <-hMax + 360841 [3506014][E](Custom_C): 01 19 <-targetPosition + 360842 [3506060][E](Custom_C): 01 25 <-Firmware Version + 360843 [3506075][E](Custom_C): 01 2b <-hMax + 360844 [3506245][E](PTable): Success! + 360845 [3506547][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000 + 360846 [3506893][E](Custom_C): 01 19 <-targetPosition + 360847 [3506949][E](PTable): Success! + 360848 [3506974][E](Custom_C): 01 19 <-targetPosition + 360849 [3507154][E](Custom_C): 01 25 <-Firmware Version + 360850 [3507304][E](Custom_C): 01 15 <-connectedPowerMete + 360851 [3507454][E](Custom_C): 01 16 <-connectedHeartMonitor + 360852 [3507544][E](Custom_C): 01 14 <-foundDevices + 360853 [3507654][E](PTable): Success! + 360854 [3507655][E](PTable): Clean Power Table + 360855 [3507655][E](PTable): Averaged Entry: watts=115.599998, cad=77.599998, targetPosition=1115.99998, (4)(4) + 360856 [3507667][E](PTable): cellValue: (105) wattDelta: (4.545455) cadDelta: (0.757576) allNeighborsPassed: (0) + 360857 [3507678][E](PTable): rightValue: (104.031998) leftValue: (105.968002) bottomValue: (101.832001) topValue: (0.000000) New averaged targetPosition: (103.944000) count: (3) + 360858 [3507689][E](PTable): Bottom failed at: (104) Target pos: (103.944000) Avg pos: (103) + 360859 [3507700][E](Custom_C): 01 08 <-shiftStep + 360860 [3507703][E](PTable): Current Position moved down is valid! Current position: 103.944000 + 360861 [3507704][E](PTable): Existing entry averaged (5)(4)(103), readings(11) + 360862 [3507784][E](Custom_C): 01 20 <-ShiftDir + 360863 [3507845][E](Custom_C): 01 18 <-saveToLittleFS + 360864 [3507883][E](Custom_C): 01 19 <-targetPosition + 360865 [3507964][E](Custom_C): 01 0b <-inclineMultiplier + 360866 [3508024][E](Custom_C): 01 1f <-ERGSensitivity + 360867 [3508086][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360868 [3508108][E](PTable): 60 rpm | 84 | 86 | 103 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 360869 [3508155][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 360870 [3508177][E](PTable): 70 rpm | 60 | 79 | 96 | 112 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 360871 [3508209][E](PTable): 75 rpm | 48 | 64 | 93 | 104 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 360872 [3508230][E](PTable): 80 rpm | 36 | 58 | 89 | 102 | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 360873 [3508277][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 103 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 360874 [3508299][E](PTable): 90 rpm | 12 | 52 | 82 | 98 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 360875 [3508331][E](PTable): 95 rpm | 0 | 49 | 79 | 97 | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 360876 [3508353][E](PTable): 100 rpm | -12 | 46 | 77 | 96 | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 360877 [3508384][E](Custom_C): 01 03 <-simulatedWatts + 360878 [3508392][E](PTable): 105 rpm | -24 | 45 | 75 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 360879 [3508413][E](PTable): Power Table Reset + 360880 [3508451][E](Custom_C): 01 04 <-simulatedHr + 360881 [3508535][E](PTable): Success! + 360882 [3508536][E](PTable): Using detected travel limits during homing + 360883 [3508566][E](Custom_C): 01 28 <-targetWatts + 360884 [3508714][E](Custom_C): 01 05 <-simulatedCad + 360885 [3508804][E](Custom_C): 01 06 <-simulatedSpeed + 360886 [3508894][E](Custom_C): 01 07 <-deviceName + 360887 [3508907][E](Custom_C): 01 19 <-targetPosition + 360888 [3508984][E](Custom_C): 01 09 <-stepperPower + 360889 [3509104][E](Custom_C): 01 0a <-stealthChop + 360890 [3509224][E](Custom_C): 01 0c <-powerCorrectionFactor + 360891 [3509238][E](PTable): Success! + 360892 [3509284][E](Custom_C): 01 0d <-simulateHr + 360893 [3509434][E](Custom_C): 01 0e <-simulateWatts + 360894 [3509494][E](Custom_C): 01 29 <-simulatetargetwatts + 360895 [3509554][E](Custom_C): 01 0f <-simulateCad + 360896 [3509644][E](Custom_C): 01 10 <-FTMSMode + 360897 [3509854][E](Custom_C): 01 11 <-autoUpdate + 360898 [3509898][E](Custom_C): 01 19 <-targetPosition + 360899 [3509943][E](PTable): Success! + 360900 [3510647][E](PTable): Success! + 360901 [3510648][E](PTable): Clean Power Table + 360902 [3510650][E](PTable): Averaged Entry: watts=72.000000, cad=80.599998, targetPosition=1080.00000, (4)(2) + 360903 [3510661][E](PTable): Keep old targetPosition: (108.000000) + 360904 [3510662][E](PTable): Right failed at: (105) Target pos: (108.000000) Avg pos: (106) + 360905 [3510673][E](PTable): All test failed right (4)(4)(105), readings (11) + 360906 [3510673][E](PTable): WEIGHTED DOWNVOTING: Target Value: (108), NeighborValue: (105) + 360907 [3510684][E](PTable): WEIGHTED DOWNVOTING: Delta: (3), Penalty: (0) + 360908 [3510694][E](PTable): PT failed (4)(4)(105), readings (11) + 360909 [3510697][E](PTable): Top failed at: (103) Target pos: (108.000000) Avg pos: (105) + 360910 [3510698][E](PTable): Current Position moved up was valid! Current position: 108.000000 + 360911 [3510709][E](PTable): Existing entry averaged (0)(2)(104), readings(3) + 360912 [3510887][E](Custom_C): 01 2a <-hMin + 360913 [3510944][E](Custom_C): 01 19 <-targetPosition + 360914 [3510988][E](Custom_C): 01 2b <-hMax + 360915 [3511117][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360916 [3511140][E](PTable): 60 rpm | 84 | 86 | 104 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 360917 [3511163][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 360918 [3511195][E](PTable): 70 rpm | 60 | 79 | 97 | 112 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 360919 [3511217][E](PTable): 75 rpm | 48 | 64 | 93 | 104 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 360920 [3511249][E](PTable): 80 rpm | 36 | 58 | 90 | 102 | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 360921 [3511271][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 103 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 360922 [3511303][E](PTable): 90 rpm | 12 | 52 | 83 | 98 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 360923 [3511325][E](PTable): 95 rpm | 0 | 49 | 79 | 97 | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 360924 [3511357][E](PTable): 100 rpm | -12 | 46 | 77 | 96 | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 360925 [3511379][E](PTable): 105 rpm | -24 | 45 | 75 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 360926 [3511410][E](PTable): Power Table Reset + 360927 [3511431][E](PTable): Success! + 360928 [3511888][E](Custom_C): 01 19 <-targetPosition + 360929 [3512137][E](PTable): Success! + 360930 [3512841][E](PTable): Success! + 360931 [3512901][E](Custom_C): 01 19 <-targetPosition + 360932 [3513544][E](PTable): Success! + 360933 [3513545][E](PTable): Clean Power Table + 360934 [3513545][E](PTable): Averaged Entry: watts=81.199997, cad=77.000000, targetPosition=1080.00000, (3)(3) + 360935 [3513556][E](PTable): Keep old targetPosition: (108.000000) + 360936 [3513557][E](PTable): Right failed at: (106) Target pos: (108.000000) Avg pos: (107) + 360937 [3513567][E](PTable): Current Position moved right was valid! Current position: 108.000000 + 360938 [3513571][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 360939 [3513891][E](Custom_C): 01 19 <-targetPosition + 360940 [3513919][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360941 [3513941][E](PTable): 60 rpm | 84 | 86 | 104 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 360942 [3513973][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 360943 [3513995][E](PTable): 70 rpm | 60 | 79 | 97 | 112 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 360944 [3514027][E](PTable): 75 rpm | 48 | 64 | 93 | 104 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 360945 [3514049][E](PTable): 80 rpm | 36 | 58 | 90 | 102 | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 360946 [3514083][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 103 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 360947 [3514104][E](PTable): 90 rpm | 12 | 52 | 83 | 98 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 360948 [3514136][E](PTable): 95 rpm | 0 | 49 | 79 | 97 | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 360949 [3514158][E](PTable): 100 rpm | -12 | 46 | 77 | 96 | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 360950 [3514190][E](PTable): 105 rpm | -24 | 45 | 75 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 360951 [3514211][E](PTable): Power Table Reset + 360952 [3514277][E](PTable): Success! + 360953 [3514881][E](Custom_C): 01 19 <-targetPosition + 360954 [3514978][E](PTable): Success! + 360955 [3515681][E](PTable): Success! + 360956 [3515905][E](Custom_C): 01 27 00 <-Power Tab Data + 360957 [3515938][E](Custom_C): 01 2a <-hMin + 360958 [3515983][E](Custom_C): 01 19 <-targetPosition + 360959 [3516063][E](Custom_C): 01 27 01 <-Power Tab Data + 360960 [3516107][E](Custom_C): 01 2b <-hMax + 360961 [3516176][E](Custom_C): 01 27 02 <-Power Tab Data + 360962 [3516220][E](Custom_C): 01 27 03 <-Power Tab Data + 360963 [3516300][E](Custom_C): 01 27 04 <-Power Tab Data + 360964 [3516385][E](PTable): Success! + 360965 [3516390][E](Custom_C): 01 27 05 <-Power Tab Data + 360966 [3516414][E](PTable): Averaged Entry: watts=87.199997, cad=77.000000, targetPosition=1080.00000, (3)(3) + 360967 [3516416][E](PTable): Keep old targetPosition: (108.000000) + 360968 [3516426][E](PTable): Right failed at: (106) Target pos: (108.000000) Avg pos: (107) + 360969 [3516427][E](PTable): Current Position moved right was valid! Current position: 108.000000 + 360970 [3516438][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 360971 [3516513][E](Custom_C): 01 27 06 <-Power Tab Data + 360972 [3516581][E](Custom_C): 01 27 07 <-Power Tab Data + 360973 [3516626][E](Custom_C): 01 27 08 <-Power Tab Data + 360974 [3516671][E](Custom_C): 01 27 09 <-Power Tab Data + 360975 [3516863][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 360976 [3516884][E](Custom_C): 01 19 <-targetPosition + 360977 [3516889][E](PTable): 60 rpm | 84 | 86 | 104 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 360978 [3516921][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 360979 [3516943][E](PTable): 70 rpm | 60 | 79 | 97 | 112 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 360980 [3516975][E](PTable): 75 rpm | 48 | 64 | 93 | 104 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 360981 [3516997][E](PTable): 80 rpm | 36 | 58 | 90 | 102 | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 360982 [3517029][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 103 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 360983 [3517050][E](PTable): 90 rpm | 12 | 52 | 83 | 98 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 360984 [3517083][E](PTable): 95 rpm | 0 | 49 | 79 | 97 | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 360985 [3517104][E](PTable): 100 rpm | -12 | 46 | 77 | 96 | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 360986 [3517136][E](PTable): 105 rpm | -24 | 45 | 75 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 360987 [3517157][E](PTable): Power Table Reset + 360988 [3517176][E](PTable): Success! + 360989 [3517878][E](PTable): Success! + 360990 [3517907][E](Custom_C): 01 19 <-targetPosition + 360991 [3518580][E](PTable): Success! + 360992 [3518908][E](Custom_C): 01 19 <-targetPosition + 360993 [3519285][E](PTable): Success! + 360994 [3519286][E](PTable): Clean Power Table + 360995 [3519286][E](PTable): Averaged Entry: watts=82.000000, cad=77.000000, targetPosition=1080.00000, (3)(3) + 360996 [3519298][E](PTable): Keep old targetPosition: (108.000000) + 360997 [3519298][E](PTable): Right failed at: (106) Target pos: (108.000000) Avg pos: (107) + 360998 [3519309][E](PTable): Current Position moved right was valid! Current position: 108.000000 + 360999 [3519320][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 361000 [3519655][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 361001 [3519677][E](PTable): 60 rpm | 84 | 86 | 104 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 361002 [3519709][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 361003 [3519731][E](PTable): 70 rpm | 60 | 79 | 97 | 112 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 361004 [3519763][E](PTable): 75 rpm | 48 | 64 | 93 | 104 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 361005 [3519785][E](PTable): 80 rpm | 36 | 58 | 90 | 102 | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 361006 [3519817][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 103 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 361007 [3519838][E](PTable): 90 rpm | 12 | 52 | 83 | 98 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 361008 [3519870][E](PTable): 95 rpm | 0 | 49 | 79 | 97 | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 361009 [3519891][E](Custom_C): 01 19 <-targetPosition + 361010 [3519896][E](PTable): 100 rpm | -12 | 46 | 77 | 96 | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 361011 [3519931][E](PTable): 105 rpm | -24 | 45 | 75 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 361012 [3519953][E](PTable): Power Table Reset + 361013 [3520011][E](PTable): Success! + 361014 [3520714][E](PTable): Success! + 361015 [3520888][E](Custom_C): 01 2a <-hMin + 361016 [3520933][E](Custom_C): 01 19 <-targetPosition + 361017 [3520978][E](Custom_C): 01 2b <-hMax + 361018 [3521417][E](PTable): Success! + 361019 [3521901][E](Custom_C): 01 19 <-targetPosition + 361020 [3522120][E](PTable): Success! + 361021 [3522121][E](PTable): Clean Power Table + 361022 [3522121][E](PTable): Averaged Entry: watts=87.199997, cad=76.599998, targetPosition=1080.00000, (3)(3) + 361023 [3522133][E](PTable): Keep old targetPosition: (108.000000) + 361024 [3522134][E](PTable): Right failed at: (106) Target pos: (108.000000) Avg pos: (107) + 361025 [3522145][E](PTable): Current Position moved right was valid! Current position: 108.000000 + 361026 [3522155][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 361027 [3522283][E](Custom_C): 01 25 <-Firmware Version + 361028 [3522510][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 361029 [3522532][E](PTable): 60 rpm | 84 | 86 | 104 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 361030 [3522564][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 361031 [3522586][E](PTable): 70 rpm | 60 | 79 | 97 | 112 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 361032 [3522618][E](PTable): 75 rpm | 48 | 64 | 93 | 104 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 361033 [3522639][E](PTable): 80 rpm | 36 | 58 | 90 | 102 | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 361034 [3522671][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 103 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 361035 [3522693][E](PTable): 90 rpm | 12 | 52 | 83 | 98 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 361036 [3522725][E](PTable): 95 rpm | 0 | 49 | 79 | 97 | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 361037 [3522746][E](PTable): 100 rpm | -12 | 46 | 77 | 96 | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 361038 [3522779][E](PTable): 105 rpm | -24 | 45 | 75 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 361039 [3522800][E](PTable): Power Table Reset + 361040 [3522825][E](PTable): Success! + 361041 [3522913][E](Custom_C): 01 19 <-targetPosition + 361042 [3523525][E](PTable): Success! + 361043 [3523903][E](Custom_C): 01 19 <-targetPosition + 361044 [3524230][E](PTable): Success! + 361045 [3524893][E](Custom_C): 01 19 <-targetPosition + 361046 [3524932][E](PTable): Success! + 361047 [3524933][E](PTable): Clean Power Table + 361048 [3524934][E](PTable): Averaged Entry: watts=52.000000, cad=74.000000, targetPosition=1080.00000, (3)(2) + 361049 [3524945][E](PTable): Keep old targetPosition: (108.000000) + 361050 [3524946][E](PTable): Right failed at: (106) Target pos: (108.000000) Avg pos: (107) + 361051 [3524957][E](PTable): Current Position moved right was valid! Current position: 108.000000 + 361052 [3524967][E](PTable): Existing entry averaged (3)(4)(106), readings(11) + 361053 [3525297][E](PTable): Top failed at: (104) Target pos: (108.000000) Avg pos: (106) + 361054 [3525299][E](PTable): Current Position moved up was valid! Current position: 108.000000 + 361055 [3525310][E](PTable): Existing entry averaged (0)(2)(104), readings(4) + 361056 [3525434][E](PTable): CAD\W | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 | 540 | 570 | 600 | 630 | 660 | 690 | 720 | 750 | 780 | 810 | 840 | 870 | 900 | 930 | 960 | 990 | 1020 | 1050 | 1080 | 1110 | 1140 | 1170 + 361057 [3525457][E](PTable): 60 rpm | 84 | 86 | 104 | 131 | 132 | 149 | 161 | 165 | 178 | | 205 | 216 | | 220 | 222 | 223 | 224 | 227 | 229 | 231 | 232 | 233 | 235 | 237 | | | | 245 | 247 | 249 | | | | | | | | | | + 361058 [3525489][E](PTable): 65 rpm | 72 | 85 | 100 | 124 | 130 | 139 | 151 | 153 | 162 | 169 | 181 | 193 | | 209 | 212 | 214 | 218 | 221 | 223 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | | | | | | | | | | + 361059 [3525510][E](PTable): 70 rpm | 60 | 79 | 97 | 112 | 120 | 130 | 141 | 147 | 158 | 162 | 171 | 179 | 189 | 197 | 200 | 209 | 213 | 216 | 218 | | | 219 | 220 | | | | | 221 | 223 | 224 | | | | | | | | | | + 361060 [3525543][E](PTable): 75 rpm | 48 | 64 | 93 | 104 | 106 | 117 | 132 | 146 | 153 | 156 | 164 | 173 | 178 | 185 | 188 | 200 | 204 | 207 | 209 | | 210 | 211 | | | 212 | 214 | 215 | 216 | 217 | 220 | | | | | | | | | | + 361061 [3525565][E](PTable): 80 rpm | 36 | 58 | 90 | 102 | 105 | 113 | 128 | 139 | 144 | 150 | 153 | 157 | 168 | 175 | 177 | 191 | 195 | 198 | 200 | 201 | 202 | 203 | 205 | 206 | 208 | 210 | 212 | | | 217 | | | | | | | | | | + 361062 [3525597][E](PTable): 85 rpm | 24 | 55 | 86 | 101 | 103 | 108 | 122 | 131 | 143 | 145 | 149 | 154 | 160 | 169 | 171 | 183 | 186 | 189 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | | 212 | | | | | | | | | | + 361063 [3525619][E](PTable): 90 rpm | 12 | 52 | 83 | 98 | 102 | 106 | 117 | 124 | 137 | 142 | 144 | 149 | 152 | 165 | 169 | 176 | 179 | 183 | | 184 | 186 | | | | 188 | 190 | | 191 | | 207 | | | | | | | | | | + 361064 [3525651][E](PTable): 95 rpm | 0 | 49 | 79 | 97 | 101 | 105 | 114 | 122 | 132 | 141 | 142 | 145 | 150 | 161 | 166 | 171 | 174 | | | 175 | 176 | | | | | 177 | 178 | 179 | 180 | 201 | | | | | | | | | | + 361065 [3525673][E](PTable): 100 rpm | -12 | 46 | 77 | 96 | 99 | 104 | 113 | 118 | 127 | 140 | 141 | 144 | 149 | 156 | 161 | | | | 164 | 166 | 168 | 169 | 194 | | | | | | | 195 | | | | | | | | | | + 361066 [3525705][E](PTable): 105 rpm | -24 | 45 | 75 | 93 | 97 | 103 | 107 | 114 | 122 | 138 | 140 | 143 | 148 | 152 | 156 | 163 | 165 | 167 | | | | 168 | 172 | 177 | 184 | | | | | 188 | | | | | | | | | | + 361067 [3525726][E](PTable): Power Table Reset + 361068 [3525809][E](PTable): Success! + 361069 [3525883][E](Custom_C): 01 2a <-hMin + 361070 [3525928][E](Custom_C): 01 19 <-targetPosition + 361071 [3525973][E](Custom_C): 01 2b <-hMax + 361072 [3526018][E](Custom_C): 01 25 <-Firmware Version + 361073 [3526307][E](FTMS_SERVER): 11 00 00 05 00 28 33 -> Sim Mode Incline 0.050000 + 361074 [3526513][E](PTable): Success! + 361075 [3526918][E](Custom_C): 01 19 <-targetPosition + 361076 [3527216][E](PTable): Success! + 361077 [3527343][E](FTMS_SERVER): 11 00 00 16 00 28 33 -> Sim Mode Incline 0.220000 + 361078 [3527897][E](Custom_C): 01 19 <-targetPosition + 361079 [3528362][E](FTMS_SERVER): 11 00 00 2b 00 28 33 -> Sim Mode Incline 0.430000 + 361080 [3528887][E](Custom_C): 01 19 <-targetPosition + 361081 [3529375][E](FTMS_SERVER): 11 00 00 43 00 28 33 -> Sim Mode Incline 0.670000 + 361082 [3529888][E](Custom_C): 01 19 <-targetPosition + 361083 [3530388][E](FTMS_SERVER): 11 00 00 5b 00 28 33 -> Sim Mode Incline 0.910000 + 361084 [3530937][E](Custom_C): 01 27 00 <-Power Tab Data + 361085 [3530968][E](Custom_C): 01 2a <-hMin + 361086 [3531047][E](Custom_C): 01 19 <-targetPosition + 361087 [3531115][E](Custom_C): 01 27 01 <-Power Tab Data + 361088 [3531148][E](Custom_C): 01 2b <-hMax + 361089 [3531240][E](Custom_C): 01 27 02 <-Power Tab Data + 361090 [3531330][E](Custom_C): 01 27 03 <-Power Tab Data + 361091 [3531385][E](Custom_C): 01 27 04 <-Power Tab Data + 361092 [3531407][E](FTMS_SERVER): 11 00 00 79 00 28 33 -> Sim Mode Incline 1.210000 + 361093 [3531432][E](Custom_C): 01 27 05 <-Power Tab Data + 361094 [3531566][E](Custom_C): 01 27 06 <-Power Tab Data + 361095 [3531634][E](Custom_C): 01 27 07 <-Power Tab Data + 361096 [3531690][E](Custom_C): 01 27 08 <-Power Tab Data + 361097 [3531780][E](Custom_C): 01 27 09 <-Power Tab Data + 361098 [3531891][E](Custom_C): 01 19 <-targetPosition + 361099 [3532466][E](FTMS_SERVER): 11 00 00 9d 00 28 33 -> Sim Mode Incline 1.570000 + 361100 [3532881][E](Custom_C): 01 19 <-targetPosition + 361101 [3533481][E](FTMS_SERVER): 11 00 00 aa 00 28 33 -> Sim Mode Incline 1.700000 + 361102 [3533893][E](Custom_C): 01 19 <-targetPosition + 361103 [3534502][E](FTMS_SERVER): 11 00 00 a5 00 28 33 -> Sim Mode Incline 1.650000 + 361104 [3534883][E](Custom_C): 01 19 <-targetPosition + 361105 [3535514][E](FTMS_SERVER): 11 00 00 a2 00 28 33 -> Sim Mode Incline 1.620000 + 361106 [3535906][E](Custom_C): 01 2a <-hMin + 361107 [3535940][E](Custom_C): 01 19 <-targetPosition + 361108 [3536009][E](Custom_C): 01 2b <-hMax + 361109 [3536540][E](FTMS_SERVER): 11 00 00 a0 00 28 33 -> Sim Mode Incline 1.600000 + 361110 [3536897][E](Custom_C): 01 19 <-targetPosition + 361111 [3537887][E](Custom_C): 01 19 <-targetPosition + 361112 [3538569][E](FTMS_SERVER): 11 00 00 9f 00 28 33 -> Sim Mode Incline 1.590000 + 361113 [3538888][E](Custom_C): 01 19 <-targetPosition + 361114 [3539901][E](Custom_C): 01 19 <-targetPosition + 361115 [3540891][E](Custom_C): 01 2a <-hMin + 361116 [3540959][E](Custom_C): 01 19 <-targetPosition + 361117 [3541003][E](Custom_C): 01 2b <-hMax + 361118 [3541903][E](Custom_C): 01 19 <-targetPosition + 361119 [3542263][E](Custom_C): 01 25 <-Firmware Version + 361120 [3542630][E](FTMS_SERVER): 11 00 00 9d 00 28 33 -> Sim Mode Incline 1.570000 + 361121 [3542893][E](Custom_C): 01 19 <-targetPosition \ No newline at end of file diff --git a/test/data_helpers.cpp b/test/data_helpers.cpp index ac013153..27d2c9b2 100644 --- a/test/data_helpers.cpp +++ b/test/data_helpers.cpp @@ -13,6 +13,9 @@ #include #include #include +#include // For _findfirst, _findnext, _findclose +#include // For _mkdir, _rmdir +#include // For std::sort // Helper function to load CSV data static void loadCSVToPTData(const std::string& filePath, PTData& ptData) { @@ -51,16 +54,42 @@ static void loadCSVToPTData(const std::string& filePath, PTData& ptData) { } // Function to create a heatmap visualization of the power table data -static void createPowerTableHeatmap(const std::string& inputFilePath, const std::string& outputFilePath) { +static void createPowerTableHeatmap(const std::string& inputFilePath, const std::string& outputFilePath, bool skip = false, bool addTimeSlider = false) { + if (skip) return; PTData ptData; - // Load the power table data loadCSVToPTData(inputFilePath, ptData); - + + // If addTimeSlider is true, gather all .ptab files in ridedata and prepare their data + std::vector ptabFiles; + if (addTimeSlider) { + // Windows directory scan for .ptab files + struct _finddata_t fileinfo; + std::string dirPath = "test/output/ridedata/"; + std::string pattern = dirPath + "*.ptab"; + intptr_t hFile = _findfirst(pattern.c_str(), &fileinfo); + if (hFile != -1) { + do { + ptabFiles.push_back(dirPath + fileinfo.name); + } while (_findnext(hFile, &fileinfo) == 0); + _findclose(hFile); + } + // Sort files by timestamp in filename (assuming numeric) + std::sort(ptabFiles.begin(), ptabFiles.end(), [](const std::string& a, const std::string& b) { + // Extract numeric part from filename + auto getNum = [](const std::string& path) { + size_t lastSlash = path.find_last_of("/\\"); + size_t dot = path.find_last_of('.'); + std::string num = path.substr(lastSlash + 1, dot - lastSlash - 1); + return std::stoll(num); + }; + return getNum(a) < getNum(b); + }); + } + // If addTimeSlider is true, we will later gather all .ptab files in ridedata and embed their data in the HTML. // Find min and max values for color mapping int16_t minValue = INT16_MAX; int16_t maxValue = INT16_MIN; - for (int row = 0; row < POWERTABLE_CAD_SIZE; row++) { for (int col = 0; col < POWERTABLE_WATT_SIZE; col++) { int16_t val = ptData.tableRow[row].tableEntry[col].targetPosition; @@ -70,14 +99,14 @@ static void createPowerTableHeatmap(const std::string& inputFilePath, const std: } } } - + // Create an HTML file with a colored table std::ofstream htmlFile(outputFilePath); if (!htmlFile.is_open()) { printf("Failed to create output file: %s\n", outputFilePath.c_str()); return; } - + // HTML header htmlFile << "\n"; htmlFile << "\n\n"; @@ -91,11 +120,56 @@ static void createPowerTableHeatmap(const std::string& inputFilePath, const std: htmlFile << " .legend-labels { display: flex; flex-direction: row; justify-content: space-between; width: 300px; }\n"; htmlFile << " .empty-cell { background-color: white; }\n"; htmlFile << " .header-cell { font-weight: bold; background-color: #f2f2f2; }\n"; + htmlFile << " #timeSliderContainer { width: 80%; margin: 30px auto 0 auto; display: flex; flex-direction: column; align-items: center; }\n"; + htmlFile << " #timeSlider { width: 100%; }\n"; htmlFile << "\n"; htmlFile << "\n\n"; - + // Table title htmlFile << "

Power Table Heatmap

\n"; + + // If addTimeSlider, embed all .ptab data as a JS array + if (addTimeSlider && !ptabFiles.empty()) { + htmlFile << "\n"; + } // Function to map value to color (blue to red gradient) auto valueToColor = [minValue, maxValue](int16_t value) -> std::string { @@ -116,44 +190,48 @@ static void createPowerTableHeatmap(const std::string& inputFilePath, const std: return std::string(colorHex); }; - // Begin table - htmlFile << "\n"; - - // Table header row with watt values - htmlFile << " \n \n"; // Corner cell - for (int col = 0; col < POWERTABLE_WATT_SIZE; col++) { - htmlFile << " \n"; - } - htmlFile << " \n"; - - // Table data - for (int row = 0; row < POWERTABLE_CAD_SIZE; row++) { - htmlFile << " \n"; - // Row header with cadence - htmlFile << " \n"; - - // Data cells + + if (addTimeSlider && !ptabFiles.empty()) { + // Add slider UI + htmlFile << "
\n"; + htmlFile << " \n"; + htmlFile << " \n"; + htmlFile << "
\n"; + // Add table container for dynamic update + htmlFile << "
\n"; + } else { + // Static table as before + htmlFile << "
CAD/WATTS" << col * POWERTABLE_WATT_INCREMENT << "W
" << (MINIMUM_TABLE_CAD + row * POWERTABLE_CAD_INCREMENT) << "RPM
\n"; + // Table header row with watt values + htmlFile << " \n \n"; // Corner cell for (int col = 0; col < POWERTABLE_WATT_SIZE; col++) { - int16_t value = ptData.tableRow[row].tableEntry[col].targetPosition; - std::string cellColor = valueToColor(value); - - htmlFile << " \n"; + htmlFile << " \n"; } - htmlFile << " \n"; + // Table data + for (int row = 0; row < POWERTABLE_CAD_SIZE; row++) { + htmlFile << " \n"; + // Row header with cadence + htmlFile << " \n"; + // Data cells + for (int col = 0; col < POWERTABLE_WATT_SIZE; col++) { + int16_t value = ptData.tableRow[row].tableEntry[col].targetPosition; + std::string cellColor = valueToColor(value); + htmlFile << " \n"; + } + htmlFile << " \n"; + } + htmlFile << "
CAD/WATTS"; - - if (value != INT16_MIN) { - htmlFile << value; - } - htmlFile << "" << col * POWERTABLE_WATT_INCREMENT << "W
" << (MINIMUM_TABLE_CAD + row * POWERTABLE_CAD_INCREMENT) << "RPM"; + if (value != INT16_MIN) { + htmlFile << value; + } + htmlFile << "
\n"; } - htmlFile << "\n"; - // Add horizontal color legend htmlFile << "
\n"; htmlFile << "
\n"; @@ -164,6 +242,7 @@ static void createPowerTableHeatmap(const std::string& inputFilePath, const std: htmlFile << "
\n"; htmlFile << "
\n"; + // Add Chart.js library htmlFile << "\n"; @@ -182,95 +261,114 @@ static void createPowerTableHeatmap(const std::string& inputFilePath, const std: htmlFile << "\n"; @@ -282,7 +380,7 @@ static void createPowerTableHeatmap(const std::string& inputFilePath, const std: } // Helper function to save PTData to CSV file -static void savePTDataToCSV(const PTData& ptData, const std::string& filePath) { +static void savePTDataToCSV(const PTData& ptData, const std::string& filePath, bool skipHeatmap = false) { std::ofstream file(filePath); if (!file.is_open()) { printf("Failed to create file: %s\n", filePath.c_str()); @@ -315,16 +413,17 @@ static void savePTDataToCSV(const PTData& ptData, const std::string& filePath) { // Generate heatmap visualization in the same folder // Create the heatmap output path by replacing .ptab extension with .html - std::string heatmapPath = filePath; - size_t extPos = heatmapPath.find_last_of('.'); - if (extPos != std::string::npos) { - heatmapPath.replace(extPos, heatmapPath.length() - extPos, ".html"); - } else { - heatmapPath += ".html"; + if (!skipHeatmap) { + std::string heatmapPath = filePath; + size_t extPos = heatmapPath.find_last_of('.'); + if (extPos != std::string::npos) { + heatmapPath.replace(extPos, heatmapPath.length() - extPos, ".html"); + } else { + heatmapPath += ".html"; + } + // Create the heatmap using the same data + createPowerTableHeatmap(filePath, heatmapPath); + printf("Heatmap visualization automatically created at: %s\n", heatmapPath.c_str()); } - - // Create the heatmap using the same data - createPowerTableHeatmap(filePath, heatmapPath); - printf("Heatmap visualization automatically created at: %s\n", heatmapPath.c_str()); } diff --git a/test/test_table_fill.cpp b/test/test_table_fill.cpp index d5a3d8e2..8aa06da0 100644 --- a/test/test_table_fill.cpp +++ b/test/test_table_fill.cpp @@ -1,9 +1,3 @@ -/* - * Copyright (C) 2020 Anthony Doud & Joel Baranick - * All rights reserved - * - * SPDX-License-Identifier: GPL-2.0-only - */ #include #include "test.h" @@ -13,53 +7,98 @@ #include #include #include +#include +#include // for _mkdir, _rmdir +#include // for _findfirst, _findnext, _findclose, _unlink #include "data_helpers.cpp" +// Helper to clean and recreate a directory + +// Helper to clean and recreate a directory (Windows version) +static void cleanAndCreateDir(const std::string& dirPath) { + // Remove all files in the directory + struct _finddata_t fileinfo; + std::string pattern = dirPath + "*"; + intptr_t hFile = _findfirst(pattern.c_str(), &fileinfo); + if (hFile != -1) { + do { + if (!(fileinfo.attrib & _A_SUBDIR)) { + std::string filepath = dirPath + fileinfo.name; + _unlink(filepath.c_str()); + } + } while (_findnext(hFile, &fileinfo) == 0); + _findclose(hFile); + } + // Remove the directory itself if it exists + _rmdir(dirPath.c_str()); + // Recreate the directory + _mkdir(dirPath.c_str()); +} + void TestTableFill::test_fill_incomplete_table(void) { - std::ofstream logFile("test/output/test_table_fill.txt", std::ios::trunc); - logFile << "Starting incomplete table fill test\n"; + std::ofstream logFile("test/output/test_table_fill.txt", std::ios::trunc); + logFile << "Starting Ride_Log replay test\n"; + + // Clean and recreate output directory + const std::string outputDir = "test/output/ridedata/"; + cleanAndCreateDir(outputDir); + + // Open Ride_Log.txt + std::ifstream rideLog("test/data/Ride_Log.txt"); + TEST_ASSERT_TRUE_MESSAGE(rideLog.good(), "Ride_Log.txt could not be opened"); + + // Prepare regex for Averaged Entry lines + std::regex entryRegex(R"(\[(\d+)\]\[E\]\(PTable\): Averaged Entry: watts=([\d\.\-]+), cad=([\d\.\-]+), targetPosition=([\d\.\-]+), \((\d+)\)\((\d+)\))"); + std::string line; + PTData ptData; // Start with an empty table + PTHelpers helpers; + int entryCount = 0; - // Create a power table - PTData ptData; + while (std::getline(rideLog, line)) { + std::smatch match; + if (std::regex_search(line, match, entryRegex)) { + // Extract values + std::string timestamp = match[1]; + float watts = std::stof(match[2]); + float cad = std::stof(match[3]); + float targetPosition = std::stof(match[4]); + int cadIndex = std::stoi(match[5]); + int wattIndex = std::stoi(match[6]); - // Load the incomplete power table data - const std::string inputFilePath = "test/data/10x5-26-25.ptab"; - loadCSVToPTData(inputFilePath, ptData); - logFile << "Loaded incomplete power table from: " << inputFilePath << "\n"; + // Log extraction + logFile << "Entry " << entryCount << ": ts=" << timestamp << ", watts=" << watts << ", cad=" << cad << ", targetPosition=" << targetPosition << ", cadIndex=" << cadIndex << ", wattIndex=" << wattIndex << "\n"; - // Create helpers object - PTHelpers helpers; + // Call enterData + ptIndex idx; + idx.cadIndex = cadIndex; + idx.wattIndex = wattIndex; + helpers.enterData(ptData, idx, static_cast(targetPosition)); - // Count initial data points - int initialPoints = helpers.getNumEntries(ptData); - logFile << "Initial data points: " << initialPoints << "\n"; - int previousFilledPoints = 0; - int filledPoints = 1; - //Fill the incomplete table - // while (previousFilledPoints < filledPoints) { - // previousFilledPoints = filledPoints; - // helpers.linearFill(ptData); - // logFile << "Applied splineFill to the table\n"; + // Save PTData to .ptab file named with timestamp + std::string outFile = outputDir + timestamp + ".ptab"; + savePTDataToCSV(ptData, outFile, true); // true = skipHeatmap - // // Count filled data points - // filledPoints = helpers.getNumEntries(ptData); - // logFile << "Filled data points: " << filledPoints << "\n"; - // logFile << "Added " << (filledPoints - initialPoints) << " points\n"; - // } + entryCount++; + } + } - // loop through the table and check for INT16_MIN values - for(int i=1; i<100; i++){ - helpers.completePowerTable(ptData);} - // Save the filled power table - const std::string outputFilePath = "test/output/power_table_filled.ptab"; - savePTDataToCSV(ptData, outputFilePath); - logFile << "Saved filled power table to: " << outputFilePath << "\n"; - // Verify the file was created - std::ifstream checkFile(outputFilePath); - TEST_ASSERT_TRUE_MESSAGE(checkFile.good(), "Output file should be created successfully"); - checkFile.close(); + rideLog.close(); + createPowerTableHeatmap("test/output/ridedata/3028648.ptab", "test/output/heatmap_slider.html", false, true); + logFile << "Processed " << entryCount << " Averaged Entry lines.\n"; + logFile.close(); - logFile << "Test completed successfully\n"; - logFile.close(); + // Check that at least one .ptab file was created + // Count .ptab files in outputDir (Windows version) + int ptabCount = 0; + struct _finddata_t fileinfo; + std::string pattern = outputDir + "*.ptab"; + intptr_t hFile = _findfirst(pattern.c_str(), &fileinfo); + if (hFile != -1) { + do { + ptabCount++; + } while (_findnext(hFile, &fileinfo) == 0); + _findclose(hFile); + } + TEST_ASSERT_TRUE_MESSAGE(ptabCount > 0, "No .ptab files were created in output directory"); } diff --git a/test/test_write_PowerTable.cpp b/test/test_write_PowerTable.cpp index 15bbccb0..625d2d7e 100644 --- a/test/test_write_PowerTable.cpp +++ b/test/test_write_PowerTable.cpp @@ -29,7 +29,7 @@ void TestWritePowerTable::test_save_and_load(void) { // Save the power table to the output file const std::string outputFilePath = "test/output/power_table.ptab"; - savePTDataToCSV(ptData, outputFilePath); + savePTDataToCSV(ptData, outputFilePath, false); logFile << "Saved power table to: " << outputFilePath << "\n"; // Verify the file was created From b25fd1df1aff52fd4b00b180e4f2d820e691ee89 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sun, 13 Jul 2025 15:47:49 -0500 Subject: [PATCH 280/451] code cleanup --- test/data_helpers.cpp | 230 ++++++++++++++++++++++++------------------ 1 file changed, 132 insertions(+), 98 deletions(-) diff --git a/test/data_helpers.cpp b/test/data_helpers.cpp index 27d2c9b2..b54d474c 100644 --- a/test/data_helpers.cpp +++ b/test/data_helpers.cpp @@ -197,39 +197,29 @@ static void createPowerTableHeatmap(const std::string& inputFilePath, const std: htmlFile << " \n"; htmlFile << " \n"; htmlFile << "
\n"; - // Add table container for dynamic update - htmlFile << "
\n"; + // Add dynamic table container above the chart + htmlFile << "
\n"; } else { - // Static table as before - htmlFile << "\n"; - // Table header row with watt values - htmlFile << " \n \n"; // Corner cell - for (int col = 0; col < POWERTABLE_WATT_SIZE; col++) { - htmlFile << " \n"; - } - htmlFile << " \n"; - // Table data + // Static (no slider) case: use the same JS-based rendering as the slider case, but with a single data array and no slider + htmlFile << "
\n"; + htmlFile << "\n"; } // Add horizontal color legend @@ -261,10 +251,39 @@ static void createPowerTableHeatmap(const std::string& inputFilePath, const std: htmlFile << "\n"; // HTML footer From 808c554915373116792b12ed360ac9ed63a560ee Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sun, 4 Jan 2026 09:03:00 -0600 Subject: [PATCH 447/451] Load power table if not yet loaded during session --- src/ERG_Mode.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index 8b261d1f..ba91b702 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -50,6 +50,10 @@ void ErgMode::runERG() { powerTable->saveFlag = false; } } + // Load power table if not yet loaded this session + if(!powerTable->_hasBeenLoadedThisSession) { + powerTable->_manageSaveState(); + } if (rtConfig->cad.getValue()) { hasConnectedPowerMeter = spinBLEClient.connectedPM; From 9a681cec932e10916add300e9e6a304965e7bfcd Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Sun, 4 Jan 2026 19:42:46 -0600 Subject: [PATCH 448/451] working great. needs cleanup. --- include/PowerTable_Helpers.h | 3 +- include/Power_Table.h | 1 - src/Main.cpp | 30 ++-- src/PowerTable_Helpers.cpp | 332 ++++++++++++++++++++++------------- src/Power_Table.cpp | 7 +- test/test_table_fill.cpp | 2 +- 6 files changed, 233 insertions(+), 142 deletions(-) diff --git a/include/PowerTable_Helpers.h b/include/PowerTable_Helpers.h index ff1cb1fb..c6686c9a 100644 --- a/include/PowerTable_Helpers.h +++ b/include/PowerTable_Helpers.h @@ -12,8 +12,6 @@ #define PTDATA_LOG_TAG "PTData" #define RETURN_ERROR INT32_MIN -#define FREE_HEAP_FOR_COMPLEX_MATH 30000 -#define COMPUTATION_TIMEOUT_MS 25 class PowerEntry { public: @@ -116,4 +114,5 @@ class PTHelpers { bool fillAllCadenceLines(PTData& ptData); std::pair, std::vector> getRow(int row, PTData& ptData); std::pair, std::vector> getColumn(int column, PTData& ptData); + void safeSmooth(PTData& ptData); }; \ No newline at end of file diff --git a/include/Power_Table.h b/include/Power_Table.h index 569f940e..c497a8b2 100644 --- a/include/Power_Table.h +++ b/include/Power_Table.h @@ -17,7 +17,6 @@ class PowerTable { public: bool saveFlag = false; bool _hasBeenLoadedThisSession = false; - bool fillTableFlag = false; PTData ptData; PTHelpers ptHelpers; diff --git a/src/Main.cpp b/src/Main.cpp index 8a9efdef..28a9eed6 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -322,8 +322,8 @@ void SS2K::maintenanceLoop(void* pvParameters) { } #endif // DEBUG_STACK // Log userParameters - SS2K_LOG(MAIN_LOG_TAG, "PM Con %d, CAD con %d, HRM Con %d, W %d, Cad %d, HR %d, Gear %d, Res %d, Current Pos %d, Target Pos %d", spinBLEClient.connectedPM, spinBLEClient.connectedCD, - spinBLEClient.connectedHRM, rtConfig->watts.getValue(), rtConfig->cad.getValue(), rtConfig->hr.getValue(), rtConfig->getShifterPosition(), + SS2K_LOG(MAIN_LOG_TAG, "PM Con %d, CAD con %d, HRM Con %d, W %d, Cad %d, HR %d, Gear %d, Res %d, Current Pos %d, Target Pos %d", spinBLEClient.connectedPM, + spinBLEClient.connectedCD, spinBLEClient.connectedHRM, rtConfig->watts.getValue(), rtConfig->cad.getValue(), rtConfig->hr.getValue(), rtConfig->getShifterPosition(), rtConfig->resistance.getValue(), ss2k->getCurrentPosition(), ss2k->getTargetPosition()); intervalTimer2 = millis(); @@ -377,8 +377,8 @@ void SS2K::FTMSModeShiftModifier() { default: // Sim Mode { - SS2K_LOG(MAIN_LOG_TAG, "Shift %+d pos %d tgt %d min %d max %d r_min %d r_max %d", shiftDelta, rtConfig->getShifterPosition(), ss2k->getTargetPosition(), rtConfig->getMinStep(), - rtConfig->getMaxStep(), rtConfig->getMinResistance(), rtConfig->getMaxResistance()); + SS2K_LOG(MAIN_LOG_TAG, "Shift %+d pos %d tgt %d min %d max %d r_min %d r_max %d", shiftDelta, rtConfig->getShifterPosition(), ss2k->getTargetPosition(), + rtConfig->getMinStep(), rtConfig->getMaxStep(), rtConfig->getMinResistance(), rtConfig->getMaxResistance()); // Block Shifts further out of bounds if (((ss2k->targetPosition + shiftDelta * userConfig->getShiftStep()) < rtConfig->getMinStep()) && (shiftDelta < 0)) { SS2K_LOG(MAIN_LOG_TAG, "Shift Blocked by stepper limits."); @@ -745,20 +745,12 @@ void SS2K::_findFTMSHome(bool bothDirections) { i++; } - bool reachedTarget = (rtConfig->resistance.getValue() == targetResistance); + bool reachedTarget = (rtConfig->resistance.getValue() == targetResistance); int32_t travelDelta = abs(ss2k->getCurrentPosition() - lastPosition); bool iterExceeded = (i >= iMax); bool travelSatisfied = (travelDelta >= minTravel); - SS2K_LOG(MAIN_LOG_TAG, - "FTMS Homing sweep exit: target=%d current=%d reached=%s iter=%d/%d travelΔ=%d minTravel=%d travelMet=%s", - targetResistance, - rtConfig->resistance.getValue(), - reachedTarget ? "true" : "false", - i, - iMax, - travelDelta, - minTravel, - travelSatisfied ? "true" : "false"); + SS2K_LOG(MAIN_LOG_TAG, "FTMS Homing sweep exit: target=%d current=%d reached=%s iter=%d/%d travelΔ=%d minTravel=%d travelMet=%s", targetResistance, + rtConfig->resistance.getValue(), reachedTarget ? "true" : "false", i, iMax, travelDelta, minTravel, travelSatisfied ? "true" : "false"); }; ss2k->updateStepperSpeed(1500); // Use a slow-medium speed for homing @@ -796,7 +788,13 @@ void SS2K::_findFTMSHome(bool bothDirections) { void SS2K::goHome(bool bothDirections) { SS2K_LOG(MAIN_LOG_TAG, "Starting homing procedure..."); - if (bothDirections) fitnessMachineService.spinDown(FitnessMachineStatus::SpinDown_SpinDownRequested); + if (bothDirections) { + fitnessMachineService.spinDown(FitnessMachineStatus::SpinDown_SpinDownRequested); + if (!userConfig->getPTab4Pwr()) { + // clean slate for homing + powerTable->reset(); + } + } // if we're using real resistance from a FTMS bike, find those values for the reported min and max resistance instead of using hard stops. if (!rtConfig->resistance.getSimulate() && userConfig->getConnectedPowerMeter() != NONE && rtConfig->resistance.getMax() > 0) { diff --git a/src/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp index 534ca5d3..359948c3 100644 --- a/src/PowerTable_Helpers.cpp +++ b/src/PowerTable_Helpers.cpp @@ -86,7 +86,7 @@ bool ResistanceModel::solveMatrix(double A[6][6], double B[6], int n) { } void ResistanceModel::fit(const PTData& data) { - // long int timer = millis(); + long int timer = millis(); isValid = false; // 1. Collect Valid Points & Find Bounds @@ -104,7 +104,7 @@ void ResistanceModel::fit(const PTData& data) { for (int r = 0; r < POWERTABLE_CAD_SIZE; r++) { for (int c = 0; c < POWERTABLE_WATT_SIZE; c++) { int16_t val = data.tableRow[r].tableEntry[c].targetPosition; - if (val == INT16_MIN) continue; + if (val == INT16_MIN || data.tableRow[r].tableEntry[c].readings < 2) continue; double w = 0 + (c * POWERTABLE_WATT_INCREMENT); double rpm = MINIMUM_TABLE_CAD + (r * POWERTABLE_CAD_INCREMENT); @@ -126,8 +126,8 @@ void ResistanceModel::fit(const PTData& data) { if (std::fabs(maxR - minR) < 1.0) maxR += 1.0; // 2. Decide Model Complexity - // Require 9 points for the complex curve to ensure stability - isQuadratic = (N >= 9) ? true : false; + // Require 10 points for the complex curve to ensure stability + isQuadratic = (N >= 10) ? true : false; int numCoeffs = isQuadratic ? 6 : 3; // 3. Build Matrices (Stack Allocated) @@ -160,12 +160,12 @@ void ResistanceModel::fit(const PTData& data) { // 4. Solve isValid = solveMatrix(A, B, numCoeffs); - // SS2K_LOG(PTDATA_LOG_TAG, "Fit Valid: %d, N: %d, Quad: %d", isValid, N, isQuadratic); + SS2K_LOG(PTDATA_LOG_TAG, "Fit Valid: %d, N: %d, Quad: %d, Time: %ld ms", isValid, N, isQuadratic, millis() - timer); } int16_t ResistanceModel::predict(double watts, double rpm) { if (!isValid) return INT16_MIN; - //SS2K_LOG(PTDATA_LOG_TAG, "Predicting for Watts: %.2f, RPM: %.2f", watts, rpm); + // SS2K_LOG(PTDATA_LOG_TAG, "Predicting for Watts: %.2f, RPM: %.2f", watts, rpm); // Normalize inputs using the bounds found during training double x = normW(watts); @@ -278,6 +278,118 @@ int ResistanceModel::predictWatts(int32_t resistance, float cadence) { } ///////////////////////////////////////////////END of testing Helpers/////////////////////////////////////////////// + +/** + * @brief Enters a new data point and then enforces monotonicity on the whole table. + * * This function first calculates the running average for the given data point. + * Then, it calls the PAVA helper functions to ensure the entire table remains + * monotonically increasing across both watts and cadence. + * * @param ptData The main power table data structure. + * @param index The watt and cadence index for the new data point. + * @param pos The measured targetPosition for this data point. + */ +void PTHelpers::enterData(PTData& ptData, ptIndex index, int pos) { + // Reference to the specific table entry for cleaner code + TableEntry& entry = ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex]; + + int left = INT16_MIN; + int down = INT16_MIN; + bool moveTable = false; + clean(ptData); + + // Get the topmost value in the column + + if (entry.readings == 0) { // if first reading in this entry + entry.readings = 1; // Initialize readings to 1 (total will be 2 after this loop) 1 alone is used for automatic computations. + SS2K_LOG(PTDATA_LOG_TAG, "New entry recorded (%d)(%d)(%d)", index.cadIndex, index.wattIndex, pos); + } else { // Average and update the readings. + // Use floating point for accuracy in averaging + float current_total_pos = (float)entry.targetPosition * entry.readings; + float new_avg_pos = (pos + current_total_pos) / (entry.readings + 1.0f); + pos = (int16_t)new_avg_pos; + + SS2K_LOG(PTDATA_LOG_TAG, "Existing entry averaged (%d)(%d)(%d), readings(%d)", index.cadIndex, index.wattIndex, pos, entry.readings); + } + + // Get the value to the left of the new entry + for (int i = index.wattIndex - 1; i > 0; i--) { + if (ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition > pos) { + left = ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition; + SS2K_LOG(PTDATA_LOG_TAG, "Greater Left Found %d, %d, tp%d", index.cadIndex, i, ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition); + ptData.tableRow[index.cadIndex].tableEntry[i].readings--; + moveTable = true; + break; + } + } + + // get the value below the new entry + for (int j = index.cadIndex + 1; j < POWERTABLE_CAD_SIZE - 1; j++) { + if (ptData.tableRow[j].tableEntry[index.wattIndex].targetPosition > pos) { + SS2K_LOG(PTDATA_LOG_TAG, "Greater Down Found %d, %d, tp%d", j, index.wattIndex, ptData.tableRow[j].tableEntry[index.wattIndex].targetPosition); + down = ptData.tableRow[j].tableEntry[index.wattIndex].targetPosition; + ptData.tableRow[j].tableEntry[index.wattIndex].readings--; + moveTable = true; + break; + } + } + + // get the value to the right of the entry + for (int i = index.wattIndex + 1; i < POWERTABLE_WATT_SIZE - 1; i++) { + if (ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition != INT16_MIN && ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition < pos) { + SS2K_LOG(PTDATA_LOG_TAG, "Lower Right Found %d, %d, tp%d", index.cadIndex, i, ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition); + ptData.tableRow[index.cadIndex].tableEntry[i].readings--; + moveTable = true; + break; + } + } + + // get the value above the entry + for (int j = index.cadIndex - 1; j > 0; j--) { + if (ptData.tableRow[j].tableEntry[index.wattIndex].targetPosition != INT16_MIN && ptData.tableRow[j].tableEntry[index.wattIndex].targetPosition < pos) { + SS2K_LOG(PTDATA_LOG_TAG, "Lower Up Found %d, %d, tp%d", j, index.wattIndex, ptData.tableRow[j].tableEntry[index.wattIndex].targetPosition); + ptData.tableRow[j].tableEntry[index.wattIndex].readings--; + moveTable = true; + break; + } + } + + if (moveTable) { + // clean(ptData); + return; + } + + entry.targetPosition = pos; // Update the target position with the new average + // Increment readings, capping at the max value. + if (entry.readings < MAX_NEIGHBOR_WEIGHT && !moveTable) { + entry.readings++; + } + + // // After updating a point, re-process the entire table to enforce global monotonicity. + this->fillGaps(ptData); + // for (int i = 0; i < 10; i++) { // Run the PAVA functions multiple times to ensure convergence + bool caddone = false; + bool wattdone = false; + int loop = 0; + while ((!caddone || !wattdone) && loop < 2) { + loop++; + if (!caddone) { + caddone = fillAllCadenceLines(ptData); + } + if (!wattdone) { + wattdone = fillAllWattColumns(ptData); + } + SS2K_LOG(PTDATA_LOG_TAG, "PAVA iteration done, still converging: cad %d, watt %d, Loop %d", caddone, wattdone, loop); + } + // Remove zig-zags in data. + //this->safeSmooth(ptData); + // After updating a point, re-process the entire table to enforce global monotonicity. + resistanceModel.fit(ptData); + + if (resistanceModel.getIsValid()) { + this->fill(ptData); + } +} + // Calculate index in the table for the given watts and cadence ptIndex PTHelpers::calculateIndex(int watts, int cad) { ptIndex index; @@ -382,12 +494,12 @@ int PTHelpers::lookupWatts(int cad, int32_t targetPosition, PTData& ptData) { void PTHelpers::fill(PTData& ptData) { for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - if (ptData.tableRow[i].tableEntry[j].targetPosition == INT16_MIN) { + if (ptData.tableRow[i].tableEntry[j].readings <= 1) { int cadence = MINIMUM_TABLE_CAD + (i * POWERTABLE_CAD_INCREMENT); int watts = j * POWERTABLE_WATT_INCREMENT; int16_t predictedPosition = resistanceModel.predict(watts, cadence); - ptData.tableRow[i].tableEntry[j].targetPosition = predictedPosition; - //ptData.tableRow[i].tableEntry[j].readings = 1; // Mark as inferred with low confidence + ptData.tableRow[i].tableEntry[j].targetPosition = ptData.tableRow[i].tableEntry[j].targetPosition == INT16_MIN ? predictedPosition : (predictedPosition + ptData.tableRow[i].tableEntry[j].targetPosition) / 2; // Blend predicted with existing low-confidence value + ptData.tableRow[i].tableEntry[j].readings = 1; // Mark as inferred with low confidence } } } @@ -525,123 +637,14 @@ bool PTHelpers::fillAllCadenceLines(PTData& ptData) { return converged; } -/** - * @brief Enters a new data point and then enforces monotonicity on the whole table. - * * This function first calculates the running average for the given data point. - * Then, it calls the PAVA helper functions to ensure the entire table remains - * monotonically increasing across both watts and cadence. - * * @param ptData The main power table data structure. - * @param index The watt and cadence index for the new data point. - * @param pos The measured targetPosition for this data point. - */ -void PTHelpers::enterData(PTData& ptData, ptIndex index, int pos) { - // Reference to the specific table entry for cleaner code - TableEntry& entry = ptData.tableRow[index.cadIndex].tableEntry[index.wattIndex]; - - int left = INT16_MIN; - int down = INT16_MIN; - bool moveTable = false; - clean(ptData); - - // Get the topmost value in the column - - if (entry.readings == 0) { // if first reading in this entry - - SS2K_LOG(PTDATA_LOG_TAG, "New entry recorded (%d)(%d)(%d)", index.cadIndex, index.wattIndex, pos); - } else { // Average and update the readings. - // Use floating point for accuracy in averaging - float current_total_pos = (float)entry.targetPosition * entry.readings; - float new_avg_pos = (pos + current_total_pos) / (entry.readings + 1.0f); - pos = (int16_t)new_avg_pos; - - SS2K_LOG(PTDATA_LOG_TAG, "Existing entry averaged (%d)(%d)(%d), readings(%d)", index.cadIndex, index.wattIndex, pos, entry.readings); - } - - // Get the value to the left of the new entry - for (int i = index.wattIndex - 1; i > 0; i--) { - if (ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition > pos) { - left = ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition; - SS2K_LOG(PTDATA_LOG_TAG, "Greater Left Found %d, %d, tp%d", index.cadIndex, i, ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition); - ptData.tableRow[index.cadIndex].tableEntry[i].readings--; - moveTable = true; - break; - } - } - - // get the value below the new entry - for (int j = index.cadIndex + 1; j < POWERTABLE_CAD_SIZE - 1; j++) { - if (ptData.tableRow[j].tableEntry[index.wattIndex].targetPosition > pos) { - SS2K_LOG(PTDATA_LOG_TAG, "Greater Down Found %d, %d, tp%d", j, index.wattIndex, ptData.tableRow[j].tableEntry[index.wattIndex].targetPosition); - down = ptData.tableRow[j].tableEntry[index.wattIndex].targetPosition; - ptData.tableRow[j].tableEntry[index.wattIndex].readings--; - moveTable = true; - break; - } - } - - // get the value to the right of the entry - for (int i = index.wattIndex + 1; i < POWERTABLE_WATT_SIZE - 1; i++) { - if (ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition != INT16_MIN && ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition < pos) { - SS2K_LOG(PTDATA_LOG_TAG, "Lower Right Found %d, %d, tp%d", index.cadIndex, i, ptData.tableRow[index.cadIndex].tableEntry[i].targetPosition); - ptData.tableRow[index.cadIndex].tableEntry[i].readings--; - moveTable = true; - break; - } - } - - // get the value above the entry - for (int j = index.cadIndex - 1; j > 0; j--) { - if (ptData.tableRow[j].tableEntry[index.wattIndex].targetPosition != INT16_MIN && ptData.tableRow[j].tableEntry[index.wattIndex].targetPosition < pos) { - SS2K_LOG(PTDATA_LOG_TAG, "Lower Up Found %d, %d, tp%d", j, index.wattIndex, ptData.tableRow[j].tableEntry[index.wattIndex].targetPosition); - ptData.tableRow[j].tableEntry[index.wattIndex].readings--; - moveTable = true; - break; - } - } - - if (moveTable) { - //clean(ptData); - return; - } - - entry.targetPosition = pos; // Update the target position with the new average - // Increment readings, capping at the max value. - if (entry.readings < MAX_NEIGHBOR_WEIGHT && !moveTable) { - entry.readings++; - } - - // After updating a point, re-process the entire table to enforce global monotonicity. - resistanceModel.fit(ptData); - // // After updating a point, re-process the entire table to enforce global monotonicity. - this->fillGaps(ptData); - // for (int i = 0; i < 10; i++) { // Run the PAVA functions multiple times to ensure convergence - bool caddone = false; - bool wattdone = false; - int loop = 0; - while ((!caddone || !wattdone) && loop < 3) { - loop++; - if (!caddone) { - caddone = fillAllCadenceLines(ptData); - } - if (!wattdone) { - wattdone = fillAllWattColumns(ptData); - } - SS2K_LOG(PTDATA_LOG_TAG, "PAVA iteration done, still converging: cad %d, watt %d, Loop %d", caddone, wattdone, loop); - } - - - if (resistanceModel.getIsValid()) { - this->fill(ptData); - } -} - void PTHelpers::clean(PTData& ptData) { int removed = 0; // First pass: remove entries with readings < 1 or negative positions for (int i = 0; i < POWERTABLE_CAD_SIZE; i++) { for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { - if (ptData.tableRow[i].tableEntry[j].readings < 1 || ptData.tableRow[i].tableEntry[j].targetPosition < 0) { + //human readings are 2+ + if (ptData.tableRow[i].tableEntry[j].readings < 2 || ptData.tableRow[i].tableEntry[j].targetPosition < 0) { if (ptData.tableRow[i].tableEntry[j].targetPosition != INT16_MIN) { removed++; } @@ -690,3 +693,92 @@ void PTHelpers::clean(PTData& ptData) { SS2K_LOG(PTDATA_LOG_TAG, "Cleaned %d readings", removed); } } + +/** + * @brief "Safe" Smoothing. + * Only smooths cells that have low confidence (few readings). + * This allows "interpolated" gaps to relax into smooth curves, + * but prevents "Real" ride data (Anchors) from being flattened. + */ +void PTHelpers::safeSmooth(PTData& ptData) { + int16_t smoothedGrid[POWERTABLE_CAD_SIZE][POWERTABLE_WATT_SIZE]; + + // CONFIGURATION: + // Any cell with this many readings (or more) is considered "Truth" + // and will NOT be modified. + const int LOCK_THRESHOLD = 5; + + // Weights + const int W_ADJ = 1; + const int W_CAD = 2; + + for (int r = 0; r < POWERTABLE_CAD_SIZE; r++) { + for (int c = 0; c < POWERTABLE_WATT_SIZE; c++) { + TableEntry& current = ptData.tableRow[r].tableEntry[c]; + + // 1. If this is a "High Confidence" cell, skip it. + // We also skip empty cells. + if (current.targetPosition == INT16_MIN || current.readings >= LOCK_THRESHOLD) { + smoothedGrid[r][c] = INT16_MIN; // Mark as "Do Not Touch" + continue; + } + + // 2. Otherwise, calculate the smoothed value + long sum = 0; + int divisor = 0; + + // Self (Low weight since we know it's low confidence) + sum += (long)current.targetPosition; + divisor += 1; + + // Left + if (c > 0) { + TableEntry& n = ptData.tableRow[r].tableEntry[c - 1]; + if (n.targetPosition != INT16_MIN) { + sum += (long)n.targetPosition * W_ADJ; + divisor += W_ADJ; + } + } + // Right + if (c < POWERTABLE_WATT_SIZE - 1) { + TableEntry& n = ptData.tableRow[r].tableEntry[c + 1]; + if (n.targetPosition != INT16_MIN) { + sum += (long)n.targetPosition * W_ADJ; + divisor += W_ADJ; + } + } + // Up + if (r > 0) { + TableEntry& n = ptData.tableRow[r - 1].tableEntry[c]; + if (n.targetPosition != INT16_MIN) { + sum += (long)n.targetPosition * W_CAD; + divisor += W_CAD; + } + } + // Down + if (r < POWERTABLE_CAD_SIZE - 1) { + TableEntry& n = ptData.tableRow[r + 1].tableEntry[c]; + if (n.targetPosition != INT16_MIN) { + sum += (long)n.targetPosition * W_CAD; + divisor += W_CAD; + } + } + + if (divisor > 0) { + smoothedGrid[r][c] = (int16_t)(sum / divisor); + } else { + smoothedGrid[r][c] = current.targetPosition; + } + } + } + + // Write back ONLY the modified cells + for (int r = 0; r < POWERTABLE_CAD_SIZE; r++) { + for (int c = 0; c < POWERTABLE_WATT_SIZE; c++) { + // Only update if we calculated a new value AND the original was unlocked + if (smoothedGrid[r][c] != INT16_MIN) { + ptData.tableRow[r].tableEntry[c].targetPosition = smoothedGrid[r][c]; + } + } + } +} diff --git a/src/Power_Table.cpp b/src/Power_Table.cpp index bae76b74..ef948561 100644 --- a/src/Power_Table.cpp +++ b/src/Power_Table.cpp @@ -68,7 +68,9 @@ void PowerTable::processPowerValue(PowerBuffer& powerBuffer, int cadence, Measur } } if (powerBuffer.powerEntry[POWER_SAMPLES - 1].readings == 1) { // If buffer is full, create a new table entry and clear the buffer. + long int timer = millis(); this->newEntry(powerBuffer); + SS2K_LOG(POWERTABLE_LOG_TAG, "New Entry Processed in %ld ms", millis() - timer); this->toLog(); this->_manageSaveState(); powerBuffer.reset(); @@ -186,8 +188,6 @@ void PowerTable::newEntry(PowerBuffer& powerBuffer) { } ptHelpers.enterData(ptData, index, (int)targetPosition); - ptHelpers.resistanceModel.fit(ptData); - fillTableFlag = true; // set flag to fill table BLE_ss2kCustomCharacteristic::notify(0x27, index.cadIndex); } @@ -368,6 +368,9 @@ bool PowerTable::reset() { this->ptData.tableRow[i].tableEntry[j].readings = 0; } } + userConfig->setHMax(INT32_MIN); + userConfig->setHMin(INT32_MIN); + rtConfig->setHomed(false); File file = LittleFS.open(POWER_TABLE_FILENAME, FILE_READ); if (!file) { SS2K_LOG(POWERTABLE_LOG_TAG, "Failed to Load Power Table."); diff --git a/test/test_table_fill.cpp b/test/test_table_fill.cpp index c6332cf2..375784ef 100644 --- a/test/test_table_fill.cpp +++ b/test/test_table_fill.cpp @@ -76,7 +76,7 @@ void TestTableFill::test_fill_incomplete_table(void) { cleanAndCreateDir(outputDir); // Open Ride_Log.txt - std::ifstream rideLog("test/data/Ride_Log3.txt"); + std::ifstream rideLog("test/data/ride_log3.txt"); // Prepare regex for Averaged Entry lines std::regex entryRegex(R"(\[(\d+)\]\[E\]\(PTable\): Averaged Entry: watts=([\d\.\-]+), cad=([\d\.\-]+), targetPosition=([\d\.\-]+), \((\d+)\)\((\d+)\))"); From 453c9690f29d8dc0f8e130ea1834e6949482f1e6 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Mon, 5 Jan 2026 13:44:55 -0600 Subject: [PATCH 449/451] Cleanup --- include/PowerTable_Helpers.h | 5 - src/PowerTable_Helpers.cpp | 151 +- test/data/Ride_Log4.txt | 15078 +++++++++++++++++++++++++++++++++ test/test_table_fill.cpp | 2 +- 4 files changed, 15081 insertions(+), 155 deletions(-) create mode 100644 test/data/Ride_Log4.txt diff --git a/include/PowerTable_Helpers.h b/include/PowerTable_Helpers.h index c6686c9a..0801fb0b 100644 --- a/include/PowerTable_Helpers.h +++ b/include/PowerTable_Helpers.h @@ -102,8 +102,6 @@ class PTHelpers { ResistanceModel resistanceModel; int32_t lookup(int watts, int cad, PTData& ptData); int lookupWatts(int cad, int32_t targetPosition, PTData& ptData); - // return number of readings in the table. If minReadings is set, it will only count entries with at least that many readings. - int getNumEntries(PTData& ptData, int minReadings = 0); int getTotalReadings(PTData& ptData); ptIndex calculateIndex(int watts, int cad); void enterData(PTData& ptData, ptIndex index, int pos); @@ -112,7 +110,4 @@ class PTHelpers { void fillGaps(PTData& ptData); bool fillAllWattColumns(PTData& ptData); bool fillAllCadenceLines(PTData& ptData); - std::pair, std::vector> getRow(int row, PTData& ptData); - std::pair, std::vector> getColumn(int column, PTData& ptData); - void safeSmooth(PTData& ptData); }; \ No newline at end of file diff --git a/src/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp index 359948c3..9b2ca5b0 100644 --- a/src/PowerTable_Helpers.cpp +++ b/src/PowerTable_Helpers.cpp @@ -39,9 +39,7 @@ unsigned long millis() { #include "SS2KLog.h" #endif -/////////////////////////Testing Helpers///////////////////////// - -// --- Advanced Predictor --- +/////////////////////////Resistance Model///////////////////////// // Gaussian Elimination Solver for NxN matrix bool ResistanceModel::solveMatrix(double A[6][6], double B[6], int n) { @@ -276,7 +274,7 @@ int ResistanceModel::predictWatts(int32_t resistance, float cadence) { return (int)round(finalWatts); } -///////////////////////////////////////////////END of testing Helpers/////////////////////////////////////////////// +///////////////////////////////////////////////Resistance Model/////////////////////////////////////////////// /** @@ -400,62 +398,6 @@ ptIndex PTHelpers::calculateIndex(int watts, int cad) { return index; } -/** - * @brief Retrieves the x and y values from a specific row of the power table. - * - * This function extracts the x and y values from the specified row of the power table - * in the provided PTData object. It skips entries where the target position is set - * to INT16_MIN, which indicates an invalid or uninitialized entry. - * - * @param row The index of the row to retrieve data from. - * @param ptData Reference to the PTData object containing the power table data. - * @return A pair of vectors: - * - The first vector contains the x values (watt increments). - * - The second vector contains the y values (target positions). - */ -std::pair, std::vector> PTHelpers::getRow(int row, PTData& ptData) { - std::vector xValues; - std::vector yValues; - // clamp row to be within table bounds - if (row < 0) row = 0; - if (row >= POWERTABLE_CAD_SIZE) row = POWERTABLE_CAD_SIZE - 1; - for (int j = 0; j < POWERTABLE_WATT_SIZE; ++j) { - if (ptData.tableRow[row].tableEntry[j].targetPosition != INT16_MIN) { - xValues.push_back(static_cast(j * POWERTABLE_WATT_INCREMENT)); - yValues.push_back(static_cast(ptData.tableRow[row].tableEntry[j].targetPosition)); - } - } - return {xValues, yValues}; -} - -/** - * @brief Extracts the x and y values for a specific column from the power table data. - * - * This function iterates through the rows of the power table data and retrieves - * the x and y values for the specified column. The x values are calculated based - * on the cadence index, and the y values are extracted from the target position - * of the table entries. Only valid entries (where the target position is not - * INT16_MIN) are included in the result. - * - * @param column The index of the column to extract data from. - * @param ptData Reference to the PTData structure containing the power table data. - * @return A pair of vectors, where the first vector contains the x values and the - * second vector contains the corresponding y values. - */ -std::pair, std::vector> PTHelpers::getColumn(int column, PTData& ptData) { - std::vector xValues; - std::vector yValues; - // clamp column to be within table bounds - if (column < 0) column = 0; - if (column >= POWERTABLE_WATT_SIZE) column = POWERTABLE_WATT_SIZE - 1; - for (int i = 0; i < POWERTABLE_CAD_SIZE; ++i) { - if (ptData.tableRow[i].tableEntry[column].targetPosition != INT16_MIN) { - xValues.push_back(static_cast(MINIMUM_TABLE_CAD + i * POWERTABLE_CAD_INCREMENT)); - yValues.push_back(static_cast(ptData.tableRow[i].tableEntry[column].targetPosition)); - } - } - return {xValues, yValues}; -} int32_t PTHelpers::lookup(int watts, int cad, PTData& ptData) { if (!resistanceModel.getIsValid()) { @@ -693,92 +635,3 @@ void PTHelpers::clean(PTData& ptData) { SS2K_LOG(PTDATA_LOG_TAG, "Cleaned %d readings", removed); } } - -/** - * @brief "Safe" Smoothing. - * Only smooths cells that have low confidence (few readings). - * This allows "interpolated" gaps to relax into smooth curves, - * but prevents "Real" ride data (Anchors) from being flattened. - */ -void PTHelpers::safeSmooth(PTData& ptData) { - int16_t smoothedGrid[POWERTABLE_CAD_SIZE][POWERTABLE_WATT_SIZE]; - - // CONFIGURATION: - // Any cell with this many readings (or more) is considered "Truth" - // and will NOT be modified. - const int LOCK_THRESHOLD = 5; - - // Weights - const int W_ADJ = 1; - const int W_CAD = 2; - - for (int r = 0; r < POWERTABLE_CAD_SIZE; r++) { - for (int c = 0; c < POWERTABLE_WATT_SIZE; c++) { - TableEntry& current = ptData.tableRow[r].tableEntry[c]; - - // 1. If this is a "High Confidence" cell, skip it. - // We also skip empty cells. - if (current.targetPosition == INT16_MIN || current.readings >= LOCK_THRESHOLD) { - smoothedGrid[r][c] = INT16_MIN; // Mark as "Do Not Touch" - continue; - } - - // 2. Otherwise, calculate the smoothed value - long sum = 0; - int divisor = 0; - - // Self (Low weight since we know it's low confidence) - sum += (long)current.targetPosition; - divisor += 1; - - // Left - if (c > 0) { - TableEntry& n = ptData.tableRow[r].tableEntry[c - 1]; - if (n.targetPosition != INT16_MIN) { - sum += (long)n.targetPosition * W_ADJ; - divisor += W_ADJ; - } - } - // Right - if (c < POWERTABLE_WATT_SIZE - 1) { - TableEntry& n = ptData.tableRow[r].tableEntry[c + 1]; - if (n.targetPosition != INT16_MIN) { - sum += (long)n.targetPosition * W_ADJ; - divisor += W_ADJ; - } - } - // Up - if (r > 0) { - TableEntry& n = ptData.tableRow[r - 1].tableEntry[c]; - if (n.targetPosition != INT16_MIN) { - sum += (long)n.targetPosition * W_CAD; - divisor += W_CAD; - } - } - // Down - if (r < POWERTABLE_CAD_SIZE - 1) { - TableEntry& n = ptData.tableRow[r + 1].tableEntry[c]; - if (n.targetPosition != INT16_MIN) { - sum += (long)n.targetPosition * W_CAD; - divisor += W_CAD; - } - } - - if (divisor > 0) { - smoothedGrid[r][c] = (int16_t)(sum / divisor); - } else { - smoothedGrid[r][c] = current.targetPosition; - } - } - } - - // Write back ONLY the modified cells - for (int r = 0; r < POWERTABLE_CAD_SIZE; r++) { - for (int c = 0; c < POWERTABLE_WATT_SIZE; c++) { - // Only update if we calculated a new value AND the original was unlocked - if (smoothedGrid[r][c] != INT16_MIN) { - ptData.tableRow[r].tableEntry[c].targetPosition = smoothedGrid[r][c]; - } - } - } -} diff --git a/test/data/Ride_Log4.txt b/test/data/Ride_Log4.txt new file mode 100644 index 00000000..bac16ffb --- /dev/null +++ b/test/data/Ride_Log4.txt @@ -0,0 +1,15078 @@ + Number New Column + 132584 [803684][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 5, Cad 81, HR 91, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132585 [809693][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 3, Cad 80, HR 90, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132586 [812492][E](PTable): Averaged Entry: watts=14.100000, cad=84.000000, targetPosition=142.000000, (5)(0) + 132587 [812493][E](PTData): Cleaned 1 readings + 132588 [812503][E](PTData): New entry recorded (5)(0)(142) + 132589 [812504][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132590 [812516][E](PTable): New Entry Processed in 25 ms + 132591 [812517][E](PTable): Power Buffer Reset + 132592 [813199][E](PTable): Using detected travel limits during homing + 132593 [815709][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 6, Cad 84, HR 89, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132594 [821723][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 4, Cad 81, HR 89, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132595 [827741][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 6, Cad 80, HR 88, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132596 [833755][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 5, Cad 80, HR 88, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132597 [839768][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 8, Cad 80, HR 87, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132598 [845783][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 7, Cad 79, HR 87, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132599 [849201][E](PTable): Using detected travel limits during homing + 132600 [851797][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 78, HR 88, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132601 [857805][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 5, Cad 79, HR 88, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132602 [863815][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 5, Cad 78, HR 88, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132603 [869829][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 79, HR 87, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132604 [875846][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 87, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132605 [881857][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 88, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132606 [887867][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 86, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132607 [893880][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 89, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132608 [899890][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 83, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132609 [905904][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 73, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132610 [911919][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 67, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132611 [917931][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 71, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132612 [922532][E](PTable): Using detected travel limits during homing + 132613 [923941][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 32, HR 75, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132614 [929953][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 100, Cad 54, HR 83, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132615 [935961][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 8, Cad 74, HR 85, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132616 [941972][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 5, Cad 75, HR 86, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132617 [947989][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 12, Cad 76, HR 87, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132618 [952186][E](PTable): Averaged Entry: watts=13.700000, cad=77.500000, targetPosition=142.000000, (3)(0) + 132619 [952188][E](PTData): Cleaned 1 readings + 132620 [952198][E](PTData): New entry recorded (3)(0)(142) + 132621 [952200][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132622 [952211][E](PTable): New Entry Processed in 25 ms + 132623 [952374][E](PTable): Writing File: /PowerTable.txt + 132624 [952665][E](PTable): Power table saved successfully with 4 readings + 132625 [952665][E](PTable): Power Buffer Reset + 132626 [953997][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 29, Cad 84, HR 85, Gear 0, Res 4, Current Pos 1421, Target Pos 1421 + 132627 [958541][E](PTable): Using detected travel limits during homing + 132628 [959256][E](FTMS_SERVER): 05 91 00 -> ERG Mode Target: 145 Current: 11 Incline: 2.030000. Responding: 80 05 01 + 132629 [959266][E](DirConManager): Sending response message type 0x04 to client 0 + 132630 [959948][E](PTable): Averaged Entry: watts=14.500000, cad=85.699997, targetPosition=134.899994, (5)(0) + 132631 [959949][E](PTData): Cleaned 1 readings + 132632 [959959][E](PTData): New entry recorded (5)(0)(134) + 132633 [959959][E](PTData): Greater Down Found 6, 0, tp142 + 132634 [959961][E](PTable): New Entry Processed in 14 ms + 132635 [959972][E](PTable): Power Buffer Reset + 132636 [959972][E](ERG_Mode): PowerTable returned negative result with homing enabled. Using PID + 132637 [959982][E](ERG_Mode): Lookup Error. Using PID + 132638 [959982][E](ERG_Mode): Proportional: 1507.500000 + 132639 [960023][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 13, Cad 87, HR 86, Gear 0, Res 2, Current Pos 595, Target Pos 2225 + 132640 [962063][E](ERG_Mode): Watts previously processed. + 132641 [962773][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 132642 [962774][E](PTable): Power Buffer Reset + 132643 [964186][E](ERG_Mode): Watts previously processed. + 132644 [965594][E](ERG_Mode): Proportional: 1406.250000 + 132645 [966032][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 20, Cad 101, HR 83, Gear 0, Res 19, Current Pos 6358, Target Pos 6853 + 132646 [966302][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 132647 [966303][E](PTable): Power Buffer Reset + 132648 [966303][E](ERG_Mode): Watts previously processed. + 132649 [967710][E](ERG_Mode): Watts previously processed. + 132650 [969847][E](ERG_Mode): Watts previously processed. + 132651 [971256][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 132652 [971257][E](PTable): Power Buffer Reset + 132653 [971257][E](ERG_Mode): Proportional: 882.000000 + 132654 [971964][E](ERG_Mode): Watts previously processed. + 132655 [972046][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 47, Cad 102, HR 83, Gear 0, Res 38, Current Pos 11991, Target Pos 12001 + 132656 [974082][E](ERG_Mode): Watts previously processed. + 132657 [976903][E](ERG_Mode): Proportional: -6.000000 + 132658 [977612][E](PTable): Averaged Entry: watts=129.399994, cad=100.900002, targetPosition=1200.000000, (8)(4) + 132659 [977613][E](PTData): Cleaned 1 readings + 132660 [977623][E](PTData): New entry recorded (8)(4)(1200) + 132661 [977625][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132662 [977636][E](PTable): New Entry Processed in 25 ms + 132663 [977637][E](PTable): Power Buffer Reset + 132664 [977637][E](ERG_Mode): Watts previously processed. + 132665 [978061][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 170, Cad 98, HR 88, Gear 0, Res 40, Current Pos 11883, Target Pos 11883 + 132666 [979718][E](ERG_Mode): Watts previously processed. + 132667 [981835][E](ERG_Mode): Watts previously processed. + 132668 [982543][E](ERG_Mode): Proportional: -27.000000 + 132669 [983951][E](PTable): Averaged Entry: watts=161.199997, cad=98.500000, targetPosition=1175.500000, (8)(5) + 132670 [983952][E](PTData): New entry recorded (8)(5)(1175) + 132671 [983962][E](PTData): Greater Left Found 8, 4, tp1200 + 132672 [983964][E](PTable): New Entry Processed in 14 ms + 132673 [983964][E](PTable): Power Buffer Reset + 132674 [983975][E](ERG_Mode): Watts previously processed. + 132675 [984076][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 144, Cad 98, HR 91, Gear 0, Res 39, Current Pos 11657, Target Pos 11657 + 132676 [986078][E](ERG_Mode): Watts previously processed. + 132677 [988194][E](ERG_Mode): Proportional: -1.500000 + 132678 [989598][E](ERG_Mode): Watts previously processed. + 132679 [990086][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 127, Cad 96, HR 100, Gear 0, Res 39, Current Pos 11619, Target Pos 11619 + 132680 [990309][E](PTable): Averaged Entry: watts=147.500000, cad=97.099998, targetPosition=1164.000000, (7)(5) + 132681 [990310][E](PTData): Cleaned 1 readings + 132682 [990320][E](PTData): New entry recorded (7)(5)(1164) + 132683 [990321][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132684 [990333][E](PTable): New Entry Processed in 25 ms + 132685 [990333][E](PTable): Power Buffer Reset + 132686 [991725][E](ERG_Mode): Watts previously processed. + 132687 [993839][E](ERG_Mode): Watts previously processed. + 132688 [994547][E](ERG_Mode): Proportional: -24.750000 + 132689 [994548][E](PTable): Using detected travel limits during homing + 132690 [995953][E](ERG_Mode): Watts previously processed. + 132691 [996095][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 131, Cad 95, HR 107, Gear 0, Res 39, Current Pos 11735, Target Pos 11735 + 132692 [996655][E](PTable): Averaged Entry: watts=136.500000, cad=94.599998, targetPosition=1170.099976, (7)(5) + 132693 [996656][E](PTData): Existing entry averaged (7)(5)(1167), readings(1) + 132694 [996667][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132695 [996669][E](PTable): New Entry Processed in 15 ms + 132696 [996680][E](PTable): Power Buffer Reset + 132697 [998058][E](ERG_Mode): Watts previously processed. + 132698 [1000180][E](ERG_Mode): Proportional: -2.250000 + 132699 [1000880][E](ERG_Mode): Watts previously processed. + 132700 [1002107][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 137, Cad 95, HR 111, Gear 0, Res 39, Current Pos 11730, Target Pos 11730 + 132701 [1002994][E](PTable): Averaged Entry: watts=145.899994, cad=94.699997, targetPosition=1174.199951, (7)(5) + 132702 [1002995][E](PTData): Existing entry averaged (7)(5)(1169), readings(2) + 132703 [1003006][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132704 [1003008][E](PTable): New Entry Processed in 15 ms + 132705 [1003019][E](PTable): Power Buffer Reset + 132706 [1003019][E](ERG_Mode): Watts previously processed. + 132707 [1005102][E](ERG_Mode): Watts previously processed. + 132708 [1005805][E](ERG_Mode): Proportional: 5.250000 + 132709 [1007212][E](ERG_Mode): Watts previously processed. + 132710 [1008118][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 138, Cad 93, HR 113, Gear 0, Res 39, Current Pos 11788, Target Pos 11788 + 132711 [1009336][E](PTable): Averaged Entry: watts=137.600006, cad=93.500000, targetPosition=1175.400024, (7)(5) + 132712 [1009338][E](PTData): Existing entry averaged (7)(5)(1170), readings(3) + 132713 [1009349][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132714 [1009351][E](PTable): New Entry Processed in 15 ms + 132715 [1009362][E](PTable): Power Buffer Reset + 132716 [1010744][E](ERG_Mode): Watts previously processed. + 132717 [1011452][E](ERG_Mode): Proportional: 27.000000 + 132718 [1012865][E](ERG_Mode): Watts previously processed. + 132719 [1014130][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 144, Cad 93, HR 115, Gear 0, Res 40, Current Pos 11874, Target Pos 11874 + 132720 [1014988][E](ERG_Mode): Watts previously processed. + 132721 [1015697][E](PTable): Averaged Entry: watts=138.899994, cad=93.500000, targetPosition=1182.699951, (7)(5) + 132722 [1015698][E](PTData): Existing entry averaged (7)(5)(1172), readings(4) + 132723 [1015709][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132724 [1015711][E](PTable): New Entry Processed in 15 ms + 132725 [1015722][E](PTable): Power Buffer Reset + 132726 [1017108][E](ERG_Mode): Watts previously processed. + 132727 [1017810][E](ERG_Mode): Proportional: 3.750000 + 132728 [1019221][E](ERG_Mode): Watts previously processed. + 132729 [1020141][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 154, Cad 94, HR 116, Gear 0, Res 40, Current Pos 11864, Target Pos 11864 + 132730 [1020636][E](ERG_Mode): Watts previously processed. + 132731 [1022052][E](PTable): Averaged Entry: watts=146.899994, cad=93.900002, targetPosition=1186.199951, (7)(5) + 132732 [1022053][E](PTData): Existing entry averaged (7)(5)(1174), readings(5) + 132733 [1022064][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132734 [1022066][E](PTable): New Entry Processed in 15 ms + 132735 [1022076][E](PTable): Power Buffer Reset + 132736 [1022755][E](ERG_Mode): Watts previously processed. + 132737 [1023464][E](ERG_Mode): Proportional: 3.750000 + 132738 [1024872][E](ERG_Mode): Watts previously processed. + 132739 [1026159][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 140, Cad 94, HR 116, Gear 0, Res 40, Current Pos 11864, Target Pos 11864 + 132740 [1026996][E](ERG_Mode): Watts previously processed. + 132741 [1028402][E](PTable): Averaged Entry: watts=142.000000, cad=93.900002, targetPosition=1185.800049, (7)(5) + 132742 [1028404][E](PTData): Existing entry averaged (7)(5)(1175), readings(6) + 132743 [1028415][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132744 [1028417][E](PTable): New Entry Processed in 15 ms + 132745 [1028428][E](PTable): Power Buffer Reset + 132746 [1029108][E](ERG_Mode): Watts previously processed. + 132747 [1029817][E](ERG_Mode): Proportional: -5.250000 + 132748 [1030526][E](PTable): Using detected travel limits during homing + 132749 [1031231][E](ERG_Mode): Watts previously processed. + 132750 [1032176][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 152, Cad 98, HR 118, Gear 0, Res 39, Current Pos 11804, Target Pos 11804 + 132751 [1032640][E](ERG_Mode): Watts previously processed. + 132752 [1034759][E](PTable): Averaged Entry: watts=155.399994, cad=96.800003, targetPosition=1180.699951, (7)(5) + 132753 [1034760][E](PTData): Existing entry averaged (7)(5)(1175), readings(7) + 132754 [1034771][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132755 [1034773][E](PTable): New Entry Processed in 15 ms + 132756 [1034783][E](PTable): Power Buffer Reset + 132757 [1034784][E](ERG_Mode): Watts previously processed. + 132758 [1034839][E](FTMS_SERVER): 05 a0 00 -> ERG Mode Target: 160 Current: 154 Incline: 117.900002. Responding: 80 05 01 + 132759 [1034847][E](DirConManager): Sending response message type 0x04 to client 0 + 132760 [1035462][E](ERG_Mode): Proportional: 40.500000 + 132761 [1036875][E](ERG_Mode): Watts previously processed. + 132762 [1038192][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 160, Cad 99, HR 121, Gear 0, Res 39, Current Pos 11805, Target Pos 11805 + 132763 [1038989][E](ERG_Mode): Watts previously processed. + 132764 [1041105][E](PTable): Averaged Entry: watts=157.100006, cad=98.199997, targetPosition=1180.199951, (8)(5) + 132765 [1041106][E](PTData): New entry recorded (8)(5)(1180) + 132766 [1041116][E](PTData): Lower Up Found 7, 5, tp1175 + 132767 [1041118][E](PTable): New Entry Processed in 14 ms + 132768 [1041118][E](PTable): Power Buffer Reset + 132769 [1041129][E](ERG_Mode): Watts previously processed. + 132770 [1041812][E](ERG_Mode): Proportional: 3.750000 + 132771 [1043217][E](ERG_Mode): Watts previously processed. + 132772 [1044201][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 155, Cad 97, HR 124, Gear 0, Res 40, Current Pos 11838, Target Pos 11838 + 132773 [1046749][E](ERG_Mode): Watts previously processed. + 132774 [1047457][E](PTable): Averaged Entry: watts=166.199997, cad=99.400002, targetPosition=1180.500000, (8)(6) + 132775 [1047458][E](PTData): New entry recorded (8)(6)(1180) + 132776 [1047469][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132777 [1047471][E](PTable): New Entry Processed in 15 ms + 132778 [1047481][E](PTable): Power Buffer Reset + 132779 [1047482][E](ERG_Mode): Proportional: -6.750000 + 132780 [1048869][E](ERG_Mode): Watts previously processed. + 132781 [1050214][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 165, Cad 100, HR 126, Gear 0, Res 39, Current Pos 11736, Target Pos 11736 + 132782 [1050994][E](ERG_Mode): Watts previously processed. + 132783 [1053127][E](ERG_Mode): Watts previously processed. + 132784 [1053837][E](PTable): Averaged Entry: watts=163.100006, cad=100.900002, targetPosition=1172.400024, (8)(5) + 132785 [1053839][E](PTData): New entry recorded (8)(5)(1172) + 132786 [1053851][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132787 [1053852][E](PTable): New Entry Processed in 15 ms + 132788 [1053863][E](PTable): Power Buffer Reset + 132789 [1053863][E](ERG_Mode): Proportional: -27.000000 + 132790 [1056225][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 165, Cad 99, HR 127, Gear 0, Res 39, Current Pos 11704, Target Pos 11704 + 132791 [1056661][E](ERG_Mode): Watts previously processed. + 132792 [1058775][E](ERG_Mode): Watts previously processed. + 132793 [1059485][E](ERG_Mode): Proportional: 4.500000 + 132794 [1060190][E](PTable): Averaged Entry: watts=154.800003, cad=99.199997, targetPosition=1170.500000, (8)(5) + 132795 [1060192][E](PTData): Existing entry averaged (8)(5)(1171), readings(1) + 132796 [1060203][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132797 [1060205][E](PTable): New Entry Processed in 15 ms + 132798 [1060216][E](PTable): Power Buffer Reset + 132799 [1060893][E](ERG_Mode): Watts previously processed. + 132800 [1062233][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 149, Cad 98, HR 127, Gear 0, Res 39, Current Pos 11800, Target Pos 11800 + 132801 [1063010][E](ERG_Mode): Watts previously processed. + 132802 [1065127][E](ERG_Mode): Watts previously processed. + 132803 [1065835][E](ERG_Mode): Proportional: 6.000000 + 132804 [1066537][E](PTable): Averaged Entry: watts=152.699997, cad=97.800003, targetPosition=1180.800049, (7)(5) + 132805 [1066539][E](PTData): Existing entry averaged (7)(5)(1175), readings(7) + 132806 [1066550][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132807 [1066552][E](PTable): New Entry Processed in 15 ms + 132808 [1066563][E](PTable): Power Buffer Reset + 132809 [1066563][E](PTable): Using detected travel limits during homing + 132810 [1068251][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 150, Cad 97, HR 127, Gear 0, Res 40, Current Pos 11877, Target Pos 11877 + 132811 [1068666][E](ERG_Mode): Watts previously processed. + 132812 [1070777][E](ERG_Mode): Watts previously processed. + 132813 [1071487][E](ERG_Mode): Proportional: 6.750000 + 132814 [1072898][E](PTable): Averaged Entry: watts=155.199997, cad=97.300003, targetPosition=1186.699951, (7)(5) + 132815 [1072899][E](PTData): Existing entry averaged (7)(5)(1176), readings(8) + 132816 [1072910][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132817 [1072912][E](PTable): New Entry Processed in 15 ms + 132818 [1072922][E](PTable): Power Buffer Reset + 132819 [1072923][E](ERG_Mode): Watts previously processed. + 132820 [1074264][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 145, Cad 98, HR 126, Gear 0, Res 40, Current Pos 11882, Target Pos 11882 + 132821 [1075011][E](ERG_Mode): Watts previously processed. + 132822 [1077131][E](ERG_Mode): Proportional: 2.250000 + 132823 [1077836][E](ERG_Mode): Watts previously processed. + 132824 [1079246][E](PTable): Averaged Entry: watts=154.300003, cad=97.099998, targetPosition=1192.199951, (7)(5) + 132825 [1079247][E](PTData): Existing entry averaged (7)(5)(1177), readings(9) + 132826 [1079258][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132827 [1079260][E](PTable): New Entry Processed in 15 ms + 132828 [1079270][E](PTable): Power Buffer Reset + 132829 [1079948][E](ERG_Mode): Watts previously processed. + 132830 [1080276][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 161, Cad 98, HR 126, Gear 0, Res 40, Current Pos 11962, Target Pos 11962 + 132831 [1082063][E](ERG_Mode): Watts previously processed. + 132832 [1082767][E](ERG_Mode): Proportional: 3.750000 + 132833 [1084171][E](ERG_Mode): Watts previously processed. + 132834 [1085581][E](PTable): Averaged Entry: watts=160.000000, cad=97.500000, targetPosition=1196.000000, (7)(5) + 132835 [1085582][E](PTData): Existing entry averaged (7)(5)(1178), readings(10) + 132836 [1085593][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132837 [1085595][E](PTable): New Entry Processed in 15 ms + 132838 [1085606][E](PTable): Power Buffer Reset + 132839 [1086286][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 156, Cad 97, HR 125, Gear 0, Res 40, Current Pos 11963, Target Pos 11963 + 132840 [1086993][E](ERG_Mode): Watts previously processed. + 132841 [1088409][E](ERG_Mode): Proportional: 0.000000 + 132842 [1089115][E](ERG_Mode): Watts previously processed. + 132843 [1091940][E](PTable): Averaged Entry: watts=156.699997, cad=96.400002, targetPosition=1196.300049, (7)(5) + 132844 [1091941][E](PTData): Existing entry averaged (7)(5)(1179), readings(11) + 132845 [1091953][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132846 [1091955][E](PTable): New Entry Processed in 16 ms + 132847 [1091965][E](PTable): Power Buffer Reset + 132848 [1091965][E](ERG_Mode): Watts previously processed. + 132849 [1092298][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 162, Cad 96, HR 125, Gear 0, Res 40, Current Pos 11976, Target Pos 11976 + 132850 [1094055][E](ERG_Mode): Watts previously processed. + 132851 [1094765][E](ERG_Mode): Proportional: 1.500000 + 132852 [1094803][E](FTMS_SERVER): 05 b4 00 -> ERG Mode Target: 180 Current: 158 Incline: 119.779999. Responding: 80 05 01 + 132853 [1094810][E](DirConManager): Sending response message type 0x04 to client 0 + 132854 [1096176][E](ERG_Mode): Watts previously processed. + 132855 [1098291][E](PTable): Averaged Entry: watts=162.199997, cad=96.599998, targetPosition=1198.599976, (7)(5) + 132856 [1098293][E](PTData): Existing entry averaged (7)(5)(1180), readings(12) + 132857 [1098304][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132858 [1098306][E](PTable): New Entry Processed in 15 ms + 132859 [1098316][E](PTable): Power Buffer Reset + 132860 [1098317][E](ERG_Mode): Watts previously processed. + 132861 [1098328][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 162, Cad 98, HR 127, Gear 0, Res 40, Current Pos 12064, Target Pos 12064 + 132862 [1100411][E](ERG_Mode): Proportional: 24.750000 + 132863 [1101815][E](ERG_Mode): Watts previously processed. + 132864 [1102523][E](PTable): Using detected travel limits during homing + 132865 [1103933][E](ERG_Mode): Watts previously processed. + 132866 [1104344][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 169, Cad 97, HR 128, Gear 0, Res 41, Current Pos 12214, Target Pos 12214 + 132867 [1104638][E](PTable): Averaged Entry: watts=167.699997, cad=97.400002, targetPosition=1214.699951, (7)(6) + 132868 [1104640][E](PTData): New entry recorded (7)(6)(1214) + 132869 [1104651][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132870 [1104653][E](PTable): New Entry Processed in 15 ms + 132871 [1104663][E](PTable): Power Buffer Reset + 132872 [1106048][E](ERG_Mode): Watts previously processed. + 132873 [1106758][E](ERG_Mode): Proportional: 6.750000 + 132874 [1108171][E](ERG_Mode): Watts previously processed. + 132875 [1110290][E](ERG_Mode): Watts previously processed. + 132876 [1110352][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 175, Cad 97, HR 129, Gear 0, Res 41, Current Pos 12254, Target Pos 12254 + 132877 [1110992][E](PTable): Averaged Entry: watts=175.199997, cad=96.699997, targetPosition=1224.099976, (7)(6) + 132878 [1110994][E](PTData): Existing entry averaged (7)(6)(1219), readings(1) + 132879 [1111005][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132880 [1111007][E](PTable): New Entry Processed in 15 ms + 132881 [1111017][E](PTable): Power Buffer Reset + 132882 [1111698][E](ERG_Mode): Watts previously processed. + 132883 [1112405][E](ERG_Mode): Proportional: 0.000000 + 132884 [1113817][E](ERG_Mode): Watts previously processed. + 132885 [1115929][E](ERG_Mode): Watts previously processed. + 132886 [1116368][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 181, Cad 98, HR 130, Gear 0, Res 41, Current Pos 12266, Target Pos 12266 + 132887 [1117348][E](PTable): Averaged Entry: watts=176.899994, cad=97.599998, targetPosition=1225.599976, (7)(6) + 132888 [1117349][E](PTData): Existing entry averaged (7)(6)(1221), readings(2) + 132889 [1117360][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132890 [1117362][E](PTable): New Entry Processed in 15 ms + 132891 [1117372][E](PTable): Power Buffer Reset + 132892 [1118052][E](ERG_Mode): Watts previously processed. + 132893 [1118754][E](ERG_Mode): Proportional: 6.000000 + 132894 [1120160][E](ERG_Mode): Watts previously processed. + 132895 [1122281][E](ERG_Mode): Watts previously processed. + 132896 [1122383][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 173, Cad 99, HR 130, Gear 0, Res 41, Current Pos 12276, Target Pos 12276 + 132897 [1123693][E](PTable): Averaged Entry: watts=177.899994, cad=98.000000, targetPosition=1226.500000, (8)(6) + 132898 [1123694][E](PTData): Existing entry averaged (8)(6)(1203), readings(1) + 132899 [1123705][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132900 [1123706][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 0 ms + 132901 [1123721][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 1 ms + 132902 [1123722][E](PTable): New Entry Processed in 30 ms + 132903 [1123722][E](PTable): Power Buffer Reset + 132904 [1123733][E](ERG_Mode): Watts previously processed. + 132905 [1124402][E](ERG_Mode): Proportional: 0.750000 + 132906 [1125809][E](ERG_Mode): Watts previously processed. + 132907 [1127932][E](ERG_Mode): Watts previously processed. + 132908 [1128394][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 183, Cad 98, HR 131, Gear 0, Res 41, Current Pos 12283, Target Pos 12283 + 132909 [1130056][E](PTable): Averaged Entry: watts=176.899994, cad=97.300003, targetPosition=1227.699951, (7)(6) + 132910 [1130057][E](PTData): Existing entry averaged (7)(6)(1222), readings(3) + 132911 [1130068][E](PTData): PAVA iteration done, still converging: cad 0, watt 0, Loop 1 + 132912 [1130078][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 132913 [1130079][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 3 + 132914 [1130089][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 0 ms + 132915 [1130093][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 0 ms + 132916 [1130105][E](PTable): New Entry Processed in 50 ms + 132917 [1130105][E](PTable): Power Buffer Reset + 132918 [1130105][E](ERG_Mode): Watts previously processed. + 132919 [1130758][E](ERG_Mode): Proportional: 6.750000 + 132920 [1132165][E](ERG_Mode): Watts previously processed. + 132921 [1134283][E](ERG_Mode): Watts previously processed. + 132922 [1134405][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 175, Cad 98, HR 132, Gear 0, Res 41, Current Pos 12302, Target Pos 12302 + 132923 [1136407][E](PTable): Averaged Entry: watts=171.000000, cad=97.099998, targetPosition=1230.099976, (7)(6) + 132924 [1136408][E](PTData): Existing entry averaged (7)(6)(1223), readings(4) + 132925 [1136419][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132926 [1136429][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 0 ms + 132927 [1136433][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 0 ms + 132928 [1136435][E](PTable): New Entry Processed in 29 ms + 132929 [1136435][E](PTable): Power Buffer Reset + 132930 [1136446][E](ERG_Mode): Proportional: 36.000000 + 132931 [1137108][E](ERG_Mode): Watts previously processed. + 132932 [1138515][E](PTable): Using detected travel limits during homing + 132933 [1139926][E](ERG_Mode): Watts previously processed. + 132934 [1140416][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 173, Cad 95, HR 133, Gear 0, Res 42, Current Pos 12446, Target Pos 12446 + 132935 [1142038][E](ERG_Mode): Watts previously processed. + 132936 [1142747][E](PTable): Averaged Entry: watts=169.500000, cad=94.900002, targetPosition=1243.400024, (7)(6) + 132937 [1142748][E](PTData): Existing entry averaged (7)(6)(1226), readings(5) + 132938 [1142759][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132939 [1142770][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 1 ms + 132940 [1142774][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 1 ms + 132941 [1142776][E](PTable): New Entry Processed in 30 ms + 132942 [1142776][E](PTable): Power Buffer Reset + 132943 [1142786][E](ERG_Mode): Proportional: 6.750000 + 132944 [1144864][E](ERG_Mode): Watts previously processed. + 132945 [1146432][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 191, Cad 95, HR 134, Gear 0, Res 42, Current Pos 12511, Target Pos 12511 + 132946 [1146977][E](ERG_Mode): Watts previously processed. + 132947 [1148392][E](ERG_Mode): Proportional: -0.750000 + 132948 [1149098][E](PTable): Averaged Entry: watts=179.600006, cad=94.800003, targetPosition=1249.099976, (7)(6) + 132949 [1149099][E](PTData): Existing entry averaged (7)(6)(1229), readings(6) + 132950 [1149110][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132951 [1149121][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 1 ms + 132952 [1149125][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 1 ms + 132953 [1149126][E](PTable): New Entry Processed in 29 ms + 132954 [1149126][E](PTable): Power Buffer Reset + 132955 [1149137][E](ERG_Mode): Watts previously processed. + 132956 [1151212][E](ERG_Mode): Watts previously processed. + 132957 [1152450][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 181, Cad 95, HR 132, Gear 0, Res 42, Current Pos 12466, Target Pos 12466 + 132958 [1153337][E](ERG_Mode): Watts previously processed. + 132959 [1154039][E](ERG_Mode): Proportional: -22.500000 + 132960 [1154832][E](FTMS_SERVER): 05 c8 00 -> ERG Mode Target: 200 Current: 190 Incline: 124.190002. Responding: 80 05 01 + 132961 [1154840][E](DirConManager): Sending response message type 0x04 to client 0 + 132962 [1155454][E](PTable): Averaged Entry: watts=185.899994, cad=95.300003, targetPosition=1245.599976, (7)(6) + 132963 [1155455][E](PTData): Existing entry averaged (7)(6)(1231), readings(7) + 132964 [1155466][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132965 [1155476][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 0 ms + 132966 [1155480][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 0 ms + 132967 [1155482][E](PTable): New Entry Processed in 29 ms + 132968 [1155482][E](PTable): Power Buffer Reset + 132969 [1156862][E](ERG_Mode): Watts previously processed. + 132970 [1158460][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 192, Cad 98, HR 131, Gear 0, Res 42, Current Pos 12456, Target Pos 12456 + 132971 [1158983][E](ERG_Mode): Watts previously processed. + 132972 [1159692][E](ERG_Mode): Proportional: 5.250000 + 132973 [1161096][E](ERG_Mode): Watts previously processed. + 132974 [1161807][E](PTable): Averaged Entry: watts=190.800003, cad=97.199997, targetPosition=1244.699951, (7)(6) + 132975 [1161808][E](PTData): Existing entry averaged (7)(6)(1232), readings(8) + 132976 [1161819][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132977 [1161830][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 1 ms + 132978 [1161834][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 1 ms + 132979 [1161835][E](PTable): New Entry Processed in 29 ms + 132980 [1161835][E](PTable): Power Buffer Reset + 132981 [1163218][E](ERG_Mode): Watts previously processed. + 132982 [1164475][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 216, Cad 97, HR 130, Gear 0, Res 42, Current Pos 12579, Target Pos 12579 + 132983 [1165343][E](ERG_Mode): Watts previously processed. + 132984 [1166053][E](ERG_Mode): Proportional: 67.500000 + 132985 [1168184][E](PTable): Averaged Entry: watts=187.699997, cad=96.000000, targetPosition=1257.199951, (7)(6) + 132986 [1168186][E](PTData): Existing entry averaged (7)(6)(1234), readings(9) + 132987 [1168197][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 132988 [1168208][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 1 ms + 132989 [1168212][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 1 ms + 132990 [1168213][E](PTable): New Entry Processed in 29 ms + 132991 [1168213][E](PTable): Power Buffer Reset + 132992 [1168893][E](ERG_Mode): Watts previously processed. + 132993 [1170490][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 196, Cad 96, HR 131, Gear 0, Res 43, Current Pos 12747, Target Pos 12747 + 132994 [1171004][E](ERG_Mode): Watts previously processed. + 132995 [1171715][E](ERG_Mode): Proportional: 22.500000 + 132996 [1173127][E](ERG_Mode): Watts previously processed. + 132997 [1174546][E](PTable): Averaged Entry: watts=192.600006, cad=95.099998, targetPosition=1275.000000, (7)(6) + 132998 [1174547][E](PTData): Existing entry averaged (7)(6)(1237), readings(10) + 132999 [1174558][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133000 [1174569][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 1 ms + 133001 [1174573][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 0 ms + 133002 [1174574][E](PTable): New Entry Processed in 29 ms + 133003 [1174575][E](PTable): Power Buffer Reset + 133004 [1174585][E](PTable): Using detected travel limits during homing + 133005 [1175254][E](ERG_Mode): Watts previously processed. + 133006 [1176503][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 196, Cad 95, HR 132, Gear 0, Res 43, Current Pos 12800, Target Pos 12800 + 133007 [1177370][E](ERG_Mode): Watts previously processed. + 133008 [1178071][E](ERG_Mode): Proportional: 3.000000 + 133009 [1180890][E](PTable): Averaged Entry: watts=194.699997, cad=95.199997, targetPosition=1279.699951, (7)(6) + 133010 [1180892][E](PTData): Existing entry averaged (7)(6)(1240), readings(11) + 133011 [1180903][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133012 [1180914][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 1 ms + 133013 [1180918][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 1 ms + 133014 [1180919][E](PTable): New Entry Processed in 29 ms + 133015 [1180920][E](PTable): Power Buffer Reset + 133016 [1180930][E](ERG_Mode): Watts previously processed. + 133017 [1182512][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 200, Cad 95, HR 132, Gear 0, Res 43, Current Pos 12815, Target Pos 12815 + 133018 [1183007][E](ERG_Mode): Watts previously processed. + 133019 [1183718][E](ERG_Mode): Proportional: 0.000000 + 133020 [1184816][E](FTMS_SERVER): 05 d7 00 -> ERG Mode Target: 215 Current: 204 Incline: 128.119995. Responding: 80 05 01 + 133021 [1184821][E](DirConManager): Sending response message type 0x04 to client 0 + 133022 [1187244][E](PTable): Averaged Entry: watts=198.800003, cad=95.500000, targetPosition=1282.599976, (7)(7) + 133023 [1187246][E](PTData): Existing entry averaged (7)(7)(1278), readings(1) + 133024 [1187257][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133025 [1187268][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133026 [1187272][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133027 [1187274][E](PTable): New Entry Processed in 30 ms + 133028 [1187274][E](PTable): Power Buffer Reset + 133029 [1187284][E](ERG_Mode): Watts previously processed. + 133030 [1188527][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 208, Cad 96, HR 133, Gear 0, Res 43, Current Pos 12944, Target Pos 12944 + 133031 [1189364][E](ERG_Mode): Watts previously processed. + 133032 [1190066][E](ERG_Mode): Proportional: 29.250000 + 133033 [1190776][E](ERG_Mode): Watts previously processed. + 133034 [1192891][E](ERG_Mode): Watts previously processed. + 133035 [1193594][E](PTable): Averaged Entry: watts=206.699997, cad=96.699997, targetPosition=1295.800049, (7)(7) + 133036 [1193595][E](PTData): Existing entry averaged (7)(7)(1283), readings(2) + 133037 [1193606][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133038 [1193617][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133039 [1193621][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133040 [1193623][E](PTable): New Entry Processed in 30 ms + 133041 [1194176][E](PTable): Writing File: /PowerTable.txt + 133042 [1194412][E](PTable): Power table saved successfully with 327 readings + 133043 [1194412][E](PTable): Power Buffer Reset + 133044 [1194537][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 200, Cad 95, HR 133, Gear 0, Res 43, Current Pos 13021, Target Pos 13035 + 133045 [1195155][E](ERG_Mode): Watts previously processed. + 133046 [1195864][E](ERG_Mode): Proportional: 33.750000 + 133047 [1197976][E](ERG_Mode): Watts previously processed. + 133048 [1200092][E](PTable): Averaged Entry: watts=206.300003, cad=95.099998, targetPosition=1304.699951, (7)(7) + 133049 [1200093][E](PTData): Existing entry averaged (7)(7)(1288), readings(3) + 133050 [1200104][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133051 [1200114][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133052 [1200119][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133053 [1200120][E](PTable): New Entry Processed in 29 ms + 133054 [1200120][E](PTable): Power Buffer Reset + 133055 [1200131][E](ERG_Mode): Watts previously processed. + 133056 [1200555][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 213, Cad 95, HR 134, Gear 0, Res 44, Current Pos 13078, Target Pos 13078 + 133057 [1201508][E](ERG_Mode): Proportional: 22.500000 + 133058 [1202215][E](ERG_Mode): Watts previously processed. + 133059 [1204330][E](ERG_Mode): Watts previously processed. + 133060 [1206445][E](PTable): Averaged Entry: watts=209.899994, cad=94.800003, targetPosition=1309.199951, (7)(7) + 133061 [1206447][E](PTData): Existing entry averaged (7)(7)(1292), readings(4) + 133062 [1206458][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133063 [1206469][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133064 [1206473][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133065 [1206474][E](PTable): New Entry Processed in 29 ms + 133066 [1206474][E](PTable): Power Buffer Reset + 133067 [1206485][E](ERG_Mode): Watts previously processed. + 133068 [1206565][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 220, Cad 94, HR 135, Gear 0, Res 44, Current Pos 13112, Target Pos 13112 + 133069 [1207146][E](ERG_Mode): Proportional: -6.000000 + 133070 [1207852][E](ERG_Mode): Watts previously processed. + 133071 [1209970][E](ERG_Mode): Watts previously processed. + 133072 [1210677][E](PTable): Using detected travel limits during homing + 133073 [1212085][E](ERG_Mode): Watts previously processed. + 133074 [1212585][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 212, Cad 96, HR 136, Gear 0, Res 44, Current Pos 13035, Target Pos 13035 + 133075 [1212800][E](PTable): Averaged Entry: watts=220.699997, cad=96.000000, targetPosition=1308.099976, (7)(7) + 133076 [1212803][E](PTData): Existing entry averaged (7)(7)(1294), readings(5) + 133077 [1212813][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133078 [1212824][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133079 [1212828][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133080 [1212829][E](PTable): New Entry Processed in 29 ms + 133081 [1212830][E](PTable): Power Buffer Reset + 133082 [1212840][E](ERG_Mode): Proportional: 2.250000 + 133083 [1214205][E](ERG_Mode): Watts previously processed. + 133084 [1214927][E](FTMS_SERVER): 05 a0 00 -> ERG Mode Target: 160 Current: 222 Incline: 130.690002. Responding: 80 05 01 + 133085 [1214932][E](DirConManager): Sending response message type 0x04 to client 0 + 133086 [1215624][E](ERG_Mode): SetPoint changed:190w Waiting:877ms PowerTable Result: 12450 + 133087 [1217904][E](ERG_Mode): ERG wait expired, pos: 12450, tgt: 0 + 133088 [1217905][E](ERG_Mode): Proportional: -195.000000 + 133089 [1218596][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 206, Cad 101, HR 136, Gear 0, Res 41, Current Pos 12255, Target Pos 12255 + 133090 [1220020][E](ERG_Mode): Watts previously processed. + 133091 [1220723][E](PTable): Averaged Entry: watts=204.899994, cad=98.000000, targetPosition=1262.500000, (8)(7) + 133092 [1220725][E](PTData): Existing entry averaged (8)(7)(1262), readings(1) + 133093 [1220736][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133094 [1220747][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 1 ms + 133095 [1220753][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 1 ms + 133096 [1220755][E](PTable): New Entry Processed in 32 ms + 133097 [1220755][E](PTable): Power Buffer Reset + 133098 [1222130][E](ERG_Mode): Watts previously processed. + 133099 [1223548][E](ERG_Mode): Proportional: -2.250000 + 133100 [1224257][E](ERG_Mode): Watts previously processed. + 133101 [1224614][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 160, Cad 97, HR 138, Gear 0, Res 40, Current Pos 11993, Target Pos 11993 + 133102 [1226367][E](ERG_Mode): Watts previously processed. + 133103 [1227076][E](PTable): Averaged Entry: watts=163.699997, cad=97.800003, targetPosition=1199.800049, (7)(5) + 133104 [1227078][E](PTData): Existing entry averaged (7)(5)(1181), readings(13) + 133105 [1227089][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133106 [1227100][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 1 ms + 133107 [1227104][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 0 ms + 133108 [1227105][E](PTable): New Entry Processed in 29 ms + 133109 [1227105][E](PTable): Power Buffer Reset + 133110 [1229193][E](ERG_Mode): Proportional: 29.250000 + 133111 [1229902][E](ERG_Mode): Watts previously processed. + 133112 [1230632][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 157, Cad 95, HR 141, Gear 0, Res 40, Current Pos 12037, Target Pos 12038 + 133113 [1232017][E](ERG_Mode): Watts previously processed. + 133114 [1233428][E](PTable): Averaged Entry: watts=153.699997, cad=95.500000, targetPosition=1201.900024, (7)(5) + 133115 [1233429][E](PTData): Existing entry averaged (7)(5)(1182), readings(14) + 133116 [1233440][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133117 [1233451][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 0 ms + 133118 [1233455][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 0 ms + 133119 [1233456][E](PTable): New Entry Processed in 29 ms + 133120 [1233457][E](PTable): Power Buffer Reset + 133121 [1234131][E](ERG_Mode): Watts previously processed. + 133122 [1234832][E](ERG_Mode): Proportional: 0.750000 + 133123 [1236245][E](ERG_Mode): Watts previously processed. + 133124 [1236643][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 165, Cad 97, HR 140, Gear 0, Res 40, Current Pos 12069, Target Pos 12069 + 133125 [1238358][E](ERG_Mode): Watts previously processed. + 133126 [1239764][E](PTable): Averaged Entry: watts=157.399994, cad=96.000000, targetPosition=1206.099976, (7)(5) + 133127 [1239766][E](PTData): Existing entry averaged (7)(5)(1183), readings(15) + 133128 [1239777][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133129 [1239787][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 0 ms + 133130 [1239791][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 0 ms + 133131 [1239793][E](PTable): New Entry Processed in 29 ms + 133132 [1239794][E](PTable): Power Buffer Reset + 133133 [1239804][E](ERG_Mode): Watts previously processed. + 133134 [1240468][E](ERG_Mode): Proportional: 5.250000 + 133135 [1241876][E](ERG_Mode): Watts previously processed. + 133136 [1242672][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 151, Cad 96, HR 139, Gear 0, Res 40, Current Pos 12089, Target Pos 12089 + 133137 [1243997][E](ERG_Mode): Watts previously processed. + 133138 [1246115][E](PTable): Averaged Entry: watts=151.100006, cad=96.000000, targetPosition=1208.000000, (7)(5) + 133139 [1246117][E](PTData): Existing entry averaged (7)(5)(1184), readings(16) + 133140 [1246128][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133141 [1246138][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 0 ms + 133142 [1246143][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 1 ms + 133143 [1246144][E](PTable): New Entry Processed in 29 ms + 133144 [1246144][E](PTable): Power Buffer Reset + 133145 [1246155][E](ERG_Mode): Watts previously processed. + 133146 [1246818][E](ERG_Mode): Proportional: 47.250000 + 133147 [1248227][E](ERG_Mode): Watts previously processed. + 133148 [1248228][E](PTable): Using detected travel limits during homing + 133149 [1248686][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 161, Cad 97, HR 138, Gear 0, Res 41, Current Pos 12133, Target Pos 12133 + 133150 [1250348][E](ERG_Mode): Watts previously processed. + 133151 [1251776][E](ERG_Mode): Watts previously processed. + 133152 [1252485][E](PTable): Averaged Entry: watts=158.800003, cad=95.500000, targetPosition=1212.900024, (7)(5) + 133153 [1252486][E](PTData): Existing entry averaged (7)(5)(1185), readings(17) + 133154 [1252497][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133155 [1252508][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 1 ms + 133156 [1252512][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 1 ms + 133157 [1252513][E](PTable): New Entry Processed in 29 ms + 133158 [1252513][E](PTable): Power Buffer Reset + 133159 [1252524][E](ERG_Mode): Proportional: -3.750000 + 133160 [1253892][E](ERG_Mode): Watts previously processed. + 133161 [1254694][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 161, Cad 96, HR 138, Gear 0, Res 41, Current Pos 12125, Target Pos 12125 + 133162 [1256000][E](ERG_Mode): Watts previously processed. + 133163 [1258122][E](ERG_Mode): Watts previously processed. + 133164 [1258831][E](PTable): Averaged Entry: watts=162.500000, cad=95.800003, targetPosition=1212.000000, (7)(5) + 133165 [1258832][E](PTData): Existing entry averaged (7)(5)(1186), readings(18) + 133166 [1258843][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133167 [1258854][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 1 ms + 133168 [1258858][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 1 ms + 133169 [1258859][E](PTable): New Entry Processed in 29 ms + 133170 [1258859][E](PTable): Power Buffer Reset + 133171 [1258870][E](ERG_Mode): Proportional: -2.250000 + 133172 [1260240][E](ERG_Mode): Watts previously processed. + 133173 [1260709][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 161, Cad 95, HR 140, Gear 0, Res 40, Current Pos 12120, Target Pos 12120 + 133174 [1263068][E](ERG_Mode): Watts previously processed. + 133175 [1264481][E](ERG_Mode): Proportional: -3.000000 + 133176 [1265189][E](PTable): Averaged Entry: watts=160.800003, cad=95.300003, targetPosition=1211.099976, (7)(5) + 133177 [1265190][E](PTData): Existing entry averaged (7)(5)(1187), readings(19) + 133178 [1265201][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133179 [1265212][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 1 ms + 133180 [1265216][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 1 ms + 133181 [1265217][E](PTable): New Entry Processed in 29 ms + 133182 [1265217][E](PTable): Power Buffer Reset + 133183 [1265228][E](ERG_Mode): Watts previously processed. + 133184 [1266717][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 157, Cad 96, HR 140, Gear 0, Res 40, Current Pos 12112, Target Pos 12112 + 133185 [1267300][E](ERG_Mode): Watts previously processed. + 133186 [1269408][E](ERG_Mode): Watts previously processed. + 133187 [1270110][E](ERG_Mode): Proportional: 0.750000 + 133188 [1271536][E](PTable): Averaged Entry: watts=159.000000, cad=94.900002, targetPosition=1210.800049, (7)(5) + 133189 [1271538][E](PTData): Existing entry averaged (7)(5)(1188), readings(20) + 133190 [1271548][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133191 [1271559][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 0 ms + 133192 [1271563][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 0 ms + 133193 [1271565][E](PTable): New Entry Processed in 29 ms + 133194 [1271565][E](PTable): Power Buffer Reset + 133195 [1272735][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 156, Cad 95, HR 138, Gear 0, Res 40, Current Pos 12114, Target Pos 12114 + 133196 [1272945][E](ERG_Mode): Watts previously processed. + 133197 [1274847][E](FTMS_SERVER): 05 3b 01 -> ERG Mode Target: 315 Current: 163 Incline: 121.080002. Responding: 80 05 01 + 133198 [1274853][E](DirConManager): Sending response message type 0x04 to client 0 + 133199 [1275068][E](ERG_Mode): SetPoint changed:285w Waiting:1278ms PowerTable Result: 14130 + 133200 [1277751][E](ERG_Mode): ERG wait expired, pos: 14130, tgt: 0 + 133201 [1277752][E](ERG_Mode): Proportional: 540.000000 + 133202 [1278462][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 133203 [1278463][E](PTable): Power Buffer Reset + 133204 [1278748][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 291, Cad 97, HR 137, Gear 0, Res 49, Current Pos 14699, Target Pos 14699 + 133205 [1279166][E](ERG_Mode): Watts previously processed. + 133206 [1281286][E](ERG_Mode): Watts previously processed. + 133207 [1283400][E](ERG_Mode): Proportional: -49.500000 + 133208 [1284109][E](ERG_Mode): Watts previously processed. + 133209 [1284757][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 323, Cad 101, HR 136, Gear 0, Res 49, Current Pos 14593, Target Pos 14593 + 133210 [1284818][E](PTable): Averaged Entry: watts=316.899994, cad=99.599998, targetPosition=1466.500000, (8)(11) + 133211 [1284820][E](PTData): Existing entry averaged (8)(11)(1462), readings(1) + 133212 [1284830][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133213 [1284841][E](PTData): Fit Valid: 1, N: 7, Quad: 0, Time: 0 ms + 133214 [1284846][E](PTData): Fit Valid: 1, N: 7, Quad: 0, Time: 1 ms + 133215 [1284847][E](PTable): New Entry Processed in 29 ms + 133216 [1284847][E](PTable): Power Buffer Reset + 133217 [1286231][E](PTable): Using detected travel limits during homing + 133218 [1286940][E](ERG_Mode): Watts previously processed. + 133219 [1289055][E](ERG_Mode): Watts previously processed. + 133220 [1289763][E](ERG_Mode): Proportional: -2.250000 + 133221 [1290770][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 324, Cad 101, HR 135, Gear 0, Res 49, Current Pos 14566, Target Pos 14566 + 133222 [1291177][E](PTable): Averaged Entry: watts=319.799988, cad=100.800003, targetPosition=1457.500000, (8)(11) + 133223 [1291178][E](PTData): Existing entry averaged (8)(11)(1460), readings(2) + 133224 [1291189][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133225 [1291200][E](PTData): Fit Valid: 1, N: 7, Quad: 0, Time: 1 ms + 133226 [1291204][E](PTData): Fit Valid: 1, N: 7, Quad: 0, Time: 1 ms + 133227 [1291205][E](PTable): New Entry Processed in 29 ms + 133228 [1291206][E](PTable): Power Buffer Reset + 133229 [1291216][E](ERG_Mode): Watts previously processed. + 133230 [1293292][E](ERG_Mode): Watts previously processed. + 133231 [1295410][E](ERG_Mode): Proportional: -47.250000 + 133232 [1296110][E](ERG_Mode): Watts previously processed. + 133233 [1296785][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 326, Cad 103, HR 140, Gear 0, Res 48, Current Pos 14419, Target Pos 14419 + 133234 [1297524][E](PTable): Averaged Entry: watts=329.100006, cad=101.699997, targetPosition=1449.699951, (8)(11) + 133235 [1297525][E](PTData): Existing entry averaged (8)(11)(1457), readings(3) + 133236 [1297536][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133237 [1297547][E](PTData): Fit Valid: 1, N: 7, Quad: 0, Time: 1 ms + 133238 [1297551][E](PTData): Fit Valid: 1, N: 7, Quad: 0, Time: 1 ms + 133239 [1297553][E](PTable): New Entry Processed in 30 ms + 133240 [1297553][E](PTable): Power Buffer Reset + 133241 [1298932][E](ERG_Mode): Watts previously processed. + 133242 [1301054][E](ERG_Mode): Watts previously processed. + 133243 [1301764][E](ERG_Mode): Proportional: -22.500000 + 133244 [1302801][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 317, Cad 103, HR 143, Gear 0, Res 48, Current Pos 14315, Target Pos 14315 + 133245 [1303168][E](ERG_Mode): Watts previously processed. + 133246 [1303878][E](PTable): Averaged Entry: watts=321.399994, cad=103.000000, targetPosition=1433.500000, (9)(11) + 133247 [1303879][E](PTData): Existing entry averaged (9)(11)(1431), readings(1) + 133248 [1303890][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133249 [1303901][E](PTData): Fit Valid: 1, N: 8, Quad: 0, Time: 1 ms + 133250 [1303905][E](PTData): Fit Valid: 1, N: 8, Quad: 0, Time: 0 ms + 133251 [1303907][E](PTable): New Entry Processed in 30 ms + 133252 [1303907][E](PTable): Power Buffer Reset + 133253 [1305285][E](ERG_Mode): Watts previously processed. + 133254 [1307400][E](ERG_Mode): Proportional: -3.750000 + 133255 [1308106][E](ERG_Mode): Watts previously processed. + 133256 [1308817][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 329, Cad 104, HR 147, Gear 0, Res 48, Current Pos 14261, Target Pos 14261 + 133257 [1310230][E](PTable): Averaged Entry: watts=323.399994, cad=103.699997, targetPosition=1427.300049, (9)(11) + 133258 [1310231][E](PTData): Existing entry averaged (9)(11)(1429), readings(2) + 133259 [1310242][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133260 [1310253][E](PTData): Fit Valid: 1, N: 8, Quad: 0, Time: 1 ms + 133261 [1310257][E](PTData): Fit Valid: 1, N: 8, Quad: 0, Time: 0 ms + 133262 [1310258][E](PTable): New Entry Processed in 29 ms + 133263 [1310259][E](PTable): Power Buffer Reset + 133264 [1310269][E](ERG_Mode): Watts previously processed. + 133265 [1312346][E](ERG_Mode): Watts previously processed. + 133266 [1313057][E](ERG_Mode): Proportional: 0.750000 + 133267 [1314828][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 297, Cad 104, HR 150, Gear 0, Res 47, Current Pos 14229, Target Pos 14229 + 133268 [1314882][E](FTMS_SERVER): 05 a0 00 -> ERG Mode Target: 160 Current: 297 Incline: 142.289993. Responding: 80 05 01 + 133269 [1314890][E](DirConManager): Sending response message type 0x04 to client 0 + 133270 [1315193][E](ERG_Mode): SetPoint changed:190w Waiting:1320ms PowerTable Result: 12060 + 133271 [1317916][E](ERG_Mode): ERG wait expired, pos: 12060, tgt: 0 + 133272 [1318626][E](PTable): Averaged Entry: watts=295.000000, cad=103.900002, targetPosition=1374.099976, (9)(10) + 133273 [1318627][E](PTData): Existing entry averaged (9)(10)(1377), readings(1) + 133274 [1318638][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133275 [1318649][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 133276 [1318654][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 133277 [1318655][E](PTable): New Entry Processed in 30 ms + 133278 [1318655][E](PTable): Power Buffer Reset + 133279 [1318666][E](ERG_Mode): Proportional: -156.000000 + 133280 [1320035][E](ERG_Mode): Watts previously processed. + 133281 [1320836][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 195, Cad 105, HR 154, Gear 0, Res 39, Current Pos 11566, Target Pos 11503 + 133282 [1322153][E](ERG_Mode): Watts previously processed. + 133283 [1324273][E](ERG_Mode): Watts previously processed. + 133284 [1324273][E](PTable): Using detected travel limits during homing + 133285 [1324983][E](PTable): Averaged Entry: watts=170.300003, cad=104.199997, targetPosition=1157.199951, (9)(6) + 133286 [1324984][E](PTData): Existing entry averaged (9)(6)(1169), readings(1) + 133287 [1324995][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 133288 [1325007][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 133289 [1325015][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 133290 [1325016][E](PTable): New Entry Processed in 34 ms + 133291 [1325016][E](PTable): Power Buffer Reset + 133292 [1325027][E](ERG_Mode): Proportional: -0.750000 + 133293 [1326393][E](ERG_Mode): Watts previously processed. + 133294 [1326853][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 153, Cad 108, HR 155, Gear 0, Res 39, Current Pos 11583, Target Pos 11583 + 133295 [1329916][E](ERG_Mode): Watts previously processed. + 133296 [1330624][E](ERG_Mode): Proportional: 47.250000 + 133297 [1332030][E](ERG_Mode): Watts previously processed. + 133298 [1332738][E](PTable): Averaged Entry: watts=149.000000, cad=102.099998, targetPosition=1164.599976, (8)(5) + 133299 [1332739][E](PTData): Cleaned 20 readings + 133300 [1332750][E](PTData): Existing entry averaged (8)(5)(1168), readings(2) + 133301 [1332751][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 133302 [1332761][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 133303 [1332772][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 3 + 133304 [1332773][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 133305 [1332792][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 133306 [1332793][E](PTable): New Entry Processed in 56 ms + 133307 [1332794][E](PTable): Power Buffer Reset + 133308 [1332864][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 147, Cad 99, HR 155, Gear 0, Res 39, Current Pos 11752, Target Pos 11774 + 133309 [1334147][E](ERG_Mode): Watts previously processed. + 133310 [1336267][E](ERG_Mode): Watts previously processed. + 133311 [1336976][E](ERG_Mode): Proportional: 27.000000 + 133312 [1338381][E](ERG_Mode): Watts previously processed. + 133313 [1338881][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 148, Cad 97, HR 155, Gear 0, Res 40, Current Pos 11878, Target Pos 11878 + 133314 [1339092][E](PTable): Averaged Entry: watts=149.699997, cad=98.000000, targetPosition=1181.599976, (8)(5) + 133315 [1339093][E](PTData): Cleaned 10 readings + 133316 [1339103][E](PTData): Existing entry averaged (8)(5)(1171), readings(3) + 133317 [1339104][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 133318 [1339115][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 133319 [1339116][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 3 + 133320 [1339127][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 133321 [1339146][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 133322 [1339147][E](PTable): New Entry Processed in 56 ms + 133323 [1339148][E](PTable): Power Buffer Reset + 133324 [1341201][E](ERG_Mode): Watts previously processed. + 133325 [1342614][E](ERG_Mode): Proportional: 3.000000 + 133326 [1343321][E](ERG_Mode): Watts previously processed. + 133327 [1344897][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 155, Cad 98, HR 153, Gear 0, Res 40, Current Pos 11923, Target Pos 11923 + 133328 [1345443][E](PTable): Averaged Entry: watts=155.600006, cad=98.099998, targetPosition=1190.900024, (8)(5) + 133329 [1345444][E](PTData): Cleaned 12 readings + 133330 [1345454][E](PTData): Existing entry averaged (8)(5)(1174), readings(4) + 133331 [1345455][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 133332 [1345466][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 133333 [1345467][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 3 + 133334 [1345479][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 133335 [1345487][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 133336 [1345488][E](PTable): New Entry Processed in 46 ms + 133337 [1345498][E](PTable): Power Buffer Reset + 133338 [1345499][E](ERG_Mode): Watts previously processed. + 133339 [1347551][E](ERG_Mode): Watts previously processed. + 133340 [1348252][E](ERG_Mode): Proportional: -56.250000 + 133341 [1350907][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 142, Cad 96, HR 149, Gear 0, Res 40, Current Pos 11917, Target Pos 11917 + 133342 [1351079][E](ERG_Mode): Watts previously processed. + 133343 [1351798][E](PTable): Averaged Entry: watts=155.199997, cad=98.000000, targetPosition=1189.900024, (8)(5) + 133344 [1351800][E](PTData): Cleaned 5 readings + 133345 [1351810][E](PTData): Existing entry averaged (8)(5)(1176), readings(5) + 133346 [1351811][E](PTData): Lower Up Found 4, 5, tp1175 + 133347 [1351822][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 133348 [1351824][E](PTable): New Entry Processed in 26 ms + 133349 [1351824][E](PTable): Power Buffer Reset + 133350 [1353216][E](ERG_Mode): Watts previously processed. + 133351 [1353921][E](ERG_Mode): Proportional: 36.000000 + 133352 [1355328][E](ERG_Mode): Watts previously processed. + 133353 [1356915][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 149, Cad 94, HR 146, Gear 0, Res 40, Current Pos 12109, Target Pos 12109 + 133354 [1357443][E](ERG_Mode): Watts previously processed. + 133355 [1358152][E](PTable): Averaged Entry: watts=147.399994, cad=94.699997, targetPosition=1202.300049, (7)(5) + 133356 [1358154][E](PTData): Cleaned 1 readings + 133357 [1358164][E](PTData): Existing entry averaged (7)(5)(1188), readings(20) + 133358 [1358164][E](PTData): Lower Up Found 3, 5, tp1150 + 133359 [1358176][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 133360 [1358178][E](PTable): New Entry Processed in 26 ms + 133361 [1358178][E](PTable): Power Buffer Reset + 133362 [1359560][E](ERG_Mode): Watts previously processed. + 133363 [1360264][E](ERG_Mode): Proportional: 2.250000 + 133364 [1360266][E](PTable): Using detected travel limits during homing + 133365 [1360966][E](ERG_Mode): Watts previously processed. + 133366 [1362928][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 160, Cad 97, HR 145, Gear 0, Res 40, Current Pos 12103, Target Pos 12103 + 133367 [1363078][E](ERG_Mode): Watts previously processed. + 133368 [1364490][E](PTable): Averaged Entry: watts=159.899994, cad=96.000000, targetPosition=1210.000000, (7)(5) + 133369 [1364491][E](PTData): Cleaned 1 readings + 133370 [1364501][E](PTData): Existing entry averaged (7)(5)(1189), readings(20) + 133371 [1364502][E](PTData): Lower Up Found 2, 5, tp1115 + 133372 [1364513][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 133373 [1364514][E](PTable): New Entry Processed in 25 ms + 133374 [1364515][E](PTable): Power Buffer Reset + 133375 [1365194][E](ERG_Mode): Watts previously processed. + 133376 [1365902][E](ERG_Mode): Proportional: -1.500000 + 133377 [1367316][E](ERG_Mode): Watts previously processed. + 133378 [1368944][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 168, Cad 96, HR 144, Gear 0, Res 40, Current Pos 12109, Target Pos 12109 + 133379 [1369432][E](ERG_Mode): Watts previously processed. + 133380 [1370847][E](PTable): Averaged Entry: watts=164.600006, cad=95.699997, targetPosition=1211.300049, (7)(5) + 133381 [1370849][E](PTData): Cleaned 1 readings + 133382 [1370859][E](PTData): Existing entry averaged (7)(5)(1189), readings(20) + 133383 [1370860][E](PTData): Lower Up Found 1, 5, tp1071 + 133384 [1370871][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 133385 [1370873][E](PTable): New Entry Processed in 26 ms + 133386 [1370873][E](PTable): Power Buffer Reset + 133387 [1371551][E](ERG_Mode): Watts previously processed. + 133388 [1372260][E](ERG_Mode): Proportional: -38.250000 + 133389 [1372962][E](ERG_Mode): Watts previously processed. + 133390 [1374874][E](FTMS_SERVER): 05 aa 00 -> ERG Mode Target: 170 Current: 162 Incline: 120.290001. Responding: 80 05 01 + 133391 [1374880][E](DirConManager): Sending response message type 0x04 to client 0 + 133392 [1374955][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 162, Cad 98, HR 142, Gear 0, Res 40, Current Pos 12029, Target Pos 12029 + 133393 [1377208][E](PTable): Averaged Entry: watts=167.399994, cad=97.900002, targetPosition=1205.300049, (7)(6) + 133394 [1377209][E](PTData): Cleaned 1 readings + 133395 [1377219][E](PTData): Existing entry averaged (7)(6)(1233), readings(12) + 133396 [1377220][E](PTData): Lower Up Found 5, 6, tp1227 + 133397 [1377231][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 133398 [1377233][E](PTable): New Entry Processed in 26 ms + 133399 [1377233][E](PTable): Power Buffer Reset + 133400 [1377243][E](ERG_Mode): Watts previously processed. + 133401 [1377917][E](ERG_Mode): Proportional: -3.000000 + 133402 [1379320][E](ERG_Mode): Watts previously processed. + 133403 [1380972][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 161, Cad 97, HR 141, Gear 0, Res 40, Current Pos 12094, Target Pos 12094 + 133404 [1381439][E](ERG_Mode): Watts previously processed. + 133405 [1383564][E](PTable): Averaged Entry: watts=163.500000, cad=97.199997, targetPosition=1207.000000, (7)(5) + 133406 [1383566][E](PTData): Cleaned 1 readings + 133407 [1383576][E](PTData): Existing entry averaged (7)(5)(1188), readings(20) + 133408 [1383578][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 133409 [1383589][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 133410 [1383590][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 3 + 133411 [1383601][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 133412 [1383607][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 133413 [1383609][E](PTable): New Entry Processed in 45 ms + 133414 [1383619][E](PTable): Power Buffer Reset + 133415 [1383620][E](ERG_Mode): Proportional: -3.750000 + 133416 [1384979][E](ERG_Mode): Watts previously processed. + 133417 [1386982][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 176, Cad 97, HR 140, Gear 0, Res 41, Current Pos 12164, Target Pos 12164 + 133418 [1387093][E](ERG_Mode): Watts previously processed. + 133419 [1389210][E](ERG_Mode): Watts previously processed. + 133420 [1389919][E](PTable): Averaged Entry: watts=161.899994, cad=95.900002, targetPosition=1217.099976, (7)(5) + 133421 [1389920][E](PTData): Cleaned 11 readings + 133422 [1389931][E](PTData): Existing entry averaged (7)(5)(1122), readings(20) + 133423 [1389931][E](PTData): Greater Down Found 8, 5, tp1126 + 133424 [1389941][E](PTData): Lower Up Found 6, 5, tp1115 + 133425 [1389942][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 133426 [1389944][E](PTable): New Entry Processed in 26 ms + 133427 [1389954][E](PTable): Power Buffer Reset + 133428 [1389954][E](ERG_Mode): Proportional: 3.750000 + 133429 [1391324][E](ERG_Mode): Watts previously processed. + 133430 [1392991][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 159, Cad 95, HR 139, Gear 0, Res 41, Current Pos 12318, Target Pos 12318 + 133431 [1394151][E](ERG_Mode): Watts previously processed. + 133432 [1395558][E](ERG_Mode): Proportional: 24.750000 + 133433 [1396268][E](PTable): Averaged Entry: watts=159.000000, cad=94.800003, targetPosition=1229.400024, (7)(5) + 133434 [1396269][E](PTData): Cleaned 1 readings + 133435 [1396279][E](PTData): Existing entry averaged (7)(5)(1123), readings(20) + 133436 [1396280][E](PTData): Greater Down Found 8, 5, tp1126 + 133437 [1396290][E](PTData): Lower Up Found 4, 5, tp1120 + 133438 [1396291][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 133439 [1396293][E](PTable): New Entry Processed in 26 ms + 133440 [1396303][E](PTable): Power Buffer Reset + 133441 [1396303][E](ERG_Mode): Watts previously processed. + 133442 [1396314][E](PTable): Using detected travel limits during homing + 133443 [1398387][E](ERG_Mode): Watts previously processed. + 133444 [1399009][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 155, Cad 93, HR 138, Gear 0, Res 41, Current Pos 12405, Target Pos 12405 + 133445 [1400502][E](ERG_Mode): Watts previously processed. + 133446 [1401205][E](ERG_Mode): Proportional: 6.750000 + 133447 [1402634][E](PTable): Averaged Entry: watts=162.000000, cad=93.099998, targetPosition=1242.000000, (7)(5) + 133448 [1402636][E](PTData): Cleaned 1 readings + 133449 [1402647][E](PTData): Existing entry averaged (7)(5)(1123), readings(20) + 133450 [1402647][E](PTData): Greater Down Found 8, 5, tp1126 + 133451 [1402658][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 133452 [1402660][E](PTable): New Entry Processed in 26 ms + 133453 [1402660][E](PTable): Power Buffer Reset + 133454 [1404049][E](ERG_Mode): Watts previously processed. + 133455 [1404792][E](FTMS_SERVER): 05 be 00 -> ERG Mode Target: 190 Current: 181 Incline: 124.370003. Responding: 80 05 01 + 133456 [1404798][E](DirConManager): Sending response message type 0x04 to client 0 + 133457 [1405024][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 181, Cad 94, HR 137, Gear 0, Res 42, Current Pos 12437, Target Pos 12437 + 133458 [1406167][E](ERG_Mode): Watts previously processed. + 133459 [1406868][E](ERG_Mode): Proportional: 6.000000 + 133460 [1408273][E](ERG_Mode): Watts previously processed. + 133461 [1408978][E](PTable): Averaged Entry: watts=178.000000, cad=95.000000, targetPosition=1244.900024, (7)(6) + 133462 [1408979][E](PTData): Existing entry averaged (7)(6)(1140), readings(12) + 133463 [1408989][E](PTData): Greater Down Found 8, 6, tp1141 + 133464 [1408990][E](PTData): Lower Up Found 6, 6, tp1129 + 133465 [1409001][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 133466 [1409002][E](PTable): New Entry Processed in 25 ms + 133467 [1409002][E](PTable): Power Buffer Reset + 133468 [1410387][E](ERG_Mode): Watts previously processed. + 133469 [1411037][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 179, Cad 97, HR 135, Gear 0, Res 42, Current Pos 12466, Target Pos 12466 + 133470 [1412503][E](ERG_Mode): Watts previously processed. + 133471 [1413204][E](ERG_Mode): Proportional: 4.500000 + 133472 [1414616][E](ERG_Mode): Watts previously processed. + 133473 [1415318][E](PTable): Averaged Entry: watts=181.100006, cad=96.400002, targetPosition=1249.800049, (7)(6) + 133474 [1415319][E](PTData): Cleaned 1 readings + 133475 [1415329][E](PTData): Existing entry averaged (7)(6)(1141), readings(12) + 133476 [1415330][E](PTData): Lower Up Found 5, 6, tp1130 + 133477 [1415340][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 0 ms + 133478 [1415342][E](PTable): New Entry Processed in 25 ms + 133479 [1415342][E](PTable): Power Buffer Reset + 133480 [1416018][E](ERG_Mode): Watts previously processed. + 133481 [1417053][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 188, Cad 96, HR 135, Gear 0, Res 42, Current Pos 12544, Target Pos 12544 + 133482 [1418136][E](ERG_Mode): Watts previously processed. + 133483 [1418843][E](ERG_Mode): Proportional: 4.500000 + 133484 [1420261][E](ERG_Mode): Watts previously processed. + 133485 [1421681][E](PTable): Averaged Entry: watts=184.100006, cad=96.000000, targetPosition=1254.599976, (7)(6) + 133486 [1421683][E](PTData): Cleaned 1 readings + 133487 [1421693][E](PTData): Existing entry averaged (7)(6)(1141), readings(12) + 133488 [1421693][E](PTData): Lower Up Found 4, 6, tp1137 + 133489 [1421704][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 0 ms + 133490 [1421706][E](PTable): New Entry Processed in 26 ms + 133491 [1421706][E](PTable): Power Buffer Reset + 133492 [1422388][E](ERG_Mode): Watts previously processed. + 133493 [1423076][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 180, Cad 96, HR 135, Gear 0, Res 42, Current Pos 12562, Target Pos 12562 + 133494 [1424509][E](ERG_Mode): Watts previously processed. + 133495 [1425212][E](ERG_Mode): Proportional: -22.500000 + 133496 [1428024][E](PTable): Averaged Entry: watts=184.800003, cad=96.099998, targetPosition=1256.900024, (7)(6) + 133497 [1428025][E](PTData): Cleaned 1 readings + 133498 [1428035][E](PTData): Existing entry averaged (7)(6)(1141), readings(12) + 133499 [1428036][E](PTData): PAVA iteration done, still converging: cad 0, watt 0, Loop 1 + 133500 [1428047][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 133501 [1428057][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 3 + 133502 [1428058][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 133503 [1428072][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 0 ms + 133504 [1428074][E](PTable): New Entry Processed in 51 ms + 133505 [1428074][E](PTable): Power Buffer Reset + 133506 [1428085][E](ERG_Mode): Watts previously processed. + 133507 [1429084][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 178, Cad 95, HR 134, Gear 0, Res 42, Current Pos 12631, Target Pos 12631 + 133508 [1430135][E](ERG_Mode): Watts previously processed. + 133509 [1430844][E](ERG_Mode): Proportional: 31.500000 + 133510 [1432247][E](ERG_Mode): Watts previously processed. + 133511 [1432248][E](PTable): Using detected travel limits during homing + 133512 [1434369][E](PTable): Averaged Entry: watts=175.100006, cad=93.699997, targetPosition=1268.300049, (7)(6) + 133513 [1434371][E](PTData): Cleaned 43 readings + 133514 [1434381][E](PTData): Existing entry averaged (7)(6)(1148), readings(13) + 133515 [1434381][E](PTData): Lower Right Found 7, 7, tp1147 + 133516 [1434392][E](PTData): Lower Up Found 6, 6, tp1136 + 133517 [1434392][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133518 [1434404][E](PTable): New Entry Processed in 35 ms + 133519 [1434404][E](PTable): Power Buffer Reset + 133520 [1434404][E](ERG_Mode): Watts previously processed. + 133521 [1434813][E](FTMS_SERVER): 05 cd 00 -> ERG Mode Target: 205 Current: 172 Incline: 128.000000. Responding: 80 05 01 + 133522 [1434821][E](DirConManager): Sending response message type 0x04 to client 0 + 133523 [1435097][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 172, Cad 91, HR 134, Gear 0, Res 43, Current Pos 12801, Target Pos 12874 + 133524 [1436478][E](ERG_Mode): Watts previously processed. + 133525 [1437187][E](ERG_Mode): Proportional: 33.750000 + 133526 [1440021][E](ERG_Mode): Watts previously processed. + 133527 [1440729][E](PTable): Averaged Entry: watts=186.899994, cad=92.699997, targetPosition=1293.599976, (6)(6) + 133528 [1440730][E](PTData): Cleaned 1 readings + 133529 [1440740][E](PTData): New entry recorded (6)(6)(1293) + 133530 [1440741][E](PTData): Lower Right Found 6, 7, tp1151 + 133531 [1440751][E](PTData): Lower Up Found 5, 6, tp1135 + 133532 [1440752][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133533 [1440753][E](PTable): New Entry Processed in 25 ms + 133534 [1440822][E](PTable): Writing File: /PowerTable.txt + 133535 [1441069][E](PTable): Power table saved successfully with 293 readings + 133536 [1441069][E](PTable): Power Buffer Reset + 133537 [1441108][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 199, Cad 94, HR 133, Gear 0, Res 44, Current Pos 13016, Target Pos 13019 + 133538 [1441432][E](ERG_Mode): Watts previously processed. + 133539 [1442851][E](ERG_Mode): Proportional: 6.000000 + 133540 [1443558][E](ERG_Mode): Watts previously processed. + 133541 [1444968][E](ERG_Mode): Watts previously processed. + 133542 [1445674][E](ERG_Mode): Watts previously processed. + 133543 [1447082][E](PTable): Averaged Entry: watts=196.300003, cad=93.300003, targetPosition=1303.199951, (7)(7) + 133544 [1447084][E](PTData): Cleaned 2 readings + 133545 [1447094][E](PTData): Existing entry averaged (7)(7)(1173), readings(5) + 133546 [1447094][E](PTData): Lower Up Found 4, 7, tp1155 + 133547 [1447105][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133548 [1447107][E](PTable): New Entry Processed in 25 ms + 133549 [1447107][E](PTable): Power Buffer Reset + 133550 [1447117][E](ERG_Mode): Watts previously processed. + 133551 [1447118][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 196, Cad 93, HR 133, Gear 0, Res 44, Current Pos 13061, Target Pos 13061 + 133552 [1448494][E](ERG_Mode): Proportional: 0.000000 + 133553 [1449201][E](ERG_Mode): Watts previously processed. + 133554 [1451318][E](ERG_Mode): Watts previously processed. + 133555 [1453142][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 202, Cad 93, HR 134, Gear 0, Res 44, Current Pos 13074, Target Pos 13074 + 133556 [1453446][E](PTable): Averaged Entry: watts=201.699997, cad=93.599998, targetPosition=1306.199951, (7)(7) + 133557 [1453448][E](PTData): Cleaned 1 readings + 133558 [1453458][E](PTData): Existing entry averaged (7)(7)(1173), readings(5) + 133559 [1453458][E](PTData): Lower Up Found 3, 7, tp1159 + 133560 [1453469][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133561 [1453471][E](PTable): New Entry Processed in 25 ms + 133562 [1453471][E](PTable): Power Buffer Reset + 133563 [1453481][E](ERG_Mode): Watts previously processed. + 133564 [1454154][E](ERG_Mode): Proportional: 27.000000 + 133565 [1455557][E](ERG_Mode): Watts previously processed. + 133566 [1458375][E](ERG_Mode): Watts previously processed. + 133567 [1459156][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 188, Cad 91, HR 134, Gear 0, Res 44, Current Pos 13204, Target Pos 13232 + 133568 [1459795][E](PTable): Averaged Entry: watts=192.899994, cad=91.800003, targetPosition=1314.199951, (6)(6) + 133569 [1459797][E](PTData): Cleaned 1 readings + 133570 [1459807][E](PTData): New entry recorded (6)(6)(1314) + 133571 [1459807][E](PTData): Lower Right Found 6, 8, tp1172 + 133572 [1459818][E](PTData): Lower Up Found 4, 6, tp1134 + 133573 [1459818][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133574 [1459820][E](PTable): New Entry Processed in 25 ms + 133575 [1459830][E](PTable): Power Buffer Reset + 133576 [1459830][E](ERG_Mode): Proportional: 24.750000 + 133577 [1461209][E](ERG_Mode): Watts previously processed. + 133578 [1463329][E](ERG_Mode): Watts previously processed. + 133579 [1464882][E](FTMS_SERVER): 05 e1 00 -> ERG Mode Target: 225 Current: 222 Incline: 131.529999. Responding: 80 05 01 + 133580 [1464890][E](DirConManager): Sending response message type 0x04 to client 0 + 133581 [1465167][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 222, Cad 95, HR 135, Gear 0, Res 44, Current Pos 13153, Target Pos 13153 + 133582 [1465455][E](ERG_Mode): Proportional: 2.250000 + 133583 [1466163][E](PTable): Averaged Entry: watts=214.199997, cad=93.099998, targetPosition=1322.000000, (7)(7) + 133584 [1466164][E](PTData): Cleaned 2 readings + 133585 [1466174][E](PTData): Existing entry averaged (7)(7)(1176), readings(5) + 133586 [1466175][E](PTData): Lower Up Found 2, 7, tp1166 + 133587 [1466185][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133588 [1466187][E](PTable): New Entry Processed in 25 ms + 133589 [1466187][E](PTable): Power Buffer Reset + 133590 [1468283][E](ERG_Mode): Watts previously processed. + 133591 [1468284][E](PTable): Using detected travel limits during homing + 133592 [1470404][E](ERG_Mode): Watts previously processed. + 133593 [1471114][E](ERG_Mode): Proportional: 31.500000 + 133594 [1471177][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 211, Cad 95, HR 136, Gear 0, Res 44, Current Pos 13178, Target Pos 13202 + 133595 [1472519][E](PTable): Averaged Entry: watts=216.600006, cad=95.500000, targetPosition=1317.000000, (7)(7) + 133596 [1472520][E](PTData): Cleaned 1 readings + 133597 [1472530][E](PTData): Existing entry averaged (7)(7)(1175), readings(5) + 133598 [1472531][E](PTData): Lower Up Found 1, 7, tp1174 + 133599 [1472541][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133600 [1472543][E](PTable): New Entry Processed in 25 ms + 133601 [1472543][E](PTable): Power Buffer Reset + 133602 [1472554][E](ERG_Mode): Watts previously processed. + 133603 [1474639][E](ERG_Mode): Watts previously processed. + 133604 [1476759][E](ERG_Mode): Proportional: 22.500000 + 133605 [1477195][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 215, Cad 94, HR 137, Gear 0, Res 44, Current Pos 13321, Target Pos 13321 + 133606 [1478169][E](ERG_Mode): Watts previously processed. + 133607 [1478871][E](PTable): Averaged Entry: watts=218.699997, cad=94.099998, targetPosition=1328.000000, (7)(7) + 133608 [1478873][E](PTData): Cleaned 1 readings + 133609 [1478883][E](PTData): Existing entry averaged (7)(7)(1177), readings(5) + 133610 [1478884][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 133611 [1478894][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 133612 [1478905][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 3 + 133613 [1478906][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133614 [1478920][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133615 [1478921][E](PTable): New Entry Processed in 50 ms + 133616 [1478922][E](PTable): Power Buffer Reset + 133617 [1480283][E](ERG_Mode): Watts previously processed. + 133618 [1482401][E](ERG_Mode): Watts previously processed. + 133619 [1483112][E](ERG_Mode): Proportional: 27.000000 + 133620 [1483205][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 213, Cad 94, HR 138, Gear 0, Res 45, Current Pos 13339, Target Pos 13351 + 133621 [1484517][E](ERG_Mode): Watts previously processed. + 133622 [1485226][E](PTable): Averaged Entry: watts=219.500000, cad=94.300003, targetPosition=1332.900024, (7)(7) + 133623 [1485228][E](PTData): Cleaned 1 readings + 133624 [1485238][E](PTData): Existing entry averaged (7)(7)(1193), readings(6) + 133625 [1485238][E](PTData): Lower Right Found 7, 8, tp1183 + 133626 [1485249][E](PTData): Lower Up Found 6, 7, tp1171 + 133627 [1485250][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133628 [1485261][E](PTable): New Entry Processed in 35 ms + 133629 [1485261][E](PTable): Power Buffer Reset + 133630 [1486635][E](ERG_Mode): Watts previously processed. + 133631 [1488747][E](ERG_Mode): Proportional: 29.250000 + 133632 [1489214][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 212, Cad 93, HR 138, Gear 0, Res 45, Current Pos 13464, Target Pos 13464 + 133633 [1490151][E](ERG_Mode): Watts previously processed. + 133634 [1491568][E](PTable): Averaged Entry: watts=214.000000, cad=92.800003, targetPosition=1343.599976, (6)(7) + 133635 [1491569][E](PTData): Cleaned 2 readings + 133636 [1491579][E](PTData): New entry recorded (6)(7)(1343) + 133637 [1491579][E](PTData): Lower Right Found 6, 8, tp1188 + 133638 [1491590][E](PTData): Lower Up Found 5, 7, tp1175 + 133639 [1491591][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133640 [1491592][E](PTable): New Entry Processed in 25 ms + 133641 [1491602][E](PTable): Power Buffer Reset + 133642 [1492274][E](ERG_Mode): Watts previously processed. + 133643 [1494403][E](ERG_Mode): Watts previously processed. + 133644 [1494795][E](FTMS_SERVER): 05 f0 00 -> ERG Mode Target: 240 Current: 228 Incline: 135.259995. Responding: 80 05 01 + 133645 [1494803][E](DirConManager): Sending response message type 0x04 to client 0 + 133646 [1495107][E](ERG_Mode): Proportional: 27.000000 + 133647 [1495230][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 228, Cad 93, HR 139, Gear 0, Res 45, Current Pos 13548, Target Pos 13553 + 133648 [1496512][E](ERG_Mode): Watts previously processed. + 133649 [1497926][E](PTable): Averaged Entry: watts=224.600006, cad=93.000000, targetPosition=1354.800049, (7)(7) + 133650 [1497928][E](PTData): Cleaned 2 readings + 133651 [1497938][E](PTData): Existing entry averaged (7)(7)(1196), readings(6) + 133652 [1497938][E](PTData): Lower Up Found 4, 7, tp1179 + 133653 [1497950][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133654 [1497951][E](PTable): New Entry Processed in 25 ms + 133655 [1497952][E](PTable): Power Buffer Reset + 133656 [1498630][E](ERG_Mode): Watts previously processed. + 133657 [1500755][E](ERG_Mode): Proportional: 38.250000 + 133658 [1501239][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 223, Cad 92, HR 140, Gear 0, Res 46, Current Pos 13729, Target Pos 13729 + 133659 [1502158][E](ERG_Mode): Watts previously processed. + 133660 [1504279][E](PTable): Averaged Entry: watts=224.300003, cad=92.800003, targetPosition=1370.900024, (6)(7) + 133661 [1504280][E](PTData): Cleaned 1 readings + 133662 [1504290][E](PTData): New entry recorded (6)(7)(1370) + 133663 [1504290][E](PTData): Lower Right Found 6, 9, tp1208 + 133664 [1504291][E](PTData): Lower Up Found 3, 7, tp1183 + 133665 [1504302][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133666 [1504303][E](PTable): New Entry Processed in 25 ms + 133667 [1504313][E](PTable): Power Buffer Reset + 133668 [1504314][E](ERG_Mode): Watts previously processed. + 133669 [1504314][E](PTable): Using detected travel limits during homing + 133670 [1506393][E](ERG_Mode): Watts previously processed. + 133671 [1507101][E](ERG_Mode): Proportional: 6.750000 + 133672 [1507257][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 231, Cad 92, HR 141, Gear 0, Res 46, Current Pos 13868, Target Pos 13868 + 133673 [1508505][E](ERG_Mode): Watts previously processed. + 133674 [1510626][E](PTable): Averaged Entry: watts=237.199997, cad=91.900002, targetPosition=1386.300049, (6)(8) + 133675 [1510628][E](PTData): Cleaned 2 readings + 133676 [1510638][E](PTData): New entry recorded (6)(8)(1386) + 133677 [1510639][E](PTData): Lower Right Found 6, 10, tp1233 + 133678 [1510649][E](PTData): Lower Up Found 5, 8, tp1192 + 133679 [1510650][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133680 [1510651][E](PTable): New Entry Processed in 25 ms + 133681 [1510662][E](PTable): Power Buffer Reset + 133682 [1511332][E](ERG_Mode): Watts previously processed. + 133683 [1512745][E](ERG_Mode): Proportional: 6.750000 + 133684 [1513271][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 231, Cad 91, HR 141, Gear 0, Res 47, Current Pos 13915, Target Pos 13915 + 133685 [1514159][E](ERG_Mode): Watts previously processed. + 133686 [1516280][E](ERG_Mode): Watts previously processed. + 133687 [1516989][E](PTable): Averaged Entry: watts=233.600006, cad=91.500000, targetPosition=1390.900024, (6)(8) + 133688 [1516991][E](PTData): Cleaned 2 readings + 133689 [1517001][E](PTData): New entry recorded (6)(8)(1390) + 133690 [1517001][E](PTData): Lower Right Found 6, 11, tp1259 + 133691 [1517001][E](PTData): Lower Up Found 4, 8, tp1196 + 133692 [1517012][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133693 [1517014][E](PTable): New Entry Processed in 26 ms + 133694 [1517024][E](PTable): Power Buffer Reset + 133695 [1518400][E](ERG_Mode): Watts previously processed. + 133696 [1519110][E](ERG_Mode): Proportional: 22.500000 + 133697 [1519286][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 230, Cad 90, HR 142, Gear 0, Res 47, Current Pos 13979, Target Pos 13979 + 133698 [1520516][E](ERG_Mode): Watts previously processed. + 133699 [1522630][E](ERG_Mode): Watts previously processed. + 133700 [1523339][E](PTable): Averaged Entry: watts=235.300003, cad=90.099998, targetPosition=1396.699951, (6)(8) + 133701 [1523340][E](PTData): Cleaned 2 readings + 133702 [1523350][E](PTData): New entry recorded (6)(8)(1396) + 133703 [1523351][E](PTData): Lower Right Found 6, 12, tp1284 + 133704 [1523361][E](PTData): Lower Up Found 3, 8, tp1202 + 133705 [1523362][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133706 [1523363][E](PTable): New Entry Processed in 25 ms + 133707 [1523374][E](PTable): Power Buffer Reset + 133708 [1524753][E](ERG_Mode): Proportional: -4.500000 + 133709 [1524788][E](FTMS_SERVER): 05 04 01 -> ERG Mode Target: 260 Current: 246 Incline: 139.809998. Responding: 80 05 01 + 133710 [1524795][E](DirConManager): Sending response message type 0x04 to client 0 + 133711 [1525302][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 246, Cad 91, HR 144, Gear 0, Res 47, Current Pos 13981, Target Pos 13981 + 133712 [1528288][E](ERG_Mode): Watts previously processed. + 133713 [1529702][E](PTable): Averaged Entry: watts=244.899994, cad=91.400002, targetPosition=1402.900024, (6)(8) + 133714 [1529704][E](PTData): Cleaned 2 readings + 133715 [1529714][E](PTData): New entry recorded (6)(8)(1402) + 133716 [1529714][E](PTData): Lower Right Found 6, 13, tp1310 + 133717 [1529725][E](PTData): Lower Up Found 2, 8, tp1209 + 133718 [1529725][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133719 [1529727][E](PTable): New Entry Processed in 25 ms + 133720 [1529737][E](PTable): Power Buffer Reset + 133721 [1530408][E](ERG_Mode): Watts previously processed. + 133722 [1531111][E](ERG_Mode): Proportional: 1.500000 + 133723 [1531317][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 258, Cad 93, HR 144, Gear 0, Res 47, Current Pos 14124, Target Pos 14124 + 133724 [1532517][E](ERG_Mode): Watts previously processed. + 133725 [1535341][E](ERG_Mode): Watts previously processed. + 133726 [1536045][E](PTable): Averaged Entry: watts=253.500000, cad=92.400002, targetPosition=1414.099976, (6)(8) + 133727 [1536047][E](PTData): Cleaned 2 readings + 133728 [1536057][E](PTData): New entry recorded (6)(8)(1414) + 133729 [1536058][E](PTData): Lower Right Found 6, 14, tp1336 + 133730 [1536068][E](PTData): Lower Up Found 1, 8, tp1218 + 133731 [1536069][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133732 [1536070][E](PTable): New Entry Processed in 25 ms + 133733 [1536080][E](PTable): Power Buffer Reset + 133734 [1536753][E](ERG_Mode): Proportional: -4.500000 + 133735 [1537330][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 266, Cad 92, HR 145, Gear 0, Res 48, Current Pos 14209, Target Pos 14209 + 133736 [1537461][E](ERG_Mode): Watts previously processed. + 133737 [1539571][E](ERG_Mode): Watts previously processed. + 133738 [1540281][E](PTable): Using detected travel limits during homing + 133739 [1542403][E](PTable): Averaged Entry: watts=264.700012, cad=94.099998, targetPosition=1416.400024, (7)(9) + 133740 [1542404][E](PTData): Cleaned 2 readings + 133741 [1542414][E](PTData): Existing entry averaged (7)(9)(1310), readings(1) + 133742 [1542415][E](PTData): Lower Right Found 7, 10, tp1229 + 133743 [1542425][E](PTData): Lower Up Found 5, 9, tp1215 + 133744 [1542425][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133745 [1542437][E](PTable): New Entry Processed in 35 ms + 133746 [1542437][E](PTable): Power Buffer Reset + 133747 [1542437][E](ERG_Mode): Watts previously processed. + 133748 [1543103][E](ERG_Mode): Proportional: -6.750000 + 133749 [1543339][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 269, Cad 94, HR 147, Gear 0, Res 47, Current Pos 14147, Target Pos 14147 + 133750 [1545215][E](ERG_Mode): Watts previously processed. + 133751 [1547329][E](ERG_Mode): Watts previously processed. + 133752 [1548744][E](PTable): Averaged Entry: watts=254.300003, cad=93.300003, targetPosition=1416.500000, (7)(8) + 133753 [1548745][E](PTData): Cleaned 2 readings + 133754 [1548755][E](PTData): New entry recorded (7)(8)(1416) + 133755 [1548755][E](PTData): Lower Right Found 7, 9, tp1204 + 133756 [1548766][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133757 [1548768][E](PTable): New Entry Processed in 25 ms + 133758 [1548768][E](PTable): Power Buffer Reset + 133759 [1548778][E](ERG_Mode): Proportional: 38.250000 + 133760 [1549351][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 243, Cad 93, HR 148, Gear 0, Res 48, Current Pos 14244, Target Pos 14244 + 133761 [1549452][E](ERG_Mode): Watts previously processed. + 133762 [1551571][E](ERG_Mode): Watts previously processed. + 133763 [1553682][E](ERG_Mode): Watts previously processed. + 133764 [1554392][E](ERG_Mode): Proportional: -31.500000 + 133765 [1554822][E](FTMS_SERVER): 05 1d 01 -> ERG Mode Target: 285 Current: 273 Incline: 141.910004. Responding: 80 05 01 + 133766 [1554829][E](DirConManager): Sending response message type 0x04 to client 0 + 133767 [1555094][E](PTable): Averaged Entry: watts=259.100006, cad=93.199997, targetPosition=1423.099976, (7)(9) + 133768 [1555095][E](PTData): Cleaned 1 readings + 133769 [1555105][E](PTData): New entry recorded (7)(9)(1423) + 133770 [1555105][E](PTData): Lower Right Found 7, 11, tp1255 + 133771 [1555116][E](PTData): Lower Up Found 4, 9, tp1220 + 133772 [1555116][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133773 [1555118][E](PTable): New Entry Processed in 25 ms + 133774 [1555128][E](PTable): Power Buffer Reset + 133775 [1555129][E](ERG_Mode): SetPoint changed:255w Waiting:1326ms PowerTable Result: 12000 + 133776 [1555359][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 273, Cad 95, HR 149, Gear 0, Res 47, Current Pos 14114, Target Pos 12000 + 133777 [1557823][E](ERG_Mode): ERG wait expired, pos: 12000, tgt: 0 + 133778 [1559241][E](ERG_Mode): Watts previously processed. + 133779 [1559949][E](ERG_Mode): Proportional: 431.250000 + 133780 [1561355][E](ERG_Mode): Watts previously processed. + 133781 [1561376][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 175, Cad 100, HR 149, Gear 0, Res 44, Current Pos 13368, Target Pos 13369 + 133782 [1563481][E](PTable): Averaged Entry: watts=195.899994, cad=99.500000, targetPosition=1282.900024, (8)(7) + 133783 [1563483][E](PTData): Cleaned 2 readings + 133784 [1563493][E](PTData): Existing entry averaged (8)(7)(1218), readings(1) + 133785 [1563493][E](PTData): Lower Right Found 8, 8, tp1176 + 133786 [1563504][E](PTData): Lower Up Found 7, 7, tp1170 + 133787 [1563504][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133788 [1563516][E](PTable): New Entry Processed in 35 ms + 133789 [1563516][E](PTable): Power Buffer Reset + 133790 [1563516][E](ERG_Mode): Watts previously processed. + 133791 [1565599][E](ERG_Mode): Watts previously processed. + 133792 [1566302][E](ERG_Mode): Proportional: 156.000000 + 133793 [1567394][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 252, Cad 96, HR 150, Gear 0, Res 48, Current Pos 14215, Target Pos 14215 + 133794 [1567715][E](ERG_Mode): Watts previously processed. + 133795 [1569828][E](PTable): Averaged Entry: watts=250.899994, cad=96.699997, targetPosition=1404.599976, (7)(8) + 133796 [1569829][E](PTData): Cleaned 1 readings + 133797 [1569840][E](PTData): New entry recorded (7)(8)(1404) + 133798 [1569840][E](PTData): Lower Right Found 7, 12, tp1278 + 133799 [1569851][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133800 [1569852][E](PTable): New Entry Processed in 25 ms + 133801 [1569852][E](PTable): Power Buffer Reset + 133802 [1571238][E](ERG_Mode): Watts previously processed. + 133803 [1571949][E](ERG_Mode): Proportional: 78.750000 + 133804 [1573352][E](ERG_Mode): Watts previously processed. + 133805 [1573404][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 254, Cad 91, HR 149, Gear 0, Res 49, Current Pos 14577, Target Pos 14577 + 133806 [1575472][E](ERG_Mode): Watts previously processed. + 133807 [1576189][E](PTable): Averaged Entry: watts=258.500000, cad=92.300003, targetPosition=1451.900024, (6)(9) + 133808 [1576191][E](PTData): Cleaned 1 readings + 133809 [1576202][E](PTData): New entry recorded (6)(9)(1451) + 133810 [1576202][E](PTData): Lower Right Found 6, 15, tp1363 + 133811 [1576202][E](PTData): Lower Up Found 3, 9, tp1226 + 133812 [1576213][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133813 [1576214][E](PTable): New Entry Processed in 25 ms + 133814 [1576224][E](PTable): Power Buffer Reset + 133815 [1577602][E](ERG_Mode): Watts previously processed. + 133816 [1578303][E](ERG_Mode): Proportional: 31.500000 + 133817 [1578305][E](PTable): Using detected travel limits during homing + 133818 [1579416][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 266, Cad 91, HR 150, Gear 0, Res 50, Current Pos 14826, Target Pos 14826 + 133819 [1579709][E](ERG_Mode): Watts previously processed. + 133820 [1581115][E](ERG_Mode): Watts previously processed. + 133821 [1582535][E](PTable): Averaged Entry: watts=276.700012, cad=90.900002, targetPosition=1476.599976, (6)(9) + 133822 [1582537][E](PTData): Cleaned 2 readings + 133823 [1582547][E](PTData): New entry recorded (6)(9)(1476) + 133824 [1582547][E](PTData): Lower Right Found 6, 16, tp1389 + 133825 [1582558][E](PTData): Lower Up Found 2, 9, tp1234 + 133826 [1582558][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133827 [1582560][E](PTable): New Entry Processed in 25 ms + 133828 [1582570][E](PTable): Power Buffer Reset + 133829 [1583242][E](ERG_Mode): Watts previously processed. + 133830 [1583951][E](ERG_Mode): Proportional: 67.500000 + 133831 [1585358][E](ERG_Mode): Watts previously processed. + 133832 [1585430][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 255, Cad 88, HR 150, Gear 0, Res 50, Current Pos 14987, Target Pos 14987 + 133833 [1587476][E](ERG_Mode): Watts previously processed. + 133834 [1588894][E](PTable): Averaged Entry: watts=270.399994, cad=89.000000, targetPosition=1493.900024, (6)(9) + 133835 [1588895][E](PTData): Cleaned 2 readings + 133836 [1588905][E](PTData): New entry recorded (6)(9)(1493) + 133837 [1588905][E](PTData): Lower Right Found 6, 17, tp1417 + 133838 [1588916][E](PTData): Lower Up Found 1, 9, tp1243 + 133839 [1588916][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133840 [1588918][E](PTable): New Entry Processed in 25 ms + 133841 [1588928][E](PTable): Power Buffer Reset + 133842 [1589598][E](ERG_Mode): Watts previously processed. + 133843 [1590308][E](ERG_Mode): Proportional: 60.750000 + 133844 [1591438][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 258, Cad 86, HR 149, Gear 0, Res 51, Current Pos 15152, Target Pos 15152 + 133845 [1591722][E](ERG_Mode): Watts previously processed. + 133846 [1593131][E](ERG_Mode): Watts previously processed. + 133847 [1595252][E](PTable): Averaged Entry: watts=274.000000, cad=87.900002, targetPosition=1509.500000, (5)(9) + 133848 [1595254][E](PTData): Cleaned 2 readings + 133849 [1595264][E](PTData): New entry recorded (5)(9)(1509) + 133850 [1595264][E](PTData): Lower Right Found 5, 10, tp1240 + 133851 [1595275][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133852 [1595277][E](PTable): New Entry Processed in 25 ms + 133853 [1595277][E](PTable): Power Buffer Reset + 133854 [1595287][E](ERG_Mode): Watts previously processed. + 133855 [1595957][E](ERG_Mode): Proportional: 36.000000 + 133856 [1597360][E](ERG_Mode): Watts previously processed. + 133857 [1597452][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 271, Cad 86, HR 150, Gear 0, Res 51, Current Pos 15197, Target Pos 15197 + 133858 [1599476][E](ERG_Mode): Watts previously processed. + 133859 [1601589][E](PTable): Averaged Entry: watts=281.500000, cad=87.000000, targetPosition=1517.400024, (5)(9) + 133860 [1601590][E](PTData): Cleaned 1 readings + 133861 [1601600][E](PTData): New entry recorded (5)(9)(1517) + 133862 [1601600][E](PTData): Lower Right Found 5, 11, tp1264 + 133863 [1601611][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133864 [1601613][E](PTable): New Entry Processed in 25 ms + 133865 [1601613][E](PTable): Power Buffer Reset + 133866 [1601623][E](ERG_Mode): Watts previously processed. + 133867 [1602299][E](ERG_Mode): Proportional: 0.000000 + 133868 [1603462][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 279, Cad 87, HR 152, Gear 0, Res 51, Current Pos 15212, Target Pos 15212 + 133869 [1605134][E](ERG_Mode): Watts previously processed. + 133870 [1607253][E](ERG_Mode): Watts previously processed. + 133871 [1607961][E](PTable): Averaged Entry: watts=278.799988, cad=87.199997, targetPosition=1520.599976, (5)(9) + 133872 [1607962][E](PTData): Cleaned 1 readings + 133873 [1607972][E](PTData): New entry recorded (5)(9)(1520) + 133874 [1607973][E](PTData): Lower Right Found 5, 12, tp1288 + 133875 [1607983][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133876 [1607985][E](PTable): New Entry Processed in 25 ms + 133877 [1607985][E](PTable): Power Buffer Reset + 133878 [1607995][E](ERG_Mode): Proportional: 24.750000 + 133879 [1609374][E](ERG_Mode): Watts previously processed. + 133880 [1609476][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 279, Cad 86, HR 154, Gear 0, Res 51, Current Pos 15257, Target Pos 15257 + 133881 [1611497][E](ERG_Mode): Watts previously processed. + 133882 [1613612][E](ERG_Mode): Watts previously processed. + 133883 [1614320][E](PTable): Averaged Entry: watts=291.500000, cad=86.800003, targetPosition=1523.000000, (5)(10) + 133884 [1614321][E](PTData): Cleaned 1 readings + 133885 [1614331][E](PTData): New entry recorded (5)(10)(1523) + 133886 [1614332][E](PTData): Lower Right Found 5, 13, tp1314 + 133887 [1614342][E](PTData): Lower Up Found 4, 10, tp1244 + 133888 [1614343][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133889 [1614344][E](PTable): New Entry Processed in 25 ms + 133890 [1614354][E](PTable): Power Buffer Reset + 133891 [1614355][E](ERG_Mode): Proportional: -83.250000 + 133892 [1614355][E](PTable): Using detected travel limits during homing + 133893 [1615489][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 294, Cad 91, HR 155, Gear 0, Res 50, Current Pos 15031, Target Pos 15031 + 133894 [1616435][E](ERG_Mode): Watts previously processed. + 133895 [1618551][E](ERG_Mode): Watts previously processed. + 133896 [1619959][E](ERG_Mode): Proportional: 22.500000 + 133897 [1620667][E](PTable): Averaged Entry: watts=288.799988, cad=89.199997, targetPosition=1505.500000, (6)(10) + 133898 [1620668][E](PTData): Cleaned 2 readings + 133899 [1620678][E](PTData): New entry recorded (6)(10)(1505) + 133900 [1620679][E](PTData): Lower Right Found 6, 18, tp1445 + 133901 [1620689][E](PTData): Lower Up Found 3, 10, tp1251 + 133902 [1620690][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133903 [1620691][E](PTable): New Entry Processed in 25 ms + 133904 [1620702][E](PTable): Power Buffer Reset + 133905 [1620702][E](ERG_Mode): Watts previously processed. + 133906 [1621504][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 278, Cad 88, HR 157, Gear 0, Res 51, Current Pos 15098, Target Pos 15098 + 133907 [1622785][E](ERG_Mode): Watts previously processed. + 133908 [1625620][E](ERG_Mode): Watts previously processed. + 133909 [1626329][E](ERG_Mode): Proportional: -56.250000 + 133910 [1627029][E](PTable): Averaged Entry: watts=290.100006, cad=89.500000, targetPosition=1508.500000, (6)(10) + 133911 [1627031][E](PTData): Cleaned 2 readings + 133912 [1627041][E](PTData): New entry recorded (6)(10)(1508) + 133913 [1627041][E](PTData): Lower Right Found 6, 19, tp1475 + 133914 [1627052][E](PTData): Lower Up Found 2, 10, tp1259 + 133915 [1627052][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133916 [1627054][E](PTable): New Entry Processed in 25 ms + 133917 [1627064][E](PTable): Power Buffer Reset + 133918 [1627535][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 307, Cad 95, HR 158, Gear 0, Res 50, Current Pos 14934, Target Pos 14934 + 133919 [1628442][E](ERG_Mode): Watts previously processed. + 133920 [1630556][E](ERG_Mode): Watts previously processed. + 133921 [1631963][E](ERG_Mode): Proportional: -3.000000 + 133922 [1632670][E](ERG_Mode): Watts previously processed. + 133923 [1633379][E](PTable): Averaged Entry: watts=297.299988, cad=93.099998, targetPosition=1487.300049, (7)(10) + 133924 [1633380][E](PTData): Cleaned 2 readings + 133925 [1633390][E](PTData): New entry recorded (7)(10)(1487) + 133926 [1633390][E](PTData): Lower Right Found 7, 13, tp1304 + 133927 [1633401][E](PTData): Lower Up Found 1, 10, tp1268 + 133928 [1633401][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133929 [1633403][E](PTable): New Entry Processed in 25 ms + 133930 [1633413][E](PTable): Power Buffer Reset + 133931 [1633546][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 301, Cad 93, HR 159, Gear 0, Res 50, Current Pos 14820, Target Pos 14811 + 133932 [1634781][E](ERG_Mode): Watts previously processed. + 133933 [1637603][E](ERG_Mode): Proportional: 22.500000 + 133934 [1638305][E](ERG_Mode): Watts previously processed. + 133935 [1639558][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 221, Cad 87, HR 159, Gear 0, Res 50, Current Pos 14941, Target Pos 14941 + 133936 [1639733][E](PTable): Averaged Entry: watts=276.600006, cad=92.000000, targetPosition=1479.000000, (6)(9) + 133937 [1639734][E](PTData): Cleaned 2 readings + 133938 [1639744][E](PTData): New entry recorded (6)(9)(1479) + 133939 [1639745][E](PTData): PAVA iteration done, still converging: cad 0, watt 0, Loop 1 + 133940 [1639755][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 133941 [1639756][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 3 + 133942 [1639767][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133943 [1639772][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 133944 [1639784][E](PTable): New Entry Processed in 52 ms + 133945 [1639784][E](PTable): Power Buffer Reset + 133946 [1640436][E](ERG_Mode): Watts previously processed. + 133947 [1642542][E](ERG_Mode): Watts previously processed. + 133948 [1643251][E](ERG_Mode): Proportional: 159.000000 + 133949 [1644665][E](ERG_Mode): Watts previously processed. + 133950 [1645575][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 231, Cad 79, HR 158, Gear 0, Res 53, Current Pos 15922, Target Pos 16018 + 133951 [1646082][E](PTable): Averaged Entry: watts=226.100006, cad=80.900002, targetPosition=1551.800049, (4)(8) + 133952 [1646083][E](PTData): Existing entry averaged (4)(8)(1387), readings(1) + 133953 [1646093][E](PTData): Lower Right Found 4, 9, tp1256 + 133954 [1646094][E](PTData): Lower Up Found 3, 8, tp1228 + 133955 [1646104][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133956 [1646106][E](PTable): New Entry Processed in 25 ms + 133957 [1646106][E](PTable): Power Buffer Reset + 133958 [1646786][E](ERG_Mode): Watts previously processed. + 133959 [1647320][E](BLE_Server): Client ID: 2 Address: 73:2a:a3:1b:05:18 Unsubscribed to 0x2ad9 + 133960 [1647321][E](BLE_Server): Client ID: 2 Address: 73:2a:a3:1b:05:18 Unsubscribed to 0x2ad2 + 133961 [1648192][E](ERG_Mode): Watts previously processed. + 133962 [1648899][E](ERG_Mode): Proportional: 63.000000 + 133963 [1650305][E](ERG_Mode): Watts previously processed. + 133964 [1650306][E](PTable): Using detected travel limits during homing + 133965 [1651593][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 252, Cad 73, HR 157, Gear 0, Res 55, Current Pos 16387, Target Pos 16387 + 133966 [1652431][E](PTable): Averaged Entry: watts=251.600006, cad=75.199997, targetPosition=1623.900024, (3)(8) + 133967 [1652432][E](PTData): Cleaned 2 readings + 133968 [1652442][E](PTData): New entry recorded (3)(8)(1623) + 133969 [1652442][E](PTData): Lower Right Found 3, 9, tp1259 + 133970 [1652453][E](PTData): Lower Up Found 2, 8, tp1232 + 133971 [1652453][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133972 [1652455][E](PTable): New Entry Processed in 25 ms + 133973 [1652465][E](PTable): Power Buffer Reset + 133974 [1652465][E](ERG_Mode): Watts previously processed. + 133975 [1654549][E](ERG_Mode): Watts previously processed. + 133976 [1655260][E](ERG_Mode): Proportional: 76.500000 + 133977 [1656674][E](ERG_Mode): Watts previously processed. + 133978 [1657602][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 252, Cad 70, HR 157, Gear 0, Res 56, Current Pos 16850, Target Pos 16860 + 133979 [1658783][E](PTable): Averaged Entry: watts=249.899994, cad=70.900002, targetPosition=1667.099976, (2)(8) + 133980 [1658785][E](PTData): Cleaned 2 readings + 133981 [1658795][E](PTData): New entry recorded (2)(8)(1667) + 133982 [1658795][E](PTData): Lower Right Found 2, 9, tp1263 + 133983 [1658806][E](PTData): Lower Up Found 1, 8, tp1236 + 133984 [1658806][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133985 [1658808][E](PTable): New Entry Processed in 25 ms + 133986 [1658818][E](PTable): Power Buffer Reset + 133987 [1658818][E](ERG_Mode): Watts previously processed. + 133988 [1660190][E](ERG_Mode): Watts previously processed. + 133989 [1660896][E](ERG_Mode): Proportional: 74.250000 + 133990 [1662299][E](ERG_Mode): Watts previously processed. + 133991 [1663611][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 255, Cad 68, HR 156, Gear 0, Res 58, Current Pos 17213, Target Pos 17213 + 133992 [1664417][E](ERG_Mode): Watts previously processed. + 133993 [1665125][E](PTable): Averaged Entry: watts=258.200012, cad=68.900002, targetPosition=1708.800049, (2)(9) + 133994 [1665126][E](PTData): Cleaned 2 readings + 133995 [1665136][E](PTData): New entry recorded (2)(9)(1708) + 133996 [1665136][E](PTData): Lower Right Found 2, 10, tp1285 + 133997 [1665147][E](PTData): Lower Up Found 1, 9, tp1268 + 133998 [1665147][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 133999 [1665149][E](PTable): New Entry Processed in 25 ms + 134000 [1665159][E](PTable): Power Buffer Reset + 134001 [1666538][E](ERG_Mode): Watts previously processed. + 134002 [1667245][E](ERG_Mode): Proportional: 56.250000 + 134003 [1668647][E](ERG_Mode): Watts previously processed. + 134004 [1669628][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 252, Cad 67, HR 155, Gear 0, Res 58, Current Pos 17506, Target Pos 17508 + 134005 [1671484][E](PTable): Averaged Entry: watts=259.399994, cad=67.400002, targetPosition=1740.599976, (1)(9) + 134006 [1671485][E](PTData): Cleaned 2 readings + 134007 [1671496][E](PTData): New entry recorded (1)(9)(1740) + 134008 [1671496][E](PTData): Lower Right Found 1, 10, tp1290 + 134009 [1671507][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 134010 [1671508][E](PTable): New Entry Processed in 24 ms + 134011 [1671508][E](PTable): Power Buffer Reset + 134012 [1671519][E](ERG_Mode): Watts previously processed. + 134013 [1672896][E](ERG_Mode): Proportional: 110.250000 + 134014 [1674310][E](ERG_Mode): Watts previously processed. + 134015 [1675642][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 251, Cad 63, HR 154, Gear 0, Res 60, Current Pos 18030, Target Pos 18030 + 134016 [1676422][E](ERG_Mode): Watts previously processed. + 134017 [1677840][E](PTable): Averaged Entry: watts=249.100006, cad=63.700001, targetPosition=1791.199951, (1)(8) + 134018 [1677841][E](PTData): Cleaned 1 readings + 134019 [1677851][E](PTData): New entry recorded (1)(8)(1791) + 134020 [1677851][E](PTData): Lower Right Found 1, 11, tp1312 + 134021 [1677862][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134022 [1677864][E](PTable): New Entry Processed in 25 ms + 134023 [1677867][E](PTable): Power Buffer Reset + 134024 [1678547][E](ERG_Mode): Watts previously processed. + 134025 [1679255][E](ERG_Mode): Proportional: 42.750000 + 134026 [1680670][E](ERG_Mode): Watts previously processed. + 134027 [1681659][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 251, Cad 61, HR 154, Gear 0, Res 61, Current Pos 18398, Target Pos 18399 + 134028 [1684210][E](PTable): Averaged Entry: watts=254.899994, cad=62.299999, targetPosition=1834.500000, (0)(8) + 134029 [1684212][E](PTData): Cleaned 1 readings + 134030 [1684222][E](PTData): Existing entry averaged (0)(8)(1537), readings(1) + 134031 [1684223][E](PTData): Lower Right Found 0, 9, tp1272 + 134032 [1684233][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134033 [1684235][E](PTable): New Entry Processed in 25 ms + 134034 [1684318][E](PTable): Writing File: /PowerTable.txt + 134035 [1684553][E](PTable): Power table saved successfully with 328 readings + 134036 [1684553][E](PTable): Power Buffer Reset + 134037 [1684553][E](ERG_Mode): Watts previously processed. + 134038 [1684918][E](ERG_Mode): Proportional: 49.500000 + 134039 [1686340][E](ERG_Mode): Watts previously processed. + 134040 [1686341][E](PTable): Using detected travel limits during homing + 134041 [1687672][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 269, Cad 60, HR 153, Gear 0, Res 63, Current Pos 18764, Target Pos 18764 + 134042 [1688462][E](ERG_Mode): Watts previously processed. + 134043 [1690576][E](PTable): Averaged Entry: watts=269.899994, cad=61.099998, targetPosition=1872.800049, (0)(9) + 134044 [1690577][E](PTData): Cleaned 1 readings + 134045 [1690587][E](PTData): New entry recorded (0)(9)(1872) + 134046 [1690587][E](PTData): Lower Right Found 0, 10, tp1294 + 134047 [1690598][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134048 [1690600][E](PTable): New Entry Processed in 25 ms + 134049 [1690600][E](PTable): Power Buffer Reset + 134050 [1690610][E](ERG_Mode): Watts previously processed. + 134051 [1691281][E](ERG_Mode): Proportional: 4.500000 + 134052 [1692686][E](ERG_Mode): Watts previously processed. + 134053 [1693687][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 275, Cad 60, HR 153, Gear 0, Res 63, Current Pos 18863, Target Pos 18863 + 134054 [1695506][E](ERG_Mode): Watts previously processed. + 134055 [1696921][E](PTable): Averaged Entry: watts=280.799988, cad=61.599998, targetPosition=1884.300049, (0)(9) + 134056 [1696922][E](PTData): Cleaned 1 readings + 134057 [1696932][E](PTData): New entry recorded (0)(9)(1884) + 134058 [1696932][E](PTData): Lower Right Found 0, 11, tp1316 + 134059 [1696943][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134060 [1696945][E](PTable): New Entry Processed in 25 ms + 134061 [1696945][E](PTable): Power Buffer Reset + 134062 [1696955][E](ERG_Mode): Proportional: -3.750000 + 134063 [1697627][E](ERG_Mode): Watts previously processed. + 134064 [1699705][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 282, Cad 61, HR 151, Gear 0, Res 63, Current Pos 18882, Target Pos 18882 + 134065 [1700455][E](ERG_Mode): Watts previously processed. + 134066 [1702577][E](ERG_Mode): Watts previously processed. + 134067 [1703287][E](PTable): Averaged Entry: watts=288.100006, cad=62.000000, targetPosition=1887.400024, (0)(10) + 134068 [1703288][E](PTData): Cleaned 1 readings + 134069 [1703298][E](PTData): New entry recorded (0)(10)(1887) + 134070 [1703299][E](PTData): Lower Right Found 0, 12, tp1339 + 134071 [1703309][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134072 [1703311][E](PTable): New Entry Processed in 25 ms + 134073 [1703311][E](PTable): Power Buffer Reset + 134074 [1703321][E](ERG_Mode): Proportional: -38.250000 + 134075 [1705406][E](ERG_Mode): Watts previously processed. + 134076 [1705713][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 283, Cad 62, HR 151, Gear 0, Res 63, Current Pos 18797, Target Pos 18797 + 134077 [1707516][E](ERG_Mode): Watts previously processed. + 134078 [1708924][E](ERG_Mode): Watts previously processed. + 134079 [1709632][E](PTable): Averaged Entry: watts=283.899994, cad=62.299999, targetPosition=1880.400024, (0)(9) + 134080 [1709633][E](PTData): Cleaned 1 readings + 134081 [1709643][E](PTData): New entry recorded (0)(9)(1880) + 134082 [1709644][E](PTData): Lower Right Found 0, 13, tp1362 + 134083 [1709654][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134084 [1709656][E](PTable): New Entry Processed in 25 ms + 134085 [1709656][E](PTable): Power Buffer Reset + 134086 [1709666][E](ERG_Mode): Proportional: 5.250000 + 134087 [1711722][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 279, Cad 62, HR 152, Gear 0, Res 63, Current Pos 18854, Target Pos 18854 + 134088 [1711742][E](ERG_Mode): Watts previously processed. + 134089 [1713862][E](ERG_Mode): Watts previously processed. + 134090 [1715278][E](ERG_Mode): Proportional: -6.750000 + 134091 [1715978][E](PTable): Averaged Entry: watts=279.200012, cad=61.700001, targetPosition=1885.300049, (0)(9) + 134092 [1715980][E](PTData): Cleaned 1 readings + 134093 [1715990][E](PTData): New entry recorded (0)(9)(1885) + 134094 [1715990][E](PTData): Lower Right Found 0, 14, tp1387 + 134095 [1716001][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134096 [1716002][E](PTable): New Entry Processed in 24 ms + 134097 [1716003][E](PTable): Power Buffer Reset + 134098 [1716684][E](ERG_Mode): Watts previously processed. + 134099 [1717735][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 287, Cad 61, HR 153, Gear 0, Res 63, Current Pos 18891, Target Pos 18891 + 134100 [1719506][E](ERG_Mode): Watts previously processed. + 134101 [1720917][E](ERG_Mode): Proportional: 3.750000 + 134102 [1721624][E](ERG_Mode): Watts previously processed. + 134103 [1722334][E](PTable): Averaged Entry: watts=280.700012, cad=61.799999, targetPosition=1888.599976, (0)(9) + 134104 [1722335][E](PTData): Cleaned 1 readings + 134105 [1722345][E](PTData): New entry recorded (0)(9)(1888) + 134106 [1722345][E](PTData): Lower Right Found 0, 15, tp1412 + 134107 [1722356][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134108 [1722358][E](PTable): New Entry Processed in 25 ms + 134109 [1722358][E](PTable): Power Buffer Reset + 134110 [1722368][E](PTable): Using detected travel limits during homing + 134111 [1723744][E](ERG_Mode): Watts previously processed. + 134112 [1723745][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 277, Cad 61, HR 153, Gear 0, Res 63, Current Pos 18907, Target Pos 18907 + 134113 [1725866][E](ERG_Mode): Watts previously processed. + 134114 [1726567][E](ERG_Mode): Proportional: 33.750000 + 134115 [1727979][E](ERG_Mode): Watts previously processed. + 134116 [1728683][E](PTable): Averaged Entry: watts=271.700012, cad=60.299999, targetPosition=1895.800049, (0)(9) + 134117 [1728685][E](PTData): Cleaned 1 readings + 134118 [1728695][E](PTData): New entry recorded (0)(9)(1895) + 134119 [1728695][E](PTData): Lower Right Found 0, 16, tp1438 + 134120 [1728706][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134121 [1728707][E](PTable): New Entry Processed in 24 ms + 134122 [1728708][E](PTable): Power Buffer Reset + 134123 [1729766][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 279, Cad 61, HR 153, Gear 0, Res 64, Current Pos 19070, Target Pos 19070 + 134124 [1731506][E](ERG_Mode): Watts previously processed. + 134125 [1732215][E](ERG_Mode): Proportional: -36.000000 + 134126 [1733629][E](ERG_Mode): Watts previously processed. + 134127 [1734838][E](FTMS_SERVER): 05 a0 00 -> ERG Mode Target: 160 Current: 297 Incline: 190.270004. Responding: 80 05 01 + 134128 [1734843][E](DirConManager): Sending response message type 0x04 to client 0 + 134129 [1735039][E](PTable): Averaged Entry: watts=289.899994, cad=61.900002, targetPosition=1905.099976, (0)(10) + 134130 [1735040][E](PTData): Cleaned 1 readings + 134131 [1735050][E](PTData): New entry recorded (0)(10)(1905) + 134132 [1735051][E](PTData): Lower Right Found 0, 17, tp1466 + 134133 [1735061][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134134 [1735062][E](PTable): New Entry Processed in 24 ms + 134135 [1735063][E](PTable): Power Buffer Reset + 134136 [1735073][E](ERG_Mode): SetPoint changed:190w Waiting:2702ms PowerTable Result: 12020 + 134137 [1735776][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 297, Cad 63, HR 154, Gear 0, Res 63, Current Pos 18271, Target Pos 12020 + 134138 [1739147][E](ERG_Mode): ERG wait expired, pos: 12020, tgt: 0 + 134139 [1739148][E](ERG_Mode): Proportional: -246.000000 + 134140 [1740550][E](ERG_Mode): Watts previously processed. + 134141 [1741785][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 113, Cad 82, HR 153, Gear 0, Res 39, Current Pos 11819, Target Pos 11819 + 134142 [1743379][E](ERG_Mode): Watts previously processed. + 134143 [1744797][E](PTable): Averaged Entry: watts=147.899994, cad=77.699997, targetPosition=1193.900024, (3)(5) + 134144 [1744798][E](PTData): Cleaned 1 readings + 134145 [1744808][E](PTData): Existing entry averaged (3)(5)(1167), readings(1) + 134146 [1744808][E](PTData): Lower Right Found 3, 6, tp1164 + 134147 [1744819][E](PTData): Lower Up Found 2, 5, tp1149 + 134148 [1744819][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134149 [1744831][E](PTable): New Entry Processed in 35 ms + 134150 [1744832][E](PTable): Power Buffer Reset + 134151 [1744832][E](ERG_Mode): Proportional: 219.000000 + 134152 [1745498][E](ERG_Mode): Watts previously processed. + 134153 [1747615][E](ERG_Mode): Watts previously processed. + 134154 [1747797][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 110, Cad 78, HR 153, Gear 0, Res 42, Current Pos 12684, Target Pos 12684 + 134155 [1749739][E](ERG_Mode): Watts previously processed. + 134156 [1750441][E](ERG_Mode): Proportional: 156.000000 + 134157 [1751142][E](PTable): Averaged Entry: watts=105.900002, cad=77.400002, targetPosition=1270.199951, (3)(4) + 134158 [1751144][E](PTData): Cleaned 2 readings + 134159 [1751154][E](PTData): Existing entry averaged (3)(4)(1193), readings(1) + 134160 [1751154][E](PTData): Lower Right Found 3, 5, tp1141 + 134161 [1751165][E](PTData): Lower Up Found 2, 4, tp1125 + 134162 [1751165][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134163 [1751177][E](PTable): New Entry Processed in 35 ms + 134164 [1751177][E](PTable): Power Buffer Reset + 134165 [1751849][E](ERG_Mode): Watts previously processed. + 134166 [1753811][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 142, Cad 72, HR 153, Gear 0, Res 45, Current Pos 13432, Target Pos 13432 + 134167 [1754677][E](ERG_Mode): Watts previously processed. + 134168 [1756087][E](ERG_Mode): Proportional: 96.750000 + 134169 [1757497][E](PTable): Averaged Entry: watts=122.199997, cad=71.900002, targetPosition=1344.099976, (2)(4) + 134170 [1757499][E](PTData): Cleaned 2 readings + 134171 [1757509][E](PTData): New entry recorded (2)(4)(1344) + 134172 [1757509][E](PTData): Lower Right Found 2, 6, tp1172 + 134173 [1757520][E](PTData): Lower Up Found 1, 4, tp1133 + 134174 [1757520][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134175 [1757522][E](PTable): New Entry Processed in 25 ms + 134176 [1757533][E](PTable): Power Buffer Reset + 134177 [1757533][E](ERG_Mode): Watts previously processed. + 134178 [1759603][E](ERG_Mode): Watts previously processed. + 134179 [1759825][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 109, Cad 65, HR 152, Gear 0, Res 47, Current Pos 14051, Target Pos 14051 + 134180 [1761712][E](ERG_Mode): Watts previously processed. + 134181 [1761713][E](PTable): Using detected travel limits during homing + 134182 [1762422][E](ERG_Mode): Proportional: 87.750000 + 134183 [1763838][E](PTable): Averaged Entry: watts=117.599998, cad=65.000000, targetPosition=1407.900024, (1)(4) + 134184 [1763839][E](PTData): Cleaned 2 readings + 134185 [1763849][E](PTData): New entry recorded (1)(4)(1407) + 134186 [1763849][E](PTData): Lower Right Found 1, 5, tp1157 + 134187 [1763860][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134188 [1763862][E](PTable): New Entry Processed in 25 ms + 134189 [1763862][E](PTable): Power Buffer Reset + 134190 [1764543][E](ERG_Mode): Watts previously processed. + 134191 [1765839][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 118, Cad 64, HR 150, Gear 0, Res 49, Current Pos 14559, Target Pos 14559 + 134192 [1766665][E](ERG_Mode): Watts previously processed. + 134193 [1768081][E](ERG_Mode): Proportional: 92.250000 + 134194 [1768788][E](ERG_Mode): Watts previously processed. + 134195 [1770195][E](PTable): Averaged Entry: watts=125.900002, cad=62.500000, targetPosition=1465.199951, (0)(4) + 134196 [1770196][E](PTData): Cleaned 1 readings + 134197 [1770206][E](PTData): Existing entry averaged (0)(4)(1303), readings(1) + 134198 [1770206][E](PTData): Lower Right Found 0, 5, tp1166 + 134199 [1770217][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134200 [1770219][E](PTable): New Entry Processed in 25 ms + 134201 [1770219][E](PTable): Power Buffer Reset + 134202 [1771616][E](ERG_Mode): Watts previously processed. + 134203 [1771849][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 134, Cad 63, HR 148, Gear 0, Res 50, Current Pos 14989, Target Pos 14989 + 134204 [1773741][E](ERG_Mode): Watts previously processed. + 134205 [1774448][E](ERG_Mode): Proportional: 69.750000 + 134206 [1776558][E](PTable): Averaged Entry: watts=134.100006, cad=61.500000, targetPosition=1507.400024, (0)(4) + 134207 [1776559][E](PTData): Cleaned 1 readings + 134208 [1776569][E](PTData): Existing entry averaged (0)(4)(1324), readings(1) + 134209 [1776570][E](PTData): Lower Right Found 0, 6, tp1189 + 134210 [1776580][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134211 [1776582][E](PTable): New Entry Processed in 25 ms + 134212 [1776583][E](PTable): Power Buffer Reset + 134213 [1776593][E](ERG_Mode): Watts previously processed. + 134214 [1777864][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 150, Cad 62, HR 145, Gear 0, Res 51, Current Pos 15322, Target Pos 15322 + 134215 [1778681][E](ERG_Mode): Watts previously processed. + 134216 [1780098][E](ERG_Mode): Proportional: 6.000000 + 134217 [1780802][E](ERG_Mode): Watts previously processed. + 134218 [1782930][E](PTable): Averaged Entry: watts=150.500000, cad=61.799999, targetPosition=1532.900024, (0)(5) + 134219 [1782931][E](PTData): Cleaned 1 readings + 134220 [1782942][E](PTData): New entry recorded (0)(5)(1532) + 134221 [1782942][E](PTData): Lower Right Found 0, 7, tp1213 + 134222 [1782943][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 134223 [1782954][E](PTable): New Entry Processed in 25 ms + 134224 [1782954][E](PTable): Power Buffer Reset + 134225 [1783635][E](ERG_Mode): Watts previously processed. + 134226 [1783879][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 153, Cad 62, HR 141, Gear 0, Res 51, Current Pos 15363, Target Pos 15363 + 134227 [1785748][E](ERG_Mode): Watts previously processed. + 134228 [1786456][E](ERG_Mode): Proportional: 6.000000 + 134229 [1788576][E](ERG_Mode): Watts previously processed. + 134230 [1789278][E](PTable): Averaged Entry: watts=153.699997, cad=62.000000, targetPosition=1536.599976, (0)(5) + 134231 [1789280][E](PTData): Cleaned 1 readings + 134232 [1789290][E](PTData): New entry recorded (0)(5)(1536) + 134233 [1789290][E](PTData): Lower Right Found 0, 8, tp1240 + 134234 [1789291][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134235 [1789303][E](PTable): New Entry Processed in 26 ms + 134236 [1789303][E](PTable): Power Buffer Reset + 134237 [1789894][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 156, Cad 62, HR 137, Gear 0, Res 52, Current Pos 15388, Target Pos 15388 + 134238 [1790689][E](ERG_Mode): Watts previously processed. + 134239 [1792096][E](ERG_Mode): Proportional: -0.750000 + 134240 [1792801][E](ERG_Mode): Watts previously processed. + 134241 [1794921][E](ERG_Mode): Watts previously processed. + 134242 [1795632][E](PTable): Averaged Entry: watts=152.899994, cad=61.799999, targetPosition=1541.000000, (0)(5) + 134243 [1795636][E](PTData): Cleaned 1 readings + 134244 [1795646][E](PTData): New entry recorded (0)(5)(1541) + 134245 [1795647][E](PTData): Lower Right Found 0, 18, tp1492 + 134246 [1795647][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134247 [1795659][E](PTable): New Entry Processed in 28 ms + 134248 [1795659][E](PTable): Power Buffer Reset + 134249 [1795912][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 145, Cad 61, HR 134, Gear 0, Res 52, Current Pos 15487, Target Pos 15487 + 134250 [1797035][E](ERG_Mode): Watts previously processed. + 134251 [1797740][E](ERG_Mode): Proportional: 33.750000 + 134252 [1797742][E](PTable): Using detected travel limits during homing + 134253 [1798450][E](ERG_Mode): Watts previously processed. + 134254 [1800569][E](ERG_Mode): Watts previously processed. + 134255 [1801923][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 162, Cad 62, HR 132, Gear 0, Res 52, Current Pos 15586, Target Pos 15586 + 134256 [1801983][E](PTable): Averaged Entry: watts=150.899994, cad=60.000000, targetPosition=1554.000000, (0)(5) + 134257 [1801985][E](PTData): Cleaned 1 readings + 134258 [1801995][E](PTData): New entry recorded (0)(5)(1554) + 134259 [1801995][E](PTData): Lower Right Found 0, 19, tp1519 + 134260 [1802006][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134261 [1802007][E](PTable): New Entry Processed in 24 ms + 134262 [1802008][E](PTable): Power Buffer Reset + 134263 [1802687][E](ERG_Mode): Watts previously processed. + 134264 [1803391][E](ERG_Mode): Proportional: -1.500000 + 134265 [1804799][E](ERG_Mode): Watts previously processed. + 134266 [1806915][E](ERG_Mode): Watts previously processed. + 134267 [1807934][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 160, Cad 62, HR 132, Gear 0, Res 52, Current Pos 15575, Target Pos 15575 + 134268 [1808331][E](PTable): Averaged Entry: watts=161.800003, cad=62.000000, targetPosition=1557.599976, (0)(5) + 134269 [1808332][E](PTData): Cleaned 1 readings + 134270 [1808342][E](PTData): New entry recorded (0)(5)(1557) + 134271 [1808343][E](PTData): Lower Right Found 0, 20, tp1546 + 134272 [1808353][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134273 [1808355][E](PTable): New Entry Processed in 25 ms + 134274 [1808355][E](PTable): Power Buffer Reset + 134275 [1809036][E](ERG_Mode): Watts previously processed. + 134276 [1809738][E](ERG_Mode): Proportional: -3.000000 + 134277 [1810443][E](ERG_Mode): Watts previously processed. + 134278 [1812569][E](ERG_Mode): Watts previously processed. + 134279 [1813948][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 154, Cad 63, HR 132, Gear 0, Res 52, Current Pos 15530, Target Pos 15530 + 134280 [1814683][E](PTable): Averaged Entry: watts=163.100006, cad=62.500000, targetPosition=1555.199951, (0)(5) + 134281 [1814684][E](PTData): Cleaned 1 readings + 134282 [1814694][E](PTData): New entry recorded (0)(5)(1555) + 134283 [1814695][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 134284 [1814705][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 134285 [1814706][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134286 [1814721][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134287 [1814722][E](PTable): New Entry Processed in 40 ms + 134288 [1814722][E](PTable): Power Buffer Reset + 134289 [1814733][E](ERG_Mode): Watts previously processed. + 134290 [1815386][E](ERG_Mode): Proportional: -29.250000 + 134291 [1816797][E](ERG_Mode): Watts previously processed. + 134292 [1818909][E](ERG_Mode): Watts previously processed. + 134293 [1819960][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 168, Cad 64, HR 130, Gear 0, Res 52, Current Pos 15457, Target Pos 15457 + 134294 [1821029][E](PTable): Averaged Entry: watts=166.899994, cad=63.299999, targetPosition=1547.599976, (1)(6) + 134295 [1821031][E](PTData): Existing entry averaged (1)(6)(1366), readings(1) + 134296 [1821041][E](PTData): Lower Right Found 1, 7, tp1209 + 134297 [1821042][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134298 [1821053][E](PTable): New Entry Processed in 24 ms + 134299 [1821054][E](PTable): Power Buffer Reset + 134300 [1821054][E](ERG_Mode): Proportional: 0.000000 + 134301 [1822444][E](ERG_Mode): Watts previously processed. + 134302 [1824557][E](ERG_Mode): Watts previously processed. + 134303 [1825971][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 161, Cad 63, HR 130, Gear 0, Res 52, Current Pos 15445, Target Pos 15445 + 134304 [1826680][E](ERG_Mode): Watts previously processed. + 134305 [1827389][E](PTable): Averaged Entry: watts=162.300003, cad=62.500000, targetPosition=1544.500000, (0)(5) + 134306 [1827390][E](PTData): Cleaned 1 readings + 134307 [1827400][E](PTData): Existing entry averaged (0)(5)(1454), readings(1) + 134308 [1827400][E](PTData): Lower Right Found 0, 6, tp1377 + 134309 [1827412][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134310 [1827413][E](PTable): New Entry Processed in 25 ms + 134311 [1827413][E](PTable): Power Buffer Reset + 134312 [1827424][E](ERG_Mode): Proportional: -0.750000 + 134313 [1828801][E](ERG_Mode): Watts previously processed. + 134314 [1830921][E](ERG_Mode): Watts previously processed. + 134315 [1831982][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 159, Cad 62, HR 131, Gear 0, Res 52, Current Pos 15439, Target Pos 15439 + 134316 [1833040][E](ERG_Mode): Proportional: -1.500000 + 134317 [1833745][E](PTable): Averaged Entry: watts=161.300003, cad=62.000000, targetPosition=1543.400024, (0)(5) + 134318 [1833747][E](PTData): Cleaned 1 readings + 134319 [1833757][E](PTData): Existing entry averaged (0)(5)(1454), readings(1) + 134320 [1833757][E](PTData): Lower Right Found 0, 7, tp1390 + 134321 [1833768][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134322 [1833769][E](PTable): New Entry Processed in 24 ms + 134323 [1833770][E](PTable): Power Buffer Reset + 134324 [1833780][E](PTable): Using detected travel limits during homing + 134325 [1834450][E](ERG_Mode): Watts previously processed. + 134326 [1836572][E](ERG_Mode): Watts previously processed. + 134327 [1837995][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 165, Cad 63, HR 129, Gear 0, Res 52, Current Pos 15420, Target Pos 15416 + 134328 [1838693][E](ERG_Mode): Watts previously processed. + 134329 [1839400][E](ERG_Mode): Proportional: 40.500000 + 134330 [1840110][E](PTable): Averaged Entry: watts=160.500000, cad=62.200001, targetPosition=1542.400024, (0)(5) + 134331 [1840111][E](PTData): Cleaned 1 readings + 134332 [1840121][E](PTData): Existing entry averaged (0)(5)(1453), readings(1) + 134333 [1840122][E](PTData): Lower Right Found 0, 8, tp1402 + 134334 [1840132][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134335 [1840134][E](PTable): New Entry Processed in 25 ms + 134336 [1840134][E](PTable): Power Buffer Reset + 134337 [1840814][E](ERG_Mode): Watts previously processed. + 134338 [1842932][E](ERG_Mode): Watts previously processed. + 134339 [1844013][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 169, Cad 63, HR 130, Gear 0, Res 52, Current Pos 15540, Target Pos 15540 + 134340 [1844347][E](ERG_Mode): Watts previously processed. + 134341 [1845056][E](ERG_Mode): Proportional: -22.500000 + 134342 [1846467][E](PTable): Averaged Entry: watts=155.100006, cad=61.000000, targetPosition=1551.400024, (0)(5) + 134343 [1846469][E](PTData): Cleaned 1 readings + 134344 [1846479][E](PTData): Existing entry averaged (0)(5)(1458), readings(1) + 134345 [1846479][E](PTData): Lower Right Found 0, 9, tp1415 + 134346 [1846490][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134347 [1846492][E](PTable): New Entry Processed in 25 ms + 134348 [1846492][E](PTable): Power Buffer Reset + 134349 [1846502][E](ERG_Mode): Watts previously processed. + 134350 [1848585][E](ERG_Mode): Watts previously processed. + 134351 [1850022][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 143, Cad 58, HR 128, Gear 0, Res 52, Current Pos 15563, Target Pos 15600 + 134352 [1850706][E](ERG_Mode): Watts previously processed. + 134353 [1851416][E](ERG_Mode): Proportional: 6.000000 + 134354 [1852821][E](PTable): Averaged Entry: watts=151.000000, cad=59.700001, targetPosition=1555.699951, (0)(5) + 134355 [1852823][E](PTData): Cleaned 1 readings + 134356 [1852833][E](PTData): Existing entry averaged (0)(5)(1460), readings(1) + 134357 [1852833][E](PTData): Lower Right Found 0, 10, tp1427 + 134358 [1852844][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134359 [1852848][E](PTable): New Entry Processed in 28 ms + 134360 [1852848][E](PTable): Power Buffer Reset + 134361 [1852849][E](ERG_Mode): Watts previously processed. + 134362 [1854826][E](FTMS_SERVER): 05 f5 00 -> ERG Mode Target: 245 Current: 147 Incline: 156.449997. Responding: 80 05 01 + 134363 [1854834][E](DirConManager): Sending response message type 0x04 to client 0 + 134364 [1854958][E](ERG_Mode): Table Result Failed increasing Test: 12270 + 134365 [1854959][E](ERG_Mode): Lookup Error. Using PID + 134366 [1856033][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 162, Cad 59, HR 129, Gear 0, Res 53, Current Pos 16129, Target Pos 16188 + 134367 [1856369][E](ERG_Mode): Watts previously processed. + 134368 [1857072][E](ERG_Mode): Watts previously processed. + 134369 [1857776][E](ERG_Mode): Proportional: 186.000000 + 134370 [1858483][E](ERG_Mode): Watts previously processed. + 134371 [1859191][E](PTable): Averaged Entry: watts=165.600006, cad=60.700001, targetPosition=1596.800049, (0)(6) + 134372 [1859192][E](PTData): Cleaned 1 readings + 134373 [1859202][E](PTData): New entry recorded (0)(6)(1596) + 134374 [1859202][E](PTData): Lower Right Found 0, 11, tp1440 + 134375 [1859213][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134376 [1859215][E](PTable): New Entry Processed in 25 ms + 134377 [1859215][E](PTable): Power Buffer Reset + 134378 [1860602][E](ERG_Mode): Watts previously processed. + 134379 [1862049][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 201, Cad 63, HR 126, Gear 0, Res 56, Current Pos 16678, Target Pos 16775 + 134380 [1862725][E](ERG_Mode): Watts previously processed. + 134381 [1863433][E](ERG_Mode): Proportional: 92.250000 + 134382 [1864835][E](ERG_Mode): Watts previously processed. + 134383 [1865543][E](PTable): Averaged Entry: watts=199.800003, cad=63.500000, targetPosition=1671.900024, (1)(7) + 134384 [1865544][E](PTData): Cleaned 1 readings + 134385 [1865554][E](PTData): New entry recorded (1)(7)(1671) + 134386 [1865555][E](PTData): Lower Right Found 1, 8, tp1234 + 134387 [1865555][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134388 [1865567][E](PTable): New Entry Processed in 25 ms + 134389 [1865568][E](PTable): Power Buffer Reset + 134390 [1867660][E](ERG_Mode): Watts previously processed. + 134391 [1868059][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 213, Cad 62, HR 123, Gear 0, Res 58, Current Pos 17253, Target Pos 17253 + 134392 [1869070][E](ERG_Mode): Proportional: 74.250000 + 134393 [1869792][E](PTable): Using detected travel limits during homing + 134394 [1870500][E](ERG_Mode): Watts previously processed. + 134395 [1871913][E](PTable): Averaged Entry: watts=215.100006, cad=61.400002, targetPosition=1729.900024, (0)(7) + 134396 [1871914][E](PTData): Cleaned 1 readings + 134397 [1871924][E](PTData): New entry recorded (0)(7)(1729) + 134398 [1871925][E](PTData): Lower Right Found 0, 12, tp1452 + 134399 [1871935][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134400 [1871937][E](PTable): New Entry Processed in 25 ms + 134401 [1871937][E](PTable): Power Buffer Reset + 134402 [1872615][E](ERG_Mode): Watts previously processed. + 134403 [1874074][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 216, Cad 60, HR 127, Gear 0, Res 59, Current Pos 17621, Target Pos 17681 + 134404 [1874730][E](ERG_Mode): Watts previously processed. + 134405 [1875439][E](ERG_Mode): Proportional: 42.750000 + 134406 [1876842][E](ERG_Mode): Watts previously processed. + 134407 [1878258][E](PTable): Averaged Entry: watts=222.399994, cad=60.400002, targetPosition=1767.000000, (0)(7) + 134408 [1878260][E](PTData): Cleaned 1 readings + 134409 [1878270][E](PTData): New entry recorded (0)(7)(1767) + 134410 [1878270][E](PTData): Lower Right Found 0, 13, tp1465 + 134411 [1878271][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134412 [1878283][E](PTable): New Entry Processed in 26 ms + 134413 [1878283][E](PTable): Power Buffer Reset + 134414 [1879663][E](ERG_Mode): Watts previously processed. + 134415 [1880092][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 237, Cad 62, HR 127, Gear 0, Res 60, Current Pos 17848, Target Pos 17848 + 134416 [1881072][E](ERG_Mode): Proportional: 47.250000 + 134417 [1881777][E](ERG_Mode): Watts previously processed. + 134418 [1883893][E](ERG_Mode): Watts previously processed. + 134419 [1884594][E](PTable): Averaged Entry: watts=232.899994, cad=60.599998, targetPosition=1789.300049, (0)(8) + 134420 [1884596][E](PTData): Cleaned 1 readings + 134421 [1884606][E](PTData): New entry recorded (0)(8)(1789) + 134422 [1884606][E](PTData): Lower Right Found 0, 14, tp1477 + 134423 [1884618][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 134424 [1884619][E](PTable): New Entry Processed in 25 ms + 134425 [1884620][E](PTable): Power Buffer Reset + 134426 [1886002][E](ERG_Mode): Watts previously processed. + 134427 [1886107][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 255, Cad 63, HR 127, Gear 0, Res 60, Current Pos 17997, Target Pos 17997 + 134428 [1886713][E](ERG_Mode): Proportional: -22.500000 + 134429 [1888837][E](ERG_Mode): Watts previously processed. + 134430 [1890954][E](PTable): Averaged Entry: watts=240.899994, cad=61.200001, targetPosition=1799.500000, (0)(8) + 134431 [1890955][E](PTData): Cleaned 1 readings + 134432 [1890966][E](PTData): New entry recorded (0)(8)(1799) + 134433 [1890966][E](PTData): Lower Right Found 0, 15, tp1490 + 134434 [1890967][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 134435 [1890978][E](PTable): New Entry Processed in 25 ms + 134436 [1890978][E](PTable): Power Buffer Reset + 134437 [1891657][E](ERG_Mode): Watts previously processed. + 134438 [1892125][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 235, Cad 60, HR 129, Gear 0, Res 61, Current Pos 18096, Target Pos 18096 + 134439 [1892360][E](ERG_Mode): Proportional: 22.500000 + 134440 [1893764][E](ERG_Mode): Watts previously processed. + 134441 [1895885][E](ERG_Mode): Watts previously processed. + 134442 [1897297][E](PTable): Averaged Entry: watts=236.899994, cad=60.299999, targetPosition=1812.300049, (0)(8) + 134443 [1897298][E](PTData): Cleaned 1 readings + 134444 [1897308][E](PTData): New entry recorded (0)(8)(1812) + 134445 [1897309][E](PTData): Lower Right Found 0, 16, tp1502 + 134446 [1897319][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134447 [1897321][E](PTable): New Entry Processed in 25 ms + 134448 [1897321][E](PTable): Power Buffer Reset + 134449 [1898003][E](ERG_Mode): Watts previously processed. + 134450 [1898141][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 241, Cad 60, HR 130, Gear 0, Res 61, Current Pos 18157, Target Pos 18157 + 134451 [1898706][E](ERG_Mode): Proportional: 3.000000 + 134452 [1900838][E](ERG_Mode): Watts previously processed. + 134453 [1903659][E](PTable): Averaged Entry: watts=234.100006, cad=59.700001, targetPosition=1819.900024, (0)(8) + 134454 [1903660][E](PTData): Cleaned 1 readings + 134455 [1903671][E](PTData): New entry recorded (0)(8)(1819) + 134456 [1903671][E](PTData): Lower Right Found 0, 17, tp1515 + 134457 [1903672][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 1 ms + 134458 [1903683][E](PTable): New Entry Processed in 25 ms + 134459 [1903684][E](PTable): Power Buffer Reset + 134460 [1903694][E](ERG_Mode): Watts previously processed. + 134461 [1904158][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 233, Cad 59, HR 131, Gear 0, Res 61, Current Pos 18306, Target Pos 18306 + 134462 [1904362][E](ERG_Mode): Proportional: 27.000000 + 134463 [1905774][E](ERG_Mode): Watts previously processed. + 134464 [1905775][E](PTable): Using detected travel limits during homing + 134465 [1907895][E](ERG_Mode): Watts previously processed. + 134466 [1910016][E](PTable): Averaged Entry: watts=235.399994, cad=58.900002, targetPosition=1833.900024, (0)(8) + 134467 [1910017][E](PTData): Cleaned 1 readings + 134468 [1910027][E](PTData): New entry recorded (0)(8)(1833) + 134469 [1910027][E](PTData): Lower Right Found 0, 18, tp1528 + 134470 [1910038][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 134471 [1910040][E](PTable): New Entry Processed in 25 ms + 134472 [1910040][E](PTable): Power Buffer Reset + 134473 [1910050][E](ERG_Mode): Watts previously processed. + 134474 [1910170][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 228, Cad 58, HR 132, Gear 0, Res 62, Current Pos 18410, Target Pos 18410 + 134475 [1910718][E](ERG_Mode): Proportional: 38.250000 + 134476 [1912132][E](ERG_Mode): Watts previously processed. + 134477 [1913538][E](ERG_Mode): Watts previously processed. + 134478 [1914829][E](FTMS_SERVER): 05 91 00 -> ERG Mode Target: 145 Current: 220 Incline: 185.960007. Responding: 80 05 01 + 134479 [1914834][E](DirConManager): Sending response message type 0x04 to client 0 + 134480 [1914948][E](ERG_Mode): SetPoint changed:175w Waiting:2582ms PowerTable Result: 12010 + 134481 [1916189][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 228, Cad 57, HR 134, Gear 0, Res 59, Current Pos 16259, Target Pos 12010 + 134482 [1918743][E](FTMS_SERVER): 11 00 00 8e ff 28 33 -> Sim Mode Incline -1.140000. Responding: 80 11 01 + 134483 [1918751][E](DirConManager): Sending response message type 0x04 to client 0 + 134484 [1918935][E](ERG_Mode): ERG wait expired, pos: 11957, tgt: 0 + 134485 [1918936][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 134486 [1918946][E](PTable): Power Buffer Reset + 134487 [1919641][E](FTMS_SERVER): 11 00 00 e8 ff 28 33 -> Sim Mode Incline -0.240000. Responding: 80 11 01 + 134488 [1919647][E](DirConManager): Sending response message type 0x04 to client 0 + 134489 [1920686][E](FTMS_SERVER): 11 00 00 3e 00 28 33 -> Sim Mode Incline 0.620000. Responding: 80 11 01 + 134490 [1920693][E](DirConManager): Sending response message type 0x04 to client 0 + 134491 [1921061][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 134492 [1921062][E](PTable): Power Buffer Reset + 134493 [1921632][E](FTMS_SERVER): 11 00 00 87 00 28 33 -> Sim Mode Incline 1.350000. Responding: 80 11 01 + 134494 [1921637][E](DirConManager): Sending response message type 0x04 to client 0 + 134495 [1922200][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 34, Cad 61, HR 134, Gear 0, Res 8, Current Pos 2093, Target Pos 945 + 134496 [1922638][E](FTMS_SERVER): 11 00 00 b7 00 28 33 -> Sim Mode Incline 1.830000. Responding: 80 11 01 + 134497 [1922643][E](DirConManager): Sending response message type 0x04 to client 0 + 134498 [1923538][E](FTMS_SERVER): 11 00 00 e2 00 28 33 -> Sim Mode Incline 2.260000. Responding: 80 11 01 + 134499 [1923545][E](DirConManager): Sending response message type 0x04 to client 0 + 134500 [1924449][E](FTMS_SERVER): 11 00 00 06 01 28 33 -> Sim Mode Incline 2.620000. Responding: 80 11 01 + 134501 [1924457][E](DirConManager): Sending response message type 0x04 to client 0 + 134502 [1925493][E](FTMS_SERVER): 11 00 00 2f 01 28 33 -> Sim Mode Incline 3.030000. Responding: 80 11 01 + 134503 [1925500][E](DirConManager): Sending response message type 0x04 to client 0 + 134504 [1926429][E](FTMS_SERVER): 11 00 00 4d 01 28 33 -> Sim Mode Incline 3.330000. Responding: 80 11 01 + 134505 [1926436][E](DirConManager): Sending response message type 0x04 to client 0 + 134506 [1927432][E](FTMS_SERVER): 11 00 00 34 01 28 33 -> Sim Mode Incline 3.080000. Responding: 80 11 01 + 134507 [1927437][E](DirConManager): Sending response message type 0x04 to client 0 + 134508 [1928217][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 134, Gear 0, Res 7, Current Pos 2156, Target Pos 2156 + 134509 [1928351][E](FTMS_SERVER): 11 00 00 14 01 28 33 -> Sim Mode Incline 2.760000. Responding: 80 11 01 + 134510 [1928358][E](DirConManager): Sending response message type 0x04 to client 0 + 134511 [1929288][E](FTMS_SERVER): 11 00 00 f9 00 28 33 -> Sim Mode Incline 2.490000. Responding: 80 11 01 + 134512 [1929295][E](DirConManager): Sending response message type 0x04 to client 0 + 134513 [1930292][E](FTMS_SERVER): 11 00 00 df 00 28 33 -> Sim Mode Incline 2.230000. Responding: 80 11 01 + 134514 [1930299][E](DirConManager): Sending response message type 0x04 to client 0 + 134515 [1931241][E](FTMS_SERVER): 11 00 00 be 00 28 33 -> Sim Mode Incline 1.900000. Responding: 80 11 01 + 134516 [1931249][E](DirConManager): Sending response message type 0x04 to client 0 + 134517 [1932244][E](FTMS_SERVER): 11 00 00 94 00 28 33 -> Sim Mode Incline 1.480000. Responding: 80 11 01 + 134518 [1932251][E](DirConManager): Sending response message type 0x04 to client 0 + 134519 [1933158][E](FTMS_SERVER): 11 00 00 59 00 28 33 -> Sim Mode Incline 0.890000. Responding: 80 11 01 + 134520 [1933163][E](DirConManager): Sending response message type 0x04 to client 0 + 134521 [1934087][E](FTMS_SERVER): 11 00 00 f3 ff 28 33 -> Sim Mode Incline -0.130000. Responding: 80 11 01 + 134522 [1934094][E](DirConManager): Sending response message type 0x04 to client 0 + 134523 [1934231][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 132, Gear 0, Res 2, Current Pos 597, Target Pos -91 + 134524 [1935048][E](FTMS_SERVER): 11 00 00 29 ff 28 33 -> Sim Mode Incline -2.150000. Responding: 80 11 01 + 134525 [1935056][E](DirConManager): Sending response message type 0x04 to client 0 + 134526 [1936047][E](FTMS_SERVER): 11 00 00 de fd 28 33 -> Sim Mode Incline -5.460000. Responding: 80 11 01 + 134527 [1936055][E](DirConManager): Sending response message type 0x04 to client 0 + 134528 [1936951][E](FTMS_SERVER): 11 00 00 10 fe 28 33 -> Sim Mode Incline -4.960000. Responding: 80 11 01 + 134529 [1936958][E](DirConManager): Sending response message type 0x04 to client 0 + 134530 [1937874][E](FTMS_SERVER): 11 00 00 ef ff 28 33 -> Sim Mode Incline -0.170000. Responding: 80 11 01 + 134531 [1937880][E](DirConManager): Sending response message type 0x04 to client 0 + 134532 [1938898][E](FTMS_SERVER): 11 00 00 0a 02 28 33 -> Sim Mode Incline 5.220000. Responding: 80 11 01 + 134533 [1938903][E](DirConManager): Sending response message type 0x04 to client 0 + 134534 [1939871][E](FTMS_SERVER): 11 00 00 51 03 28 33 -> Sim Mode Incline 8.490000. Responding: 80 11 01 + 134535 [1939876][E](DirConManager): Sending response message type 0x04 to client 0 + 134536 [1940241][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 130, Gear 0, Res 4, Current Pos 2674, Target Pos 5943 + 134537 [1940751][E](FTMS_SERVER): 11 00 00 d8 02 28 33 -> Sim Mode Incline 7.280000. Responding: 80 11 01 + 134538 [1940758][E](DirConManager): Sending response message type 0x04 to client 0 + 134539 [1941662][E](FTMS_SERVER): 11 00 00 2e 00 28 33 -> Sim Mode Incline 0.460000. Responding: 80 11 01 + 134540 [1941669][E](DirConManager): Sending response message type 0x04 to client 0 + 134541 [1942685][E](FTMS_SERVER): 11 00 00 d2 ff 28 33 -> Sim Mode Incline -0.460000. Responding: 80 11 01 + 134542 [1942693][E](DirConManager): Sending response message type 0x04 to client 0 + 134543 [1943752][E](FTMS_SERVER): 11 00 00 bb ff 28 33 -> Sim Mode Incline -0.690000. Responding: 80 11 01 + 134544 [1943759][E](DirConManager): Sending response message type 0x04 to client 0 + 134545 [1944866][E](FTMS_SERVER): 11 00 00 b0 ff 28 33 -> Sim Mode Incline -0.800000. Responding: 80 11 01 + 134546 [1944873][E](DirConManager): Sending response message type 0x04 to client 0 + 134547 [1945865][E](FTMS_SERVER): 11 00 00 ad ff 28 33 -> Sim Mode Incline -0.830000. Responding: 80 11 01 + 134548 [1945872][E](DirConManager): Sending response message type 0x04 to client 0 + 134549 [1946251][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 127, Gear 0, Res 0, Current Pos 1, Target Pos -581 + 134550 [1946780][E](FTMS_SERVER): 11 00 00 af ff 28 33 -> Sim Mode Incline -0.810000. Responding: 80 11 01 + 134551 [1946785][E](DirConManager): Sending response message type 0x04 to client 0 + 134552 [1947799][E](FTMS_SERVER): 11 00 00 b5 ff 28 33 -> Sim Mode Incline -0.750000. Responding: 80 11 01 + 134553 [1947804][E](DirConManager): Sending response message type 0x04 to client 0 + 134554 [1948755][E](FTMS_SERVER): 11 00 00 c7 ff 28 33 -> Sim Mode Incline -0.570000. Responding: 80 11 01 + 134555 [1948760][E](DirConManager): Sending response message type 0x04 to client 0 + 134556 [1949751][E](FTMS_SERVER): 11 00 00 e7 ff 28 33 -> Sim Mode Incline -0.250000. Responding: 80 11 01 + 134557 [1949759][E](DirConManager): Sending response message type 0x04 to client 0 + 134558 [1950677][E](FTMS_SERVER): 11 00 00 07 00 28 33 -> Sim Mode Incline 0.070000. Responding: 80 11 01 + 134559 [1950684][E](DirConManager): Sending response message type 0x04 to client 0 + 134560 [1951588][E](FTMS_SERVER): 11 00 00 32 00 28 33 -> Sim Mode Incline 0.500000. Responding: 80 11 01 + 134561 [1951595][E](DirConManager): Sending response message type 0x04 to client 0 + 134562 [1952266][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 122, Gear 0, Res 0, Current Pos 350, Target Pos 350 + 134563 [1952614][E](FTMS_SERVER): 11 00 00 4e 00 28 33 -> Sim Mode Incline 0.780000. Responding: 80 11 01 + 134564 [1952621][E](DirConManager): Sending response message type 0x04 to client 0 + 134565 [1953571][E](FTMS_SERVER): 11 00 00 51 00 28 33 -> Sim Mode Incline 0.810000. Responding: 80 11 01 + 134566 [1953578][E](DirConManager): Sending response message type 0x04 to client 0 + 134567 [1954561][E](FTMS_SERVER): 11 00 00 0c 00 28 33 -> Sim Mode Incline 0.120000. Responding: 80 11 01 + 134568 [1954566][E](DirConManager): Sending response message type 0x04 to client 0 + 134569 [1955499][E](FTMS_SERVER): 11 00 00 d1 ff 28 33 -> Sim Mode Incline -0.470000. Responding: 80 11 01 + 134570 [1955507][E](DirConManager): Sending response message type 0x04 to client 0 + 134571 [1956514][E](FTMS_SERVER): 11 00 00 d3 ff 28 33 -> Sim Mode Incline -0.450000. Responding: 80 11 01 + 134572 [1956521][E](DirConManager): Sending response message type 0x04 to client 0 + 134573 [1957472][E](FTMS_SERVER): 11 00 00 d1 ff 28 33 -> Sim Mode Incline -0.470000. Responding: 80 11 01 + 134574 [1957479][E](DirConManager): Sending response message type 0x04 to client 0 + 134575 [1958276][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 113, Gear 0, Res 0, Current Pos 1, Target Pos -329 + 134576 [1958462][E](FTMS_SERVER): 11 00 00 cb ff 28 33 -> Sim Mode Incline -0.530000. Responding: 80 11 01 + 134577 [1958469][E](DirConManager): Sending response message type 0x04 to client 0 + 134578 [1959384][E](FTMS_SERVER): 11 00 00 c3 ff 28 33 -> Sim Mode Incline -0.610000. Responding: 80 11 01 + 134579 [1959392][E](DirConManager): Sending response message type 0x04 to client 0 + 134580 [1960300][E](FTMS_SERVER): 11 00 00 b8 ff 28 33 -> Sim Mode Incline -0.720000. Responding: 80 11 01 + 134581 [1960305][E](DirConManager): Sending response message type 0x04 to client 0 + 134582 [1961329][E](FTMS_SERVER): 11 00 00 ac ff 28 33 -> Sim Mode Incline -0.840000. Responding: 80 11 01 + 134583 [1961334][E](DirConManager): Sending response message type 0x04 to client 0 + 134584 [1962358][E](FTMS_SERVER): 11 00 00 9c ff 28 33 -> Sim Mode Incline -1.000000. Responding: 80 11 01 + 134585 [1962363][E](DirConManager): Sending response message type 0x04 to client 0 + 134586 [1963387][E](FTMS_SERVER): 11 00 00 88 ff 28 33 -> Sim Mode Incline -1.200000. Responding: 80 11 01 + 134587 [1963393][E](DirConManager): Sending response message type 0x04 to client 0 + 134588 [1964285][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 113, Gear 0, Res 0, Current Pos 1, Target Pos -840 + 134589 [1964299][E](FTMS_SERVER): 11 00 00 5d ff 28 33 -> Sim Mode Incline -1.630000. Responding: 80 11 01 + 134590 [1964306][E](DirConManager): Sending response message type 0x04 to client 0 + 134591 [1965220][E](FTMS_SERVER): 11 00 00 32 ff 28 33 -> Sim Mode Incline -2.060000. Responding: 80 11 01 + 134592 [1965228][E](DirConManager): Sending response message type 0x04 to client 0 + 134593 [1966242][E](FTMS_SERVER): 11 00 00 19 ff 28 33 -> Sim Mode Incline -2.310000. Responding: 80 11 01 + 134594 [1966250][E](DirConManager): Sending response message type 0x04 to client 0 + 134595 [1967192][E](FTMS_SERVER): 11 00 00 0a ff 28 33 -> Sim Mode Incline -2.460000. Responding: 80 11 01 + 134596 [1967200][E](DirConManager): Sending response message type 0x04 to client 0 + 134597 [1968197][E](FTMS_SERVER): 11 00 00 09 ff 28 33 -> Sim Mode Incline -2.470000. Responding: 80 11 01 + 134598 [1968204][E](DirConManager): Sending response message type 0x04 to client 0 + 134599 [1969118][E](FTMS_SERVER): 11 00 00 12 ff 28 33 -> Sim Mode Incline -2.380000. Responding: 80 11 01 + 134600 [1969123][E](DirConManager): Sending response message type 0x04 to client 0 + 134601 [1970026][E](FTMS_SERVER): 11 00 00 2b ff 28 33 -> Sim Mode Incline -2.130000. Responding: 80 11 01 + 134602 [1970033][E](DirConManager): Sending response message type 0x04 to client 0 + 134603 [1970300][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 108, Gear 0, Res 0, Current Pos 1, Target Pos -1491 + 134604 [1970981][E](FTMS_SERVER): 11 00 00 5d ff 28 33 -> Sim Mode Incline -1.630000. Responding: 80 11 01 + 134605 [1970988][E](DirConManager): Sending response message type 0x04 to client 0 + 134606 [1971991][E](FTMS_SERVER): 11 00 00 c6 ff 28 33 -> Sim Mode Incline -0.580000. Responding: 80 11 01 + 134607 [1971999][E](DirConManager): Sending response message type 0x04 to client 0 + 134608 [1972886][E](FTMS_SERVER): 11 00 00 cd 00 28 33 -> Sim Mode Incline 2.050000. Responding: 80 11 01 + 134609 [1972892][E](DirConManager): Sending response message type 0x04 to client 0 + 134610 [1973827][E](FTMS_SERVER): 11 00 00 db 01 28 33 -> Sim Mode Incline 4.750000. Responding: 80 11 01 + 134611 [1973832][E](DirConManager): Sending response message type 0x04 to client 0 + 134612 [1974850][E](FTMS_SERVER): 11 00 00 6f 02 28 33 -> Sim Mode Incline 6.230000. Responding: 80 11 01 + 134613 [1974855][E](DirConManager): Sending response message type 0x04 to client 0 + 134614 [1975891][E](FTMS_SERVER): 11 00 00 be 02 28 33 -> Sim Mode Incline 7.020000. Responding: 80 11 01 + 134615 [1975897][E](DirConManager): Sending response message type 0x04 to client 0 + 134616 [1976310][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 102, Gear 0, Res 14, Current Pos 4622, Target Pos 4914 + 134617 [1976788][E](FTMS_SERVER): 11 00 00 d8 02 28 33 -> Sim Mode Incline 7.280000. Responding: 80 11 01 + 134618 [1976795][E](DirConManager): Sending response message type 0x04 to client 0 + 134619 [1977718][E](FTMS_SERVER): 11 00 00 cd 02 28 33 -> Sim Mode Incline 7.170000. Responding: 80 11 01 + 134620 [1977725][E](DirConManager): Sending response message type 0x04 to client 0 + 134621 [1978620][E](FTMS_SERVER): 11 00 00 b9 02 28 33 -> Sim Mode Incline 6.970000. Responding: 80 11 01 + 134622 [1978626][E](DirConManager): Sending response message type 0x04 to client 0 + 134623 [1979659][E](FTMS_SERVER): 11 00 00 a2 02 28 33 -> Sim Mode Incline 6.740000. Responding: 80 11 01 + 134624 [1979664][E](DirConManager): Sending response message type 0x04 to client 0 + 134625 [1980591][E](FTMS_SERVER): 11 00 00 92 02 28 33 -> Sim Mode Incline 6.580000. Responding: 80 11 01 + 134626 [1980596][E](DirConManager): Sending response message type 0x04 to client 0 + 134627 [1981608][E](FTMS_SERVER): 11 00 00 8e 02 28 33 -> Sim Mode Incline 6.540000. Responding: 80 11 01 + 134628 [1981615][E](DirConManager): Sending response message type 0x04 to client 0 + 134629 [1982325][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 98, Gear 0, Res 15, Current Pos 4578, Target Pos 4578 + 134630 [1988338][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 96, Gear 0, Res 15, Current Pos 4578, Target Pos 4578 + 134631 [1994351][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 94, Gear 0, Res 15, Current Pos 4578, Target Pos 4578 + 134632 [2000362][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 95, Gear 0, Res 15, Current Pos 4578, Target Pos 4578 + 134633 [2005868][E](FTMS_SERVER): 11 00 00 80 02 28 33 -> Sim Mode Incline 6.400000. Responding: 80 11 01 + 134634 [2005875][E](DirConManager): Sending response message type 0x04 to client 0 + 134635 [2006376][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 98, Gear 0, Res 15, Current Pos 4480, Target Pos 4480 + 134636 [2006825][E](FTMS_SERVER): 11 00 00 7f 02 28 33 -> Sim Mode Incline 6.390000. Responding: 80 11 01 + 134637 [2006832][E](DirConManager): Sending response message type 0x04 to client 0 + 134638 [2012388][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 94, Gear 0, Res 15, Current Pos 4473, Target Pos 4473 + 134639 [2018399][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 92, Gear 0, Res 15, Current Pos 4473, Target Pos 4473 + 134640 [2024408][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 89, Gear 0, Res 15, Current Pos 4473, Target Pos 4473 + 134641 [2030421][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 88, Gear 0, Res 15, Current Pos 4473, Target Pos 4473 + 134642 [2036437][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 88, Gear 0, Res 15, Current Pos 4473, Target Pos 4473 + 134643 [2042450][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 84, Gear 0, Res 15, Current Pos 4473, Target Pos 4473 + 134644 [2043869][E](FTMS_SERVER): 11 00 00 7a 02 28 33 -> Sim Mode Incline 6.340000. Responding: 80 11 01 + 134645 [2043873][E](DirConManager): Sending response message type 0x04 to client 0 + 134646 [2044778][E](FTMS_SERVER): 11 00 00 74 02 28 33 -> Sim Mode Incline 6.280000. Responding: 80 11 01 + 134647 [2044785][E](DirConManager): Sending response message type 0x04 to client 0 + 134648 [2048462][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 85, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134649 [2054475][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 90, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134650 [2060492][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 93, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134651 [2066508][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 91, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134652 [2072522][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 84, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134653 [2078533][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 82, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134654 [2084542][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 83, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134655 [2090558][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 84, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134656 [2096575][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 83, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134657 [2102585][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 84, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134658 [2108597][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 82, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134659 [2114612][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 83, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134660 [2120622][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 83, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134661 [2126637][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 82, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134662 [2132649][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 82, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134663 [2138662][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 82, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134664 [2144674][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 81, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134665 [2150687][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 81, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134666 [2156698][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 82, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134667 [2162714][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 81, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134668 [2168727][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 82, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134669 [2174744][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 81, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134670 [2180756][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 81, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134671 [2186773][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 81, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134672 [2192787][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 82, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134673 [2198801][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 82, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134674 [2204815][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 79, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134675 [2210833][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 82, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134676 [2216848][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 81, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134677 [2222865][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 83, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134678 [2228882][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 84, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134679 [2229282][E](BLE_Client): Client e8:fe:6e:91:9f:16 Disconnected, reason = 531 + 134680 [2229283][E](BLE_Client): Detected 0x1818 Disconnect + 134681 [2229283][E](BLE_Client): Deregistered PM on Disconnect + 134682 [2229296][E](BLE_Client): Resetting Device: ASSIOMA17287L 16 + 134683 [2232405][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134684 [2232405][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134685 [2232967][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134686 [2233964][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134687 [2233964][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134688 [2233976][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134689 [2234895][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 85, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134690 [2236430][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134691 [2238496][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134692 [2238497][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134693 [2238599][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134694 [2238599][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134695 [2238613][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134696 [2239599][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134697 [2240909][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 90, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134698 [2242521][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134699 [2244578][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134700 [2244579][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134701 [2244609][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134702 [2244610][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134703 [2244621][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134704 [2246927][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 86, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134705 [2248458][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134706 [2248609][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134707 [2250668][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134708 [2250669][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134709 [2251593][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134710 [2251593][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134711 [2251604][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134712 [2252331][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134713 [2252935][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 85, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134714 [2254709][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134715 [2256787][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134716 [2256788][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134717 [2257323][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134718 [2257324][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134719 [2257335][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134720 [2258151][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134721 [2258944][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 88, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134722 [2260814][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134723 [2262863][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134724 [2262864][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134725 [2263358][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134726 [2263742][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134727 [2263743][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134728 [2263756][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134729 [2264957][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 92, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134730 [2266897][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134731 [2268956][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134732 [2268957][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134733 [2269721][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134734 [2270851][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134735 [2270852][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134736 [2270862][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134737 [2270972][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 87, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134738 [2272984][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134739 [2275046][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134740 [2275047][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134741 [2276370][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134742 [2276594][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134743 [2276596][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134744 [2276606][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134745 [2276984][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 85, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134746 [2279073][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134747 [2281130][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134748 [2281131][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134749 [2281461][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134750 [2281461][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134751 [2281472][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134752 [2281618][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134753 [2282995][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 83, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134754 [2285156][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134755 [2287208][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134756 [2287209][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134757 [2287601][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134758 [2287601][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134759 [2287612][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134760 [2289005][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 85, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134761 [2290219][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134762 [2291232][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134763 [2293293][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134764 [2293294][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134765 [2293368][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134766 [2293368][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134767 [2293379][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134768 [2295021][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 85, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134769 [2296018][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134770 [2297318][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134771 [2299377][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134772 [2299378][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134773 [2299620][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134774 [2299917][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134775 [2299917][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134776 [2299928][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134777 [2301032][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 90, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134778 [2303404][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134779 [2305467][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134780 [2305468][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134781 [2305502][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134782 [2305503][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134783 [2305513][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134784 [2307048][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 84, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134785 [2307075][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134786 [2309494][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134787 [2311557][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134788 [2311558][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134789 [2312610][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134790 [2312621][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134791 [2312622][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134792 [2312632][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134793 [2313057][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 85, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134794 [2315583][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134795 [2317636][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134796 [2317637][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134797 [2318151][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134798 [2318360][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134799 [2318360][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134800 [2318371][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134801 [2319071][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 91, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134802 [2321666][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134803 [2323717][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134804 [2323718][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134805 [2324373][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134806 [2324374][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134807 [2324384][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134808 [2325084][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 87, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134809 [2325907][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134810 [2327740][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134811 [2329810][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134812 [2329811][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134813 [2329838][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134814 [2329838][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134815 [2329851][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134816 [2330625][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134817 [2331095][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 82, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134818 [2333848][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134819 [2335892][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134820 [2335893][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134821 [2335978][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134822 [2335979][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134823 [2335992][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134824 [2337111][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 79, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134825 [2338914][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134826 [2339925][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134827 [2341980][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134828 [2341981][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134829 [2343124][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 80, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134830 [2344073][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134831 [2344073][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134832 [2344085][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134833 [2345008][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134834 [2346007][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134835 [2348056][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134836 [2348057][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134837 [2348436][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 134838 [2348437][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 134839 [2348447][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 134840 [2348875][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134841 [2349133][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 82, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134842 [2352089][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134843 [2354153][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134844 [2354154][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134845 [2354680][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134846 [2355144][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 82, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134847 [2358179][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134848 [2360230][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134849 [2360231][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134850 [2361162][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 82, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134851 [2362033][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134852 [2364264][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134853 [2366321][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134854 [2366322][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134855 [2367178][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 82, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134856 [2370058][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134857 [2370344][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134858 [2372402][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134859 [2372403][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134860 [2372559][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134861 [2373194][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 82, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134862 [2376428][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134863 [2378490][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134864 [2378491][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134865 [2379205][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 83, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134866 [2380284][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134867 [2382513][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134868 [2384582][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134869 [2384582][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134870 [2385223][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 83, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134871 [2385538][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134872 [2388605][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134873 [2390666][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134874 [2390667][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134875 [2391238][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 84, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134876 [2391621][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134877 [2394689][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134878 [2396750][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134879 [2396751][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134880 [2397044][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134881 [2397254][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 85, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134882 [2400775][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134883 [2402825][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134884 [2402825][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134885 [2403134][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134886 [2403267][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 84, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134887 [2406852][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134888 [2408911][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134889 [2408912][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134890 [2409277][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 83, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134891 [2410333][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134892 [2411336][E](BLE_Client): Found device c8:27:52:ec:ec:1c with services: 0xfeaf + 134893 [2412936][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134894 [2414994][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134895 [2414995][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134896 [2415289][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 83, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134897 [2415855][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134898 [2419019][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134899 [2421091][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134900 [2421092][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134901 [2421303][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 83, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134902 [2421669][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134903 [2425116][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134904 [2427170][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134905 [2427171][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134906 [2427208][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134907 [2427320][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 81, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134908 [2431192][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134909 [2433243][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134910 [2433244][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134911 [2433330][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 82, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134912 [2433569][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134913 [2437273][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134914 [2439328][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134915 [2439329][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134916 [2439339][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 84, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134917 [2442980][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134918 [2443352][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134919 [2445362][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 85, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134920 [2445406][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134921 [2445407][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134922 [2446030][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134923 [2449430][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134924 [2451382][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 90, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134925 [2451485][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134926 [2451486][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134927 [2451560][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134928 [2455517][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134929 [2457397][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 87, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134930 [2457569][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134931 [2457569][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134932 [2460684][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134933 [2461408][E](BLE_Client): Found device c8:27:52:ec:ec:1c with services: 0xfeaf + 134934 [2461595][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134935 [2463414][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 90, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134936 [2463645][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134937 [2463646][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134938 [2464569][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134939 [2467668][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134940 [2469429][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 96, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134941 [2469756][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134942 [2469756][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134943 [2470100][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134944 [2473782][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134945 [2475447][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 96, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134946 [2475837][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134947 [2475838][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134948 [2475929][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134949 [2479870][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134950 [2481460][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 98, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134951 [2481923][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134952 [2481924][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134953 [2481994][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134954 [2485948][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134955 [2487473][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 104, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134956 [2488010][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134957 [2488011][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134958 [2488644][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134959 [2492033][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134960 [2493486][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 105, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134961 [2494084][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134962 [2494085][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134963 [2498106][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134964 [2499499][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 99, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134965 [2500168][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134966 [2500168][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134967 [2500837][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134968 [2504203][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 134969 [2505513][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 0, Res 14, Current Pos 4396, Target Pos 4396 + 134970 [2506253][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134971 [2506254][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134972 [2509703][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 134973 [ 55][E](Main): Compiled Jan 4 202617:54:44 + 134974 [ 56][E](Main): Current Board Revision is: Revision Two + 134975 [ 58][E](Main): Mounting Filesystem + 134976 [ 64][E](Config): Reading File: /config.txt + 134977 [ 97][E](Config): Config File Loaded: /config.txt + 134978 [ 98][E](Config): Contents of file: /config.txt + 134979 [ 133][E](Config): Writing File: /config.txt + 134980 [ 202][E](Main): Using homing data from config file. + 134981 [ 338][E](HTTP_Server): Build version check. FS:'25.12.28-Marc_Roy-15-g808c554' CUR:'25.12.28-Marc_Roy-15-g808c554' + 134982 [ 338][E](HTTP_Server): Connecting to: NetwalkerLair + 134983 [ 1463][E](HTTP_Server): Waiting for connection to be established... + 134984 [ 2463][E](HTTP_Server): Waiting for connection to be established... + 134985 [ 2472][E](HTTP_Server): Connected to NetwalkerLair IP address: 192.168.1.180 + 134986 [ 2472][E](HTTP_Server): Open http://SmartPelo.local/ + 134987 [ 2483][E](DirConManager): Adding DirCon MDNS service: _wahoo-fitness-tnp.tcp on port 8081 + 134988 [ 4504][E](BLE_Server): Bluetooth Remote Client Connected: 57:7c:3d:29:a0:c1 Connected Clients: 1 + 134989 [ 5525][E](BLE_Server): MTU updated: 512 for connection ID: 0 + 134990 [ 5899][E](BLE_Server): MTU updated: 512 for connection ID: 0 + 134991 [ 6675][E](BLE_Server): MTU updated: 515 for connection ID: 0 + 134992 [ 6696][E](BLE_Server): Client ID: 0 Address: 57:7c:3d:29:a0:c1 Subscribed to notifications for 0x2ad2 + 134993 [ 6718][E](Custom_C): Subscribe from 57:7c:3d:29:a0:c1 + 134994 [ 8430][E](BLE_Server): MTU updated: 515 for connection ID: 0 + 134995 [ 8859][E](BLE_Server): MTU updated: 515 for connection ID: 0 + 134996 [ 9983][E](Main): PM Con 0, CAD con 0, HRM Con 0, W 0, Cad 0, HR 0, Gear 0, Res 0, Current Pos 0, Target Pos 0 + 134997 [ 10091][E](BLE_Client): Devices not connected: HRM PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 134998 [ 10101][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 134999 [ 10123][E](BLE_Client): Found device Polar OH1 B9B6D624 d6 with services: 0x180d 0xfeee + 135000 [ 10123][E](BLE_Client): Supported Device: Polar OH1 B9B6D624 d6 with service Heart Rate Service + 135001 [ 10134][E](BLE_Client): HRM Name Matched Polar OH1 B9B6D624 d6 + 135002 [ 10136][E](BLE_Client): Setting Device Polar OH1 B9B6D624 d6 + 135003 [ 10147][E](BLE_Client): Set Polar OH1 B9B6D624 d6 with no current connection. + 135004 [ 10148][E](BLE_Client): Polar OH1 B9B6D624 d6 assigned slot: 0 + 135005 [ 10204][E](BLE_Client): Stopping scan before connecting Polar OH1 B9B6D624 d6 on slot 0 ... + 135006 [ 10307][E](BLE_Client): Connecting Polar OH1 B9B6D624 d6 on slot 0 ... + 135007 [ 10308][E](BLE_Client): Initiating Server Connection + 135008 [ 10308][E](BLE_Client): Connecting slot 0 + 135009 [ 10319][E](BLE_Client): Getting service info for device: Polar OH1 B9B6D624 with 2 services + 135010 [ 10330][E](BLE_Client): Trying to connect to Heart Rate Service (Service UUID: 0x180d) + 135011 [ 10331][E](BLE_Client): Forming a connection to: Polar OH1 B9B6D624 d6 + 135012 [ 10341][E](BLE_Client): - Created new client + 135013 [ 11297][E](BLE_Client): Connected, a0:9e:1a:b9:b6:d6 + 135014 [ 11298][E](BLE_Client): Connected to: Polar OH1 B9B6D624 d6 - a0:9e:1a:b9:b6:d6 RSSI -71 + 135015 [ 11299][E](BLE_Client): Setting Device Polar OH1 B9B6D624 d6 + 135016 [ 12258][E](BLE_Client): Registered HRM on Connect + 135017 [ 12259][E](BLE_Client): Device Connected + 135018 [ 12260][E](BLE_Client): We are now connected to Polar OH1 B9B6D624 d6 + 135019 [ 12372][E](BLE_Client): Post connecting: Polar OH1 B9B6D624 d6 , ConnID 1, PrimaryChar 0x2a37 + 135020 [ 13333][E](BLE_Client): Found Heart Rate Service + 135021 [ 13558][E](BLE_Client): Found 0x180d, 0x2a37 + 135022 [ 13785][E](BLE_Client): Subscribed to Heart Rate Service 0x2a37 handle: 40 + 135023 [ 15246][E](BLE_Client): a0:9e:1a:b9:b6:d6 Battery updated 90 + 135024 [ 15998][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 107, Gear 0, Res 0, Current Pos 0, Target Pos 0 + 135025 [ 16144][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 135026 [ 16145][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 135027 [ 17020][E](BLE_Client): Found device ASSIOMA59350R d5 with services: 0x180f 6e400001-b5a3-f393-e0a9-e50e24dcca9e + 135028 [ 17684][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 135029 [ 17685][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 135030 [ 17696][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 135031 [ 17740][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 135032 [ 18232][E](BLE_Client): Found device ASSIOMA17287L 16 with services: 0x1818 0x180f 6e400001-b5a3-f393-e0a9-e50e24dcca9e + 135033 [ 18233][E](BLE_Client): Supported Device: ASSIOMA17287L 16 with service Cycling Power Service + 135034 [ 18243][E](BLE_Client): PM Name Matched ASSIOMA17287L 16 + 135035 [ 18254][E](BLE_Client): Slot 0 contains Polar OH1 B9B6D624 d6 + 135036 [ 18255][E](BLE_Client): Setting Device ASSIOMA17287L 16 + 135037 [ 18266][E](BLE_Client): Set ASSIOMA17287L 16 with no current connection. + 135038 [ 18266][E](BLE_Client): ASSIOMA17287L 16 assigned slot: 1 + 135039 [ 18283][E](BLE_Client): Stopping scan before connecting ASSIOMA17287L 16 on slot 1 ... + 135040 [ 18387][E](BLE_Client): Connecting ASSIOMA17287L 16 on slot 1 ... + 135041 [ 18388][E](BLE_Client): Initiating Server Connection + 135042 [ 18388][E](BLE_Client): doConnect on slot 0 not set + 135043 [ 18399][E](BLE_Client): Connecting slot 1 + 135044 [ 18399][E](BLE_Client): Getting service info for device: ASSIOMA17287L with 3 services + 135045 [ 18416][E](BLE_Client): Trying to connect to Cycling Power Service (Service UUID: 0x1818) + 135046 [ 18417][E](BLE_Client): Forming a connection to: ASSIOMA17287L 16 + 135047 [ 18428][E](BLE_Client): - Created new client + 135048 [ 19326][E](BLE_Client): Connected, e8:fe:6e:91:9f:16 + 135049 [ 19329][E](BLE_Client): Connected to: ASSIOMA17287L 16 - e8:fe:6e:91:9f:16 RSSI -66 + 135050 [ 19330][E](BLE_Client): Setting Device ASSIOMA17287L 16 + 135051 [ 19834][E](BLE_Client): Registered PM on Connect + 135052 [ 19835][E](BLE_Client): Device Connected + 135053 [ 19835][E](BLE_Client): We are now connected to ASSIOMA17287L 16 + 135054 [ 19947][E](BLE_Client): Post connecting: ASSIOMA17287L 16 , ConnID 2, PrimaryChar 0x2a63 + 135055 [ 19951][E](BLE_Client): Found Cycling Power Service + 135056 [ 20394][E](BLE_Client): Found 0x1818, 0x2a63 + 135057 [ 20676][E](BLE_Client): Subscribed to Cycling Power Service 0x2a63 handle: 22 + 135058 [ 20676][E](BLE_Client): Found 0x1818, 0x2a65 + 135059 [ 20676][E](BLE_Client): Found 0x1818, 0x2a66 + 135060 [ 20957][E](BLE_Client): Subscribed to Cycling Power Service 0x2a66 handle: 27 + 135061 [ 20958][E](BLE_Client): Found 0x1818, 0x2a5d + 135062 [ 22009][E](Main): PM Con 1, CAD con 0, HRM Con 1, W 0, Cad 0, HR 106, Gear 0, Res 0, Current Pos 0, Target Pos 0 + 135063 [ 22419][E](BLE_Client): Found Flywheel UART Service + 135064 [ 22926][E](BLE_Client): Found 6e400001-b5a3-f393-e0a9-e50e24dcca9e, 6e400003-b5a3-f393-e0a9-e50e24dcca9e + 135065 [ 23263][E](BLE_Client): Subscribed to Flywheel UART Service 6e400003-b5a3-f393-e0a9-e50e24dcca9e handle: 13 + 135066 [ 23264][E](BLE_Client): Found 6e400001-b5a3-f393-e0a9-e50e24dcca9e, 6e400004-b5a3-f393-e0a9-e50e24dcca9e + 135067 [ 23544][E](BLE_Client): Subscribed to Flywheel UART Service 6e400004-b5a3-f393-e0a9-e50e24dcca9e handle: 16 + 135068 [ 23545][E](BLE_Client): Found 6e400001-b5a3-f393-e0a9-e50e24dcca9e, 6e400002-b5a3-f393-e0a9-e50e24dcca9e + 135069 [ 23995][E](BLE_Client): e8:fe:6e:91:9f:16 Battery updated 98 + 135070 [ 26152][E](BLE_Client): Spin Down initiated via BLE Client task. + 135071 [ 26153][E](Main): Starting homing procedure... + 135072 [ 27412][E](Main): Stepper power is now 720. read:703 + 135073 [ 27939][E](Main): Homing backward (min). Stable Threshold: 328, Sensitivity: 50 + 135074 [ 27949][E](Main): Homing... Current SG: 364, Baseline: 328, Target: < 278 + 135075 [ 28021][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 21, Cad 72, HR 101, Gear 0, Res 0, Current Pos 0, Target Pos 0 + 135076 [ 28951][E](Main): Homing... Current SG: 358, Baseline: 328, Target: < 278 + 135077 [ 29954][E](Main): Homing... Current SG: 366, Baseline: 328, Target: < 278 + 135078 [ 30962][E](Main): Homing... Current SG: 362, Baseline: 328, Target: < 278 + 135079 [ 31965][E](Main): Homing... Current SG: 364, Baseline: 328, Target: < 278 + 135080 [ 32147][E](Main): Stall detected! SG dropped to 276. Threshold: 278 + 135081 [ 32265][E](Main): StealthChop is now 1 + 135082 [ 32282][E](Main): Stepper power is now 900. read:703 + 135083 [ 33540][E](Main): Stepper power is now 720. read:703 + 135084 [ 34031][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 75, HR 99, Gear 0, Res 0, Current Pos -5585, Target Pos 0 + 135085 [ 34068][E](Main): Homing backward (min). Stable Threshold: 328, Sensitivity: 50 + 135086 [ 34077][E](Main): Homing... Current SG: 364, Baseline: 328, Target: < 278 + 135087 [ 34557][E](Main): Stall detected! SG dropped to 258. Threshold: 278 + 135088 [ 34676][E](Main): StealthChop is now 1 + 135089 [ 34693][E](Main): Stepper power is now 900. read:703 + 135090 [ 35937][E](Main): Min position found and set to 0. + 135091 [ 35956][E](Main): StealthChop is now 1 + 135092 [ 35978][E](Main): Stepper power is now 900. read:887 + 135093 [ 35979][E](Main): Homing procedure complete. + 135094 [ 35982][E](Main): Shift +8 pos 8 tgt 9600 min 0 max 29566 r_min -2000 r_max 2000 + 135095 [ 35994][E](PTable): Loading Power Table.... + 135096 [ 36024][E](PTable): Loading power table version 6, Size 328, Homed 1 + 135097 [ 36061][E](PTable): Loaded values directly + 135098 [ 38823][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 135099 [ 38824][E](PTable): Power Buffer Reset + 135100 [ 40047][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 7, Cad 79, HR 99, Gear 8, Res 32, Current Pos 9600, Target Pos 9600 + 135101 [ 43795][E](PTable): Failed to Load Power Table. + 135102 [ 43954][E](PTable): Not enough valid readings to save power table (0) + 135103 [ 43969][E](Config): Writing File: /config.txt + 135104 [ 44402][E](Config): Writing File: /config.txt + 135105 [ 44475][E](Config): Writing File: /config.txt + 135106 [ 46061][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 49, Cad 77, HR 98, Gear 8, Res 32, Current Pos 9600, Target Pos 9600 + 135107 [ 48059][E](PTable): Averaged Entry: watts=49.400002, cad=75.199997, targetPosition=960.000000, (3)(2) + 135108 [ 48060][E](PTData): New entry recorded (3)(2)(960) + 135109 [ 48071][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 135110 [ 48073][E](PTable): New Entry Processed in 15 ms + 135111 [ 48083][E](PTable): Power Buffer Reset + 135112 [ 50819][E](BLE_Server): MTU updated: 515 for connection ID: 0 + 135113 [ 52072][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 50, Cad 75, HR 98, Gear 8, Res 32, Current Pos 9600, Target Pos 9600 + 135114 [ 54411][E](PTable): Averaged Entry: watts=49.700001, cad=75.199997, targetPosition=960.000000, (3)(2) + 135115 [ 54412][E](PTData): Existing entry averaged (3)(2)(960), readings(2) + 135116 [ 54423][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 135117 [ 54425][E](PTable): New Entry Processed in 15 ms + 135118 [ 54436][E](PTable): Power Buffer Reset + 135119 [ 54532][E](BLE_Server): MTU updated: 515 for connection ID: 0 + 135120 [ 58083][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 50, Cad 75, HR 100, Gear 8, Res 32, Current Pos 9600, Target Pos 9600 + 135121 [ 58407][E](FTMS_SERVER): 13 01 -> Spin Down Requested. Responding: 80 13 01 + 135122 [ 60297][E](BLE_Client): Spin Down initiated via BLE Client task. + 135123 [ 60298][E](Main): Starting homing procedure... + 135124 [ 60298][E](FTMS_SERVER): Sent SpinDown Status: 0x01 + 135125 [ 61567][E](Main): Stepper power is now 720. read:703 + 135126 [ 62093][E](Main): Homing backward (min). Stable Threshold: 324, Sensitivity: 50 + 135127 [ 62103][E](Main): Homing... Current SG: 364, Baseline: 324, Target: < 274 + 135128 [ 63105][E](Main): Homing... Current SG: 364, Baseline: 324, Target: < 274 + 135129 [ 64099][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 65, Cad 78, HR 103, Gear 8, Res 32, Current Pos 9600, Target Pos 9600 + 135130 [ 64107][E](Main): Homing... Current SG: 368, Baseline: 324, Target: < 274 + 135131 [ 65121][E](Main): Homing... Current SG: 368, Baseline: 324, Target: < 274 + 135132 [ 66125][E](Main): Homing... Current SG: 362, Baseline: 324, Target: < 274 + 135133 [ 67129][E](Main): Homing... Current SG: 356, Baseline: 324, Target: < 274 + 135134 [ 68138][E](Main): Homing... Current SG: 366, Baseline: 324, Target: < 274 + 135135 [ 69148][E](Main): Homing... Current SG: 360, Baseline: 324, Target: < 274 + 135136 [ 69784][E](Main): Stall detected! SG dropped to 244. Threshold: 274 + 135137 [ 69904][E](Main): StealthChop is now 1 + 135138 [ 69921][E](Main): Stepper power is now 900. read:703 + 135139 [ 70114][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 7, Cad 81, HR 104, Gear 8, Res 32, Current Pos -1205, Target Pos 9600 + 135140 [ 71181][E](Main): Stepper power is now 720. read:703 + 135141 [ 71706][E](Main): Homing backward (min). Stable Threshold: 327, Sensitivity: 50 + 135142 [ 71716][E](Main): Homing... Current SG: 364, Baseline: 327, Target: < 277 + 135143 [ 72262][E](Main): Stall detected! SG dropped to 246. Threshold: 277 + 135144 [ 72380][E](Main): StealthChop is now 1 + 135145 [ 72399][E](Main): Stepper power is now 900. read:703 + 135146 [ 73643][E](Main): Min position found and set to 0. + 135147 [ 73644][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135148 [ 73659][E](Main): Stepper power is now 720. read:703 + 135149 [ 74183][E](Main): Homing forward (max). Stable Threshold: 325, Sensitivity: 50 + 135150 [ 74198][E](Main): Homing... Current SG: 362, Baseline: 325, Target: < 275 + 135151 [ 74198][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135152 [ 75203][E](Main): Homing... Current SG: 366, Baseline: 325, Target: < 275 + 135153 [ 75204][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135154 [ 76129][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 7, Cad 83, HR 105, Gear 8, Res 0, Current Pos -1306, Target Pos 0 + 135155 [ 76207][E](Main): Homing... Current SG: 352, Baseline: 325, Target: < 275 + 135156 [ 76208][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135157 [ 77209][E](Main): Homing... Current SG: 356, Baseline: 325, Target: < 275 + 135158 [ 77210][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135159 [ 78217][E](Main): Homing... Current SG: 362, Baseline: 325, Target: < 275 + 135160 [ 78217][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135161 [ 78910][E](BLE_Server): MTU updated: 515 for connection ID: 0 + 135162 [ 79226][E](Main): Homing... Current SG: 352, Baseline: 325, Target: < 275 + 135163 [ 79227][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135164 [ 80234][E](Main): Homing... Current SG: 356, Baseline: 325, Target: < 275 + 135165 [ 80235][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135166 [ 81258][E](Main): Homing... Current SG: 358, Baseline: 325, Target: < 275 + 135167 [ 81258][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135168 [ 82144][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 36, Cad 81, HR 103, Gear 8, Res 0, Current Pos -1306, Target Pos 0 + 135169 [ 82262][E](Main): Homing... Current SG: 348, Baseline: 325, Target: < 275 + 135170 [ 82263][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135171 [ 83266][E](Main): Homing... Current SG: 358, Baseline: 325, Target: < 275 + 135172 [ 83267][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135173 [ 84275][E](Main): Homing... Current SG: 352, Baseline: 325, Target: < 275 + 135174 [ 84276][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135175 [ 85278][E](Main): Homing... Current SG: 356, Baseline: 325, Target: < 275 + 135176 [ 85278][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135177 [ 86290][E](Main): Homing... Current SG: 354, Baseline: 325, Target: < 275 + 135178 [ 86290][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135179 [ 87322][E](Main): Homing... Current SG: 358, Baseline: 325, Target: < 275 + 135180 [ 87325][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135181 [ 88160][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 185, Cad 62, HR 101, Gear 8, Res 0, Current Pos -1306, Target Pos 0 + 135182 [ 88331][E](Main): Homing... Current SG: 364, Baseline: 325, Target: < 275 + 135183 [ 88331][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135184 [ 89336][E](Main): Homing... Current SG: 360, Baseline: 325, Target: < 275 + 135185 [ 89337][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135186 [ 89712][E](DirConManager): New DirCon client connected from 192.168.1.106, assigned slot 0 + 135187 [ 89814][E](DirConMessage): Discover services response contains 0 UUIDs + 135188 [ 89815][E](DirConManager): Initialized service discovery with 4 services + 135189 [ 89825][E](DirConManager): Received service discovery request from client 0 + 135190 [ 89825][E](DirConManager): Responding with 4 service UUIDs + 135191 [ 89836][E](DirConManager): Sending response message type 0x01 to client 0 + 135192 [ 89836][E](DirConManager): Discover services response contains 4 UUIDs + 135193 [ 89847][E](DirConManager): Service 0: 0x1818 + 135194 [ 89847][E](DirConManager): Service 1: 0x1816 + 135195 [ 89857][E](DirConManager): Service 2: 0x180d + 135196 [ 89858][E](DirConManager): Service 3: 0x1826 + 135197 [ 89858][E](DirConMessage): Adding 4 service UUIDs to discovery response + 135198 [ 89869][E](DirConMessage): Adding service 0 UUID: 0x1818 + 135199 [ 89869][E](DirConMessage): Adding service 1 UUID: 0x1816 + 135200 [ 89879][E](DirConMessage): Adding service 2 UUID: 0x180d + 135201 [ 90014][E](DirConManager): Sending response message type 0x02 to client 0 + 135202 [ 90102][E](DirConManager): Sending response message type 0x02 to client 0 + 135203 [ 90117][E](DirConManager): Sending response message type 0x02 to client 0 + 135204 [ 90141][E](DirConManager): Sending response message type 0x02 to client 0 + 135205 [ 90187][E](DirConManager): Sending response message type 0x03 to client 0 + 135206 [ 90190][E](DirConManager): Client 0 subscribed to characteristic 00002a63-0000-1000-8000-00805f9b34fb + 135207 [ 90201][E](DirConManager): Sending response message type 0x05 to client 0 + 135208 [ 90216][E](DirConManager): Client 0 subscribed to characteristic 00002a5b-0000-1000-8000-00805f9b34fb + 135209 [ 90216][E](DirConManager): Sending response message type 0x05 to client 0 + 135210 [ 90314][E](DirConManager): Sending response message type 0x03 to client 0 + 135211 [ 90344][E](Main): Homing... Current SG: 364, Baseline: 325, Target: < 275 + 135212 [ 90345][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135213 [ 91354][E](Main): Homing... Current SG: 358, Baseline: 325, Target: < 275 + 135214 [ 91354][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135215 [ 92359][E](Main): Homing... Current SG: 358, Baseline: 325, Target: < 275 + 135216 [ 92361][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135217 [ 93263][E](FTMS_SERVER): 11 00 00 4a 02 28 33 -> Sim Mode Incline 5.860000. Responding: 80 11 01 + 135218 [ 93270][E](DirConManager): Sending response message type 0x04 to client 0 + 135219 [ 93367][E](Main): Homing... Current SG: 364, Baseline: 325, Target: < 275 + 135220 [ 93368][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135221 [ 94179][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 160, Cad 0, HR 106, Gear 8, Res 0, Current Pos -1306, Target Pos 0 + 135222 [ 94223][E](FTMS_SERVER): 11 00 00 31 02 28 33 -> Sim Mode Incline 5.610000. Responding: 80 11 01 + 135223 [ 94228][E](DirConManager): Sending response message type 0x04 to client 0 + 135224 [ 94259][E](Main): Stall detected! SG dropped to 274. Threshold: 275 + 135225 [ 94378][E](Main): StealthChop is now 1 + 135226 [ 94397][E](Main): Stepper power is now 900. read:703 + 135227 [ 95229][E](FTMS_SERVER): 11 00 00 0e 02 28 33 -> Sim Mode Incline 5.260000. Responding: 80 11 01 + 135228 [ 95234][E](DirConManager): Sending response message type 0x04 to client 0 + 135229 [ 95655][E](Main): Stepper power is now 720. read:703 + 135230 [ 96118][E](FTMS_SERVER): 11 00 00 e6 01 28 33 -> Sim Mode Incline 4.860000. Responding: 80 11 01 + 135231 [ 96126][E](DirConManager): Sending response message type 0x04 to client 0 + 135232 [ 96196][E](Main): Homing forward (max). Stable Threshold: 317, Sensitivity: 50 + 135233 [ 96205][E](Main): Homing... Current SG: 340, Baseline: 317, Target: < 267 + 135234 [ 96206][E](FTMS_SERVER): Sent SpinDown Status: 0x04 + 135235 [ 96653][E](Main): Stall detected! SG dropped to 266. Threshold: 267 + 135236 [ 96772][E](Main): StealthChop is now 1 + 135237 [ 96802][E](Main): Stepper power is now 900. read:703 + 135238 [ 96803][E](Main): Max Position found: 29356 + 135239 [ 96822][E](Config): Writing File: /config.txt + 135240 [ 96876][E](Main): StealthChop is now 1 + 135241 [ 96895][E](Main): Stepper power is now 900. read:703 + 135242 [ 96896][E](FTMS_SERVER): Sent SpinDown Status: 0x02 + 135243 [ 96915][E](Config): Writing File: /config.txt + 135244 [ 96961][E](Config): Writing File: /config.txt + 135245 [ 97015][E](Main): Homing procedure complete. + 135246 [ 97022][E](Main): Shift -8 pos 0 tgt 3402 min 0 max 29356 r_min -2000 r_max 2000 + 135247 [ 97022][E](Main): Shift Blocked by stepper limits. + 135248 [ 97039][E](FTMS_SERVER): 11 00 00 cd 01 28 33 -> Sim Mode Incline 4.610000. Responding: 80 11 01 + 135249 [ 97046][E](DirConManager): Sending response message type 0x04 to client 0 + 135250 [ 98062][E](FTMS_SERVER): 11 00 00 c6 01 28 33 -> Sim Mode Incline 4.540000. Responding: 80 11 01 + 135251 [ 98070][E](DirConManager): Sending response message type 0x04 to client 0 + 135252 [100192][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 109, Gear 8, Res 75, Current Pos 21135, Target Pos 12778 + 135253 [103524][E](FTMS_SERVER): 11 00 00 c0 01 28 33 -> Sim Mode Incline 4.480000. Responding: 80 11 01 + 135254 [103531][E](DirConManager): Sending response message type 0x04 to client 0 + 135255 [104518][E](FTMS_SERVER): 11 00 00 a5 01 28 33 -> Sim Mode Incline 4.210000. Responding: 80 11 01 + 135256 [104526][E](DirConManager): Sending response message type 0x04 to client 0 + 135257 [105441][E](FTMS_SERVER): 11 00 00 76 01 28 33 -> Sim Mode Incline 3.740000. Responding: 80 11 01 + 135258 [105448][E](DirConManager): Sending response message type 0x04 to client 0 + 135259 [105502][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 135260 [105502][E](PTable): Power Buffer Reset + 135261 [106201][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 158, Cad 65, HR 104, Gear 8, Res 42, Current Pos 12218, Target Pos 12218 + 135262 [106454][E](FTMS_SERVER): 11 00 00 39 01 28 33 -> Sim Mode Incline 3.130000. Responding: 80 11 01 + 135263 [106462][E](DirConManager): Sending response message type 0x04 to client 0 + 135264 [107423][E](FTMS_SERVER): 11 00 00 09 01 28 33 -> Sim Mode Incline 2.650000. Responding: 80 11 01 + 135265 [107430][E](DirConManager): Sending response message type 0x04 to client 0 + 135266 [108430][E](FTMS_SERVER): 11 00 00 e4 00 28 33 -> Sim Mode Incline 2.280000. Responding: 80 11 01 + 135267 [108439][E](DirConManager): Sending response message type 0x04 to client 0 + 135268 [109434][E](FTMS_SERVER): 11 00 00 c6 00 28 33 -> Sim Mode Incline 1.980000. Responding: 80 11 01 + 135269 [109439][E](DirConManager): Sending response message type 0x04 to client 0 + 135270 [110361][E](FTMS_SERVER): 11 00 00 a5 00 28 33 -> Sim Mode Incline 1.650000. Responding: 80 11 01 + 135271 [110369][E](DirConManager): Sending response message type 0x04 to client 0 + 135272 [110456][E](PTable): Using detected travel limits during homing + 135273 [111368][E](FTMS_SERVER): 11 00 00 8b 00 28 33 -> Sim Mode Incline 1.390000. Responding: 80 11 01 + 135274 [111375][E](DirConManager): Sending response message type 0x04 to client 0 + 135275 [111865][E](PTable): Averaged Entry: watts=131.399994, cad=78.099998, targetPosition=1140.199951, (4)(4) + 135276 [111866][E](PTData): New entry recorded (4)(4)(1140) + 135277 [111878][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 135278 [111880][E](PTable): New Entry Processed in 15 ms + 135279 [111880][E](PTable): Power Buffer Reset + 135280 [112211][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 100, Cad 81, HR 103, Gear 8, Res 36, Current Pos 10573, Target Pos 10573 + 135281 [112335][E](FTMS_SERVER): 11 00 00 70 00 28 33 -> Sim Mode Incline 1.120000. Responding: 80 11 01 + 135282 [112342][E](DirConManager): Sending response message type 0x04 to client 0 + 135283 [113339][E](FTMS_SERVER): 11 00 00 56 00 28 33 -> Sim Mode Incline 0.860000. Responding: 80 11 01 + 135284 [113346][E](DirConManager): Sending response message type 0x04 to client 0 + 135285 [114247][E](FTMS_SERVER): 11 00 00 3f 00 28 33 -> Sim Mode Incline 0.630000. Responding: 80 11 01 + 135286 [114253][E](DirConManager): Sending response message type 0x04 to client 0 + 135287 [115159][E](FTMS_SERVER): 11 00 00 28 00 28 33 -> Sim Mode Incline 0.400000. Responding: 80 11 01 + 135288 [115164][E](DirConManager): Sending response message type 0x04 to client 0 + 135289 [116201][E](FTMS_SERVER): 11 00 00 12 00 28 33 -> Sim Mode Incline 0.180000. Responding: 80 11 01 + 135290 [116205][E](DirConManager): Sending response message type 0x04 to client 0 + 135291 [117211][E](FTMS_SERVER): 11 00 00 fc ff 28 33 -> Sim Mode Incline -0.040000. Responding: 80 11 01 + 135292 [117218][E](DirConManager): Sending response message type 0x04 to client 0 + 135293 [118148][E](FTMS_SERVER): 11 00 00 ee ff 28 33 -> Sim Mode Incline -0.180000. Responding: 80 11 01 + 135294 [118155][E](DirConManager): Sending response message type 0x04 to client 0 + 135295 [118209][E](PTable): Averaged Entry: watts=79.699997, cad=81.000000, targetPosition=1003.299988, (4)(3) + 135296 [118210][E](PTData): New entry recorded (4)(3)(1003) + 135297 [118222][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 135298 [118224][E](PTable): New Entry Processed in 15 ms + 135299 [118224][E](PTable): Power Buffer Reset + 135300 [118235][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 74, Cad 81, HR 110, Gear 8, Res 32, Current Pos 9567, Target Pos 9474 + 135301 [119053][E](FTMS_SERVER): 11 00 00 e0 ff 28 33 -> Sim Mode Incline -0.320000. Responding: 80 11 01 + 135302 [119060][E](DirConManager): Sending response message type 0x04 to client 0 + 135303 [120075][E](FTMS_SERVER): 11 00 00 d0 ff 28 33 -> Sim Mode Incline -0.480000. Responding: 80 11 01 + 135304 [120082][E](DirConManager): Sending response message type 0x04 to client 0 + 135305 [121040][E](FTMS_SERVER): 11 00 00 bb ff 28 33 -> Sim Mode Incline -0.690000. Responding: 80 11 01 + 135306 [121047][E](DirConManager): Sending response message type 0x04 to client 0 + 135307 [121946][E](FTMS_SERVER): 11 00 00 a4 ff 28 33 -> Sim Mode Incline -0.920000. Responding: 80 11 01 + 135308 [121951][E](DirConManager): Sending response message type 0x04 to client 0 + 135309 [122847][E](FTMS_SERVER): 11 00 00 8a ff 28 33 -> Sim Mode Incline -1.180000. Responding: 80 11 01 + 135310 [122854][E](DirConManager): Sending response message type 0x04 to client 0 + 135311 [123760][E](FTMS_SERVER): 11 00 00 6e ff 28 33 -> Sim Mode Incline -1.460000. Responding: 80 11 01 + 135312 [123767][E](DirConManager): Sending response message type 0x04 to client 0 + 135313 [124258][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 49, Cad 81, HR 113, Gear 8, Res 29, Current Pos 8578, Target Pos 8578 + 135314 [124563][E](PTable): Averaged Entry: watts=60.299999, cad=82.199997, targetPosition=910.599976, (4)(2) + 135315 [124564][E](PTData): New entry recorded (4)(2)(910) + 135316 [124576][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 135317 [124577][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 1 ms + 135318 [124591][E](PTData): Fit Valid: 1, N: 4, Quad: 0, Time: 0 ms + 135319 [124593][E](PTable): New Entry Processed in 31 ms + 135320 [124593][E](PTable): Power Buffer Reset + 135321 [124789][E](FTMS_SERVER): 11 00 00 2b ff 28 33 -> Sim Mode Incline -2.130000. Responding: 80 11 01 + 135322 [124797][E](DirConManager): Sending response message type 0x04 to client 0 + 135323 [125746][E](FTMS_SERVER): 11 00 00 ef fe 28 33 -> Sim Mode Incline -2.730000. Responding: 80 11 01 + 135324 [125753][E](DirConManager): Sending response message type 0x04 to client 0 + 135325 [126739][E](FTMS_SERVER): 11 00 00 d2 fe 28 33 -> Sim Mode Incline -3.020000. Responding: 80 11 01 + 135326 [126744][E](DirConManager): Sending response message type 0x04 to client 0 + 135327 [127669][E](FTMS_SERVER): 11 00 00 ca fe 28 33 -> Sim Mode Incline -3.100000. Responding: 80 11 01 + 135328 [127676][E](DirConManager): Sending response message type 0x04 to client 0 + 135329 [128578][E](FTMS_SERVER): 11 00 00 c9 fe 28 33 -> Sim Mode Incline -3.110000. Responding: 80 11 01 + 135330 [128585][E](DirConManager): Sending response message type 0x04 to client 0 + 135331 [129601][E](FTMS_SERVER): 11 00 00 cf fe 28 33 -> Sim Mode Incline -3.050000. Responding: 80 11 01 + 135332 [129608][E](DirConManager): Sending response message type 0x04 to client 0 + 135333 [130275][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 36, Cad 84, HR 112, Gear 8, Res 25, Current Pos 7465, Target Pos 7465 + 135334 [130545][E](FTMS_SERVER): 11 00 00 e1 fe 28 33 -> Sim Mode Incline -2.870000. Responding: 80 11 01 + 135335 [130552][E](DirConManager): Sending response message type 0x04 to client 0 + 135336 [130912][E](PTable): Averaged Entry: watts=40.000000, cad=82.500000, targetPosition=770.200012, (4)(1) + 135337 [130913][E](PTData): Existing entry averaged (4)(1)(779), readings(1) + 135338 [130924][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 135339 [130925][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 135340 [130940][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 135341 [130941][E](PTable): New Entry Processed in 29 ms + 135342 [130941][E](PTable): Power Buffer Reset + 135343 [131460][E](FTMS_SERVER): 11 00 00 03 ff 28 33 -> Sim Mode Incline -2.530000. Responding: 80 11 01 + 135344 [131465][E](DirConManager): Sending response message type 0x04 to client 0 + 135345 [132359][E](FTMS_SERVER): 11 00 00 5d ff 28 33 -> Sim Mode Incline -1.630000. Responding: 80 11 01 + 135346 [132367][E](DirConManager): Sending response message type 0x04 to client 0 + 135347 [133297][E](FTMS_SERVER): 11 00 00 93 00 28 33 -> Sim Mode Incline 1.470000. Responding: 80 11 01 + 135348 [133304][E](DirConManager): Sending response message type 0x04 to client 0 + 135349 [134258][E](FTMS_SERVER): 11 00 00 88 01 28 33 -> Sim Mode Incline 3.920000. Responding: 80 11 01 + 135350 [134265][E](DirConManager): Sending response message type 0x04 to client 0 + 135351 [134440][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 135352 [134440][E](PTable): Power Buffer Reset + 135353 [135263][E](FTMS_SERVER): 11 00 00 ec 01 28 33 -> Sim Mode Incline 4.920000. Responding: 80 11 01 + 135354 [135271][E](DirConManager): Sending response message type 0x04 to client 0 + 135355 [136268][E](FTMS_SERVER): 11 00 00 18 02 28 33 -> Sim Mode Incline 5.360000. Responding: 80 11 01 + 135356 [136275][E](DirConManager): Sending response message type 0x04 to client 0 + 135357 [136287][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 29, Cad 13, HR 110, Gear 8, Res 44, Current Pos 13044, Target Pos 13352 + 135358 [137192][E](FTMS_SERVER): 11 00 00 26 02 28 33 -> Sim Mode Incline 5.500000. Responding: 80 11 01 + 135359 [137198][E](DirConManager): Sending response message type 0x04 to client 0 + 135360 [138214][E](FTMS_SERVER): 11 00 00 22 02 28 33 -> Sim Mode Incline 5.460000. Responding: 80 11 01 + 135361 [138219][E](DirConManager): Sending response message type 0x04 to client 0 + 135362 [139237][E](FTMS_SERVER): 11 00 00 fc 01 28 33 -> Sim Mode Incline 5.080000. Responding: 80 11 01 + 135363 [139242][E](DirConManager): Sending response message type 0x04 to client 0 + 135364 [140247][E](FTMS_SERVER): 11 00 00 ad 01 28 33 -> Sim Mode Incline 4.290000. Responding: 80 11 01 + 135365 [140253][E](DirConManager): Sending response message type 0x04 to client 0 + 135366 [141185][E](FTMS_SERVER): 11 00 00 3d 01 28 33 -> Sim Mode Incline 3.170000. Responding: 80 11 01 + 135367 [141192][E](DirConManager): Sending response message type 0x04 to client 0 + 135368 [142211][E](FTMS_SERVER): 11 00 00 11 01 28 33 -> Sim Mode Incline 2.730000. Responding: 80 11 01 + 135369 [142218][E](DirConManager): Sending response message type 0x04 to client 0 + 135370 [142308][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 134, Cad 71, HR 108, Gear 8, Res 40, Current Pos 11805, Target Pos 11511 + 135371 [142916][E](PTable): Averaged Entry: watts=140.899994, cad=67.699997, targetPosition=1286.400024, (1)(5) + 135372 [142917][E](PTData): Existing entry averaged (1)(5)(1356), readings(1) + 135373 [142928][E](PTData): Greater Down Found 2, 5, tp1368 + 135374 [142928][E](PTData): Fit Valid: 1, N: 5, Quad: 0, Time: 0 ms + 135375 [142940][E](PTable): New Entry Processed in 24 ms + 135376 [142940][E](PTable): Power Buffer Reset + 135377 [143166][E](FTMS_SERVER): 11 00 00 e9 00 28 33 -> Sim Mode Incline 2.330000. Responding: 80 11 01 + 135378 [143174][E](DirConManager): Sending response message type 0x04 to client 0 + 135379 [144166][E](FTMS_SERVER): 11 00 00 cb 00 28 33 -> Sim Mode Incline 2.030000. Responding: 80 11 01 + 135380 [144174][E](DirConManager): Sending response message type 0x04 to client 0 + 135381 [145062][E](FTMS_SERVER): 11 00 00 b6 00 28 33 -> Sim Mode Incline 1.820000. Responding: 80 11 01 + 135382 [145067][E](DirConManager): Sending response message type 0x04 to client 0 + 135383 [145993][E](FTMS_SERVER): 11 00 00 a5 00 28 33 -> Sim Mode Incline 1.650000. Responding: 80 11 01 + 135384 [145998][E](DirConManager): Sending response message type 0x04 to client 0 + 135385 [146442][E](PTable): Using detected travel limits during homing + 135386 [147026][E](FTMS_SERVER): 11 00 00 99 00 28 33 -> Sim Mode Incline 1.530000. Responding: 80 11 01 + 135387 [147030][E](DirConManager): Sending response message type 0x04 to client 0 + 135388 [148044][E](FTMS_SERVER): 11 00 00 8d 00 28 33 -> Sim Mode Incline 1.410000. Responding: 80 11 01 + 135389 [148049][E](DirConManager): Sending response message type 0x04 to client 0 + 135390 [148323][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 80, Cad 78, HR 108, Gear 8, Res 36, Current Pos 10591, Target Pos 10587 + 135391 [149075][E](FTMS_SERVER): 11 00 00 84 00 28 33 -> Sim Mode Incline 1.320000. Responding: 80 11 01 + 135392 [149082][E](DirConManager): Sending response message type 0x04 to client 0 + 135393 [149278][E](PTable): Averaged Entry: watts=103.500000, cad=75.300003, targetPosition=1088.599976, (3)(3) + 135394 [149279][E](PTData): Cleaned 1 readings + 135395 [149289][E](PTData): Existing entry averaged (3)(3)(1082), readings(1) + 135396 [149290][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 135397 [149301][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 1 ms + 135398 [149305][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 0 ms + 135399 [149306][E](PTable): New Entry Processed in 28 ms + 135400 [149317][E](PTable): Power Buffer Reset + 135401 [149980][E](FTMS_SERVER): 11 00 00 7e 00 28 33 -> Sim Mode Incline 1.260000. Responding: 80 11 01 + 135402 [149987][E](DirConManager): Sending response message type 0x04 to client 0 + 135403 [150895][E](FTMS_SERVER): 11 00 00 79 00 28 33 -> Sim Mode Incline 1.210000. Responding: 80 11 01 + 135404 [150903][E](DirConManager): Sending response message type 0x04 to client 0 + 135405 [151919][E](FTMS_SERVER): 11 00 00 77 00 28 33 -> Sim Mode Incline 1.190000. Responding: 80 11 01 + 135406 [151927][E](DirConManager): Sending response message type 0x04 to client 0 + 135407 [152863][E](FTMS_SERVER): 11 00 00 79 00 28 33 -> Sim Mode Incline 1.210000. Responding: 80 11 01 + 135408 [152871][E](DirConManager): Sending response message type 0x04 to client 0 + 135409 [153888][E](FTMS_SERVER): 11 00 00 82 00 28 33 -> Sim Mode Incline 1.300000. Responding: 80 11 01 + 135410 [153892][E](DirConManager): Sending response message type 0x04 to client 0 + 135411 [154335][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 75, Cad 79, HR 110, Gear 8, Res 35, Current Pos 10510, Target Pos 10510 + 135412 [154810][E](FTMS_SERVER): 11 00 00 78 00 28 33 -> Sim Mode Incline 1.200000. Responding: 80 11 01 + 135413 [154817][E](DirConManager): Sending response message type 0x04 to client 0 + 135414 [155647][E](PTable): Averaged Entry: watts=75.500000, cad=78.699997, targetPosition=1046.900024, (4)(3) + 135415 [155648][E](PTData): Existing entry averaged (4)(3)(1017), readings(2) + 135416 [155659][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 135417 [155660][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 1 ms + 135418 [155674][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 0 ms + 135419 [155675][E](PTable): New Entry Processed in 29 ms + 135420 [155676][E](PTable): Power Buffer Reset + 135421 [155830][E](FTMS_SERVER): 11 00 00 36 00 28 33 -> Sim Mode Incline 0.540000. Responding: 80 11 01 + 135422 [155837][E](DirConManager): Sending response message type 0x04 to client 0 + 135423 [156772][E](FTMS_SERVER): 11 00 00 e5 ff 28 33 -> Sim Mode Incline -0.270000. Responding: 80 11 01 + 135424 [156780][E](DirConManager): Sending response message type 0x04 to client 0 + 135425 [157779][E](FTMS_SERVER): 11 00 00 b4 ff 28 33 -> Sim Mode Incline -0.760000. Responding: 80 11 01 + 135426 [157786][E](DirConManager): Sending response message type 0x04 to client 0 + 135427 [158683][E](FTMS_SERVER): 11 00 00 f1 ff 28 33 -> Sim Mode Incline -0.150000. Responding: 80 11 01 + 135428 [158690][E](DirConManager): Sending response message type 0x04 to client 0 + 135429 [159606][E](FTMS_SERVER): 11 00 00 6e 00 28 33 -> Sim Mode Incline 1.100000. Responding: 80 11 01 + 135430 [159611][E](DirConManager): Sending response message type 0x04 to client 0 + 135431 [160343][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 78, Cad 82, HR 111, Gear 8, Res 33, Current Pos 10194, Target Pos 10370 + 135432 [160642][E](FTMS_SERVER): 11 00 00 7a 00 28 33 -> Sim Mode Incline 1.220000. Responding: 80 11 01 + 135433 [160647][E](DirConManager): Sending response message type 0x04 to client 0 + 135434 [161589][E](FTMS_SERVER): 11 00 00 78 00 28 33 -> Sim Mode Incline 1.200000. Responding: 80 11 01 + 135435 [161596][E](DirConManager): Sending response message type 0x04 to client 0 + 135436 [162002][E](PTable): Averaged Entry: watts=68.300003, cad=80.400002, targetPosition=987.200012, (4)(2) + 135437 [162003][E](PTData): Existing entry averaged (4)(2)(935), readings(2) + 135438 [162014][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 135439 [162015][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 1 ms + 135440 [162029][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 0 ms + 135441 [162030][E](PTable): New Entry Processed in 28 ms + 135442 [162030][E](PTable): Power Buffer Reset + 135443 [162688][E](FTMS_SERVER): 11 00 00 74 00 28 33 -> Sim Mode Incline 1.160000. Responding: 80 11 01 + 135444 [162693][E](DirConManager): Sending response message type 0x04 to client 0 + 135445 [163597][E](FTMS_SERVER): 11 00 00 6d 00 28 33 -> Sim Mode Incline 1.090000. Responding: 80 11 01 + 135446 [163604][E](DirConManager): Sending response message type 0x04 to client 0 + 135447 [164617][E](FTMS_SERVER): 11 00 00 63 00 28 33 -> Sim Mode Incline 0.990000. Responding: 80 11 01 + 135448 [164624][E](DirConManager): Sending response message type 0x04 to client 0 + 135449 [165578][E](FTMS_SERVER): 11 00 00 53 00 28 33 -> Sim Mode Incline 0.830000. Responding: 80 11 01 + 135450 [165585][E](DirConManager): Sending response message type 0x04 to client 0 + 135451 [166359][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 73, Cad 81, HR 111, Gear 8, Res 34, Current Pos 10181, Target Pos 10181 + 135452 [166585][E](FTMS_SERVER): 11 00 00 39 00 28 33 -> Sim Mode Incline 0.570000. Responding: 80 11 01 + 135453 [166592][E](DirConManager): Sending response message type 0x04 to client 0 + 135454 [167490][E](FTMS_SERVER): 11 00 00 16 00 28 33 -> Sim Mode Incline 0.220000. Responding: 80 11 01 + 135455 [167496][E](DirConManager): Sending response message type 0x04 to client 0 + 135456 [168348][E](PTable): Averaged Entry: watts=69.400002, cad=82.500000, targetPosition=1021.599976, (4)(2) + 135457 [168349][E](PTData): Existing entry averaged (4)(2)(956), readings(3) + 135458 [168360][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 135459 [168361][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 1 ms + 135460 [168375][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 0 ms + 135461 [168376][E](PTable): New Entry Processed in 29 ms + 135462 [168377][E](PTable): Power Buffer Reset + 135463 [168522][E](FTMS_SERVER): 11 00 00 fa ff 28 33 -> Sim Mode Incline -0.060000. Responding: 80 11 01 + 135464 [168527][E](DirConManager): Sending response message type 0x04 to client 0 + 135465 [169532][E](FTMS_SERVER): 11 00 00 f2 ff 28 33 -> Sim Mode Incline -0.140000. Responding: 80 11 01 + 135466 [169537][E](DirConManager): Sending response message type 0x04 to client 0 + 135467 [170390][E](FTMS_SERVER): 11 00 00 eb ff 28 33 -> Sim Mode Incline -0.210000. Responding: 80 11 01 + 135468 [170398][E](DirConManager): Sending response message type 0x04 to client 0 + 135469 [171392][E](FTMS_SERVER): 11 00 00 e2 ff 28 33 -> Sim Mode Incline -0.300000. Responding: 80 11 01 + 135470 [171399][E](DirConManager): Sending response message type 0x04 to client 0 + 135471 [172297][E](FTMS_SERVER): 11 00 00 d5 ff 28 33 -> Sim Mode Incline -0.430000. Responding: 80 11 01 + 135472 [172306][E](DirConManager): Sending response message type 0x04 to client 0 + 135473 [172369][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 34, Cad 76, HR 112, Gear 8, Res 31, Current Pos 9382, Target Pos 9299 + 135474 [173328][E](FTMS_SERVER): 11 00 00 c0 ff 28 33 -> Sim Mode Incline -0.640000. Responding: 80 11 01 + 135475 [173336][E](DirConManager): Sending response message type 0x04 to client 0 + 135476 [174295][E](FTMS_SERVER): 11 00 00 85 ff 28 33 -> Sim Mode Incline -1.230000. Responding: 80 11 01 + 135477 [174300][E](DirConManager): Sending response message type 0x04 to client 0 + 135478 [174684][E](PTable): Averaged Entry: watts=49.200001, cad=77.000000, targetPosition=935.900024, (3)(2) + 135479 [174685][E](PTData): Existing entry averaged (3)(2)(953), readings(3) + 135480 [174695][E](PTData): Greater Down Found 4, 2, tp956 + 135481 [174696][E](PTData): Fit Valid: 1, N: 6, Quad: 0, Time: 0 ms + 135482 [174708][E](PTable): New Entry Processed in 24 ms + 135483 [174708][E](PTable): Power Buffer Reset + 135484 [175287][E](FTMS_SERVER): 11 00 00 55 ff 28 33 -> Sim Mode Incline -1.710000. Responding: 80 11 01 + 135485 [175292][E](DirConManager): Sending response message type 0x04 to client 0 + 135486 [176310][E](FTMS_SERVER): 11 00 00 84 ff 28 33 -> Sim Mode Incline -1.240000. Responding: 80 11 01 + 135487 [176315][E](DirConManager): Sending response message type 0x04 to client 0 + 135488 [177218][E](FTMS_SERVER): 11 00 00 89 ff 28 33 -> Sim Mode Incline -1.190000. Responding: 80 11 01 + 135489 [177225][E](DirConManager): Sending response message type 0x04 to client 0 + 135490 [178241][E](FTMS_SERVER): 11 00 00 8b ff 28 33 -> Sim Mode Incline -1.170000. Responding: 80 11 01 + 135491 [178248][E](DirConManager): Sending response message type 0x04 to client 0 + 135492 [178397][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 32, Cad 72, HR 110, Gear 8, Res 29, Current Pos 8781, Target Pos 8781 + 135493 [179205][E](FTMS_SERVER): 11 00 00 8d ff 28 33 -> Sim Mode Incline -1.150000. Responding: 80 11 01 + 135494 [179211][E](DirConManager): Sending response message type 0x04 to client 0 + 135495 [180187][E](FTMS_SERVER): 11 00 00 8f ff 28 33 -> Sim Mode Incline -1.130000. Responding: 80 11 01 + 135496 [180195][E](DirConManager): Sending response message type 0x04 to client 0 + 135497 [181037][E](PTable): Averaged Entry: watts=34.500000, cad=72.400002, targetPosition=872.099976, (2)(1) + 135498 [181038][E](PTData): Existing entry averaged (2)(1)(885), readings(1) + 135499 [181049][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 135500 [181050][E](PTData): Fit Valid: 1, N: 7, Quad: 0, Time: 1 ms + 135501 [181064][E](PTData): Fit Valid: 1, N: 7, Quad: 0, Time: 0 ms + 135502 [181065][E](PTable): New Entry Processed in 28 ms + 135503 [181066][E](PTable): Power Buffer Reset + 135504 [181121][E](FTMS_SERVER): 11 00 00 90 ff 28 33 -> Sim Mode Incline -1.120000. Responding: 80 11 01 + 135505 [181126][E](DirConManager): Sending response message type 0x04 to client 0 + 135506 [182140][E](FTMS_SERVER): 11 00 00 92 ff 28 33 -> Sim Mode Incline -1.100000. Responding: 80 11 01 + 135507 [182145][E](DirConManager): Sending response message type 0x04 to client 0 + 135508 [182449][E](PTable): Using detected travel limits during homing + 135509 [183176][E](FTMS_SERVER): 11 00 00 94 ff 28 33 -> Sim Mode Incline -1.080000. Responding: 80 11 01 + 135510 [183181][E](DirConManager): Sending response message type 0x04 to client 0 + 135511 [184199][E](FTMS_SERVER): 11 00 00 97 ff 28 33 -> Sim Mode Incline -1.050000. Responding: 80 11 01 + 135512 [184204][E](DirConManager): Sending response message type 0x04 to client 0 + 135513 [184411][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 33, Cad 71, HR 106, Gear 8, Res 30, Current Pos 8865, Target Pos 8865 + 135514 [185228][E](FTMS_SERVER): 11 00 00 9a ff 28 33 -> Sim Mode Incline -1.020000. Responding: 80 11 01 + 135515 [185232][E](DirConManager): Sending response message type 0x04 to client 0 + 135516 [186135][E](FTMS_SERVER): 11 00 00 9e ff 28 33 -> Sim Mode Incline -0.980000. Responding: 80 11 01 + 135517 [186142][E](DirConManager): Sending response message type 0x04 to client 0 + 135518 [187156][E](FTMS_SERVER): 11 00 00 a4 ff 28 33 -> Sim Mode Incline -0.920000. Responding: 80 11 01 + 135519 [187163][E](DirConManager): Sending response message type 0x04 to client 0 + 135520 [187392][E](PTable): Averaged Entry: watts=31.700001, cad=71.300003, targetPosition=885.799988, (2)(1) + 135521 [187393][E](PTData): Existing entry averaged (2)(1)(885), readings(2) + 135522 [187404][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 135523 [187405][E](PTData): Fit Valid: 1, N: 7, Quad: 0, Time: 1 ms + 135524 [187419][E](PTData): Fit Valid: 1, N: 7, Quad: 0, Time: 0 ms + 135525 [187420][E](PTable): New Entry Processed in 28 ms + 135526 [187421][E](PTable): Power Buffer Reset + 135527 [188109][E](FTMS_SERVER): 11 00 00 af ff 28 33 -> Sim Mode Incline -0.810000. Responding: 80 11 01 + 135528 [188116][E](DirConManager): Sending response message type 0x04 to client 0 + 135529 [189113][E](FTMS_SERVER): 11 00 00 d1 ff 28 33 -> Sim Mode Incline -0.470000. Responding: 80 11 01 + 135530 [189120][E](DirConManager): Sending response message type 0x04 to client 0 + 135531 [190017][E](FTMS_SERVER): 11 00 00 05 00 28 33 -> Sim Mode Incline 0.050000. Responding: 80 11 01 + 135532 [190023][E](DirConManager): Sending response message type 0x04 to client 0 + 135533 [190435][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 35, Cad 70, HR 102, Gear 8, Res 32, Current Pos 9518, Target Pos 9635 + 135534 [191043][E](FTMS_SERVER): 11 00 00 56 00 28 33 -> Sim Mode Incline 0.860000. Responding: 80 11 01 + 135535 [191048][E](DirConManager): Sending response message type 0x04 to client 0 + 135536 [192075][E](FTMS_SERVER): 11 00 00 84 00 28 33 -> Sim Mode Incline 1.320000. Responding: 80 11 01 + 135537 [192080][E](DirConManager): Sending response message type 0x04 to client 0 + 135538 [193003][E](FTMS_SERVER): 11 00 00 81 00 28 33 -> Sim Mode Incline 1.290000. Responding: 80 11 01 + 135539 [193010][E](DirConManager): Sending response message type 0x04 to client 0 + 135540 [193760][E](PTable): Averaged Entry: watts=32.599998, cad=70.000000, targetPosition=965.099976, (2)(1) + 135541 [193761][E](PTData): Existing entry averaged (2)(1)(905), readings(3) + 135542 [193772][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 135543 [193772][E](PTData): Fit Valid: 1, N: 7, Quad: 0, Time: 0 ms + 135544 [193787][E](PTData): Fit Valid: 1, N: 7, Quad: 0, Time: 1 ms + 135545 [193788][E](PTable): New Entry Processed in 29 ms + 135546 [193788][E](PTable): Power Buffer Reset + 135547 [193904][E](FTMS_SERVER): 11 00 00 64 00 28 33 -> Sim Mode Incline 1.000000. Responding: 80 11 01 + 135548 [193911][E](DirConManager): Sending response message type 0x04 to client 0 + 135549 [194834][E](FTMS_SERVER): 11 00 00 3b 00 28 33 -> Sim Mode Incline 0.590000. Responding: 80 11 01 + 135550 [194841][E](DirConManager): Sending response message type 0x04 to client 0 + 135551 [195857][E](FTMS_SERVER): 11 00 00 0f 00 28 33 -> Sim Mode Incline 0.150000. Responding: 80 11 01 + 135552 [195865][E](DirConManager): Sending response message type 0x04 to client 0 + 135553 [196447][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 46, Cad 62, HR 99, Gear 8, Res 33, Current Pos 9709, Target Pos 9705 + 135554 [196817][E](FTMS_SERVER): 11 00 00 ef ff 28 33 -> Sim Mode Incline -0.170000. Responding: 80 11 01 + 135555 [196822][E](DirConManager): Sending response message type 0x04 to client 0 + 135556 [197718][E](FTMS_SERVER): 11 00 00 d9 ff 28 33 -> Sim Mode Incline -0.390000. Responding: 80 11 01 + 135557 [197725][E](DirConManager): Sending response message type 0x04 to client 0 + 135558 [198619][E](FTMS_SERVER): 11 00 00 c5 ff 28 33 -> Sim Mode Incline -0.590000. Responding: 80 11 01 + 135559 [198626][E](DirConManager): Sending response message type 0x04 to client 0 + 135560 [199535][E](FTMS_SERVER): 11 00 00 b1 ff 28 33 -> Sim Mode Incline -0.790000. Responding: 80 11 01 + 135561 [199543][E](DirConManager): Sending response message type 0x04 to client 0 + 135562 [200111][E](PTable): Averaged Entry: watts=40.599998, cad=64.199997, targetPosition=968.299988, (1)(1) + 135563 [200112][E](PTData): Existing entry averaged (1)(1)(956), readings(1) + 135564 [200123][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 135565 [200124][E](PTData): Fit Valid: 1, N: 8, Quad: 0, Time: 1 ms + 135566 [200138][E](PTData): Fit Valid: 1, N: 8, Quad: 0, Time: 0 ms + 135567 [200139][E](PTable): New Entry Processed in 28 ms + 135568 [200140][E](PTable): Power Buffer Reset + 135569 [200568][E](FTMS_SERVER): 11 00 00 9f ff 28 33 -> Sim Mode Incline -0.970000. Responding: 80 11 01 + 135570 [200575][E](DirConManager): Sending response message type 0x04 to client 0 + 135571 [201514][E](FTMS_SERVER): 11 00 00 95 ff 28 33 -> Sim Mode Incline -1.070000. Responding: 80 11 01 + 135572 [201522][E](DirConManager): Sending response message type 0x04 to client 0 + 135573 [202457][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 32, Cad 63, HR 98, Gear 8, Res 30, Current Pos 8851, Target Pos 8851 + 135574 [202512][E](FTMS_SERVER): 11 00 00 8d ff 28 33 -> Sim Mode Incline -1.150000. Responding: 80 11 01 + 135575 [202518][E](DirConManager): Sending response message type 0x04 to client 0 + 135576 [203450][E](FTMS_SERVER): 11 00 00 88 ff 28 33 -> Sim Mode Incline -1.200000. Responding: 80 11 01 + 135577 [203458][E](DirConManager): Sending response message type 0x04 to client 0 + 135578 [204461][E](FTMS_SERVER): 11 00 00 84 ff 28 33 -> Sim Mode Incline -1.240000. Responding: 80 11 01 + 135579 [204468][E](DirConManager): Sending response message type 0x04 to client 0 + 135580 [205421][E](FTMS_SERVER): 11 00 00 80 ff 28 33 -> Sim Mode Incline -1.280000. Responding: 80 11 01 + 135581 [205428][E](DirConManager): Sending response message type 0x04 to client 0 + 135582 [206422][E](FTMS_SERVER): 11 00 00 7d ff 28 33 -> Sim Mode Incline -1.310000. Responding: 80 11 01 + 135583 [206429][E](DirConManager): Sending response message type 0x04 to client 0 + 135584 [206472][E](PTable): Averaged Entry: watts=29.299999, cad=63.900002, targetPosition=881.299988, (1)(1) + 135585 [206473][E](PTData): Existing entry averaged (1)(1)(931), readings(2) + 135586 [206484][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 135587 [206484][E](PTData): Fit Valid: 1, N: 8, Quad: 0, Time: 0 ms + 135588 [206500][E](PTData): Fit Valid: 1, N: 8, Quad: 0, Time: 1 ms + 135589 [206501][E](PTable): New Entry Processed in 29 ms + 135590 [206502][E](PTable): Power Buffer Reset + 135591 [207330][E](FTMS_SERVER): 11 00 00 7a ff 28 33 -> Sim Mode Incline -1.340000. Responding: 80 11 01 + 135592 [207337][E](DirConManager): Sending response message type 0x04 to client 0 + 135593 [208255][E](FTMS_SERVER): 11 00 00 79 ff 28 33 -> Sim Mode Incline -1.350000. Responding: 80 11 01 + 135594 [208260][E](DirConManager): Sending response message type 0x04 to client 0 + 135595 [208473][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 18, Cad 64, HR 98, Gear 8, Res 29, Current Pos 8655, Target Pos 8655 + 135596 [209284][E](FTMS_SERVER): 11 00 00 77 ff 28 33 -> Sim Mode Incline -1.370000. Responding: 80 11 01 + 135597 [209289][E](DirConManager): Sending response message type 0x04 to client 0 + 135598 [210305][E](FTMS_SERVER): 11 00 00 75 ff 28 33 -> Sim Mode Incline -1.390000. Responding: 80 11 01 + 135599 [210310][E](DirConManager): Sending response message type 0x04 to client 0 + 135600 [211329][E](FTMS_SERVER): 11 00 00 73 ff 28 33 -> Sim Mode Incline -1.410000. Responding: 80 11 01 + 135601 [211333][E](DirConManager): Sending response message type 0x04 to client 0 + 135602 [212255][E](FTMS_SERVER): 11 00 00 72 ff 28 33 -> Sim Mode Incline -1.420000. Responding: 80 11 01 + 135603 [212262][E](DirConManager): Sending response message type 0x04 to client 0 + 135604 [212831][E](PTable): Averaged Entry: watts=25.500000, cad=64.000000, targetPosition=864.000000, (1)(1) + 135605 [212832][E](PTData): Existing entry averaged (1)(1)(914), readings(3) + 135606 [212843][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 135607 [212844][E](PTData): Fit Valid: 1, N: 8, Quad: 0, Time: 1 ms + 135608 [212858][E](PTData): Fit Valid: 1, N: 8, Quad: 0, Time: 0 ms + 135609 [212860][E](PTable): New Entry Processed in 29 ms + 135610 [212860][E](PTable): Power Buffer Reset + 135611 [213264][E](FTMS_SERVER): 11 00 00 71 ff 28 33 -> Sim Mode Incline -1.430000. Responding: 80 11 01 + 135612 [213272][E](DirConManager): Sending response message type 0x04 to client 0 + 135613 [214228][E](FTMS_SERVER): 11 00 00 70 ff 28 33 -> Sim Mode Incline -1.440000. Responding: 80 11 01 + 135614 [214235][E](DirConManager): Sending response message type 0x04 to client 0 + 135615 [214483][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 24, Cad 64, HR 97, Gear 8, Res 29, Current Pos 8592, Target Pos 8592 + 135616 [215230][E](FTMS_SERVER): 11 00 00 6f ff 28 33 -> Sim Mode Incline -1.450000. Responding: 80 11 01 + 135617 [215237][E](DirConManager): Sending response message type 0x04 to client 0 + 135618 [216139][E](FTMS_SERVER): 11 00 00 6e ff 28 33 -> Sim Mode Incline -1.460000. Responding: 80 11 01 + 135619 [216144][E](DirConManager): Sending response message type 0x04 to client 0 + 135620 [217082][E](FTMS_SERVER): 11 00 00 6d ff 28 33 -> Sim Mode Incline -1.470000. Responding: 80 11 01 + 135621 [217088][E](DirConManager): Sending response message type 0x04 to client 0 + 135622 [218493][E](PTable): Using detected travel limits during homing + 135623 [219203][E](PTable): Averaged Entry: watts=24.100000, cad=63.799999, targetPosition=857.900024, (1)(1) + 135624 [219204][E](PTData): Existing entry averaged (1)(1)(902), readings(4) + 135625 [219215][E](PTData): Greater Down Found 2, 1, tp905 + 135626 [219215][E](PTData): Fit Valid: 1, N: 8, Quad: 0, Time: 0 ms + 135627 [219227][E](PTable): New Entry Processed in 24 ms + 135628 [219227][E](PTable): Power Buffer Reset + 135629 [220245][E](FTMS_SERVER): 11 00 00 6e ff 28 33 -> Sim Mode Incline -1.460000. Responding: 80 11 01 + 135630 [220250][E](DirConManager): Sending response message type 0x04 to client 0 + 135631 [220494][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 23, Cad 62, HR 97, Gear 8, Res 29, Current Pos 8578, Target Pos 8578 + 135632 [221165][E](FTMS_SERVER): 11 00 00 6f ff 28 33 -> Sim Mode Incline -1.450000. Responding: 80 11 01 + 135633 [221172][E](DirConManager): Sending response message type 0x04 to client 0 + 135634 [222169][E](FTMS_SERVER): 11 00 00 67 ff 28 33 -> Sim Mode Incline -1.530000. Responding: 80 11 01 + 135635 [222178][E](DirConManager): Sending response message type 0x04 to client 0 + 135636 [223125][E](FTMS_SERVER): 11 00 00 5e ff 28 33 -> Sim Mode Incline -1.620000. Responding: 80 11 01 + 135637 [223133][E](DirConManager): Sending response message type 0x04 to client 0 + 135638 [224135][E](FTMS_SERVER): 11 00 00 54 ff 28 33 -> Sim Mode Incline -1.720000. Responding: 80 11 01 + 135639 [224143][E](DirConManager): Sending response message type 0x04 to client 0 + 135640 [225050][E](FTMS_SERVER): 11 00 00 4e ff 28 33 -> Sim Mode Incline -1.780000. Responding: 80 11 01 + 135641 [225055][E](DirConManager): Sending response message type 0x04 to client 0 + 135642 [225543][E](PTable): Averaged Entry: watts=22.799999, cad=62.099998, targetPosition=850.500000, (0)(1) + 135643 [225545][E](PTData): Existing entry averaged (0)(1)(915), readings(1) + 135644 [225556][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 135645 [225557][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 135646 [225571][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 0 ms + 135647 [225573][E](PTable): New Entry Processed in 30 ms + 135648 [225573][E](PTable): Power Buffer Reset + 135649 [225969][E](FTMS_SERVER): 11 00 00 4d ff 28 33 -> Sim Mode Incline -1.790000. Responding: 80 11 01 + 135650 [225976][E](DirConManager): Sending response message type 0x04 to client 0 + 135651 [226507][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 25, Cad 63, HR 97, Gear 8, Res 28, Current Pos 8347, Target Pos 8347 + 135652 [227007][E](FTMS_SERVER): 11 00 00 53 ff 28 33 -> Sim Mode Incline -1.730000. Responding: 80 11 01 + 135653 [227012][E](DirConManager): Sending response message type 0x04 to client 0 + 135654 [227935][E](FTMS_SERVER): 11 00 00 60 ff 28 33 -> Sim Mode Incline -1.600000. Responding: 80 11 01 + 135655 [227943][E](DirConManager): Sending response message type 0x04 to client 0 + 135656 [228936][E](FTMS_SERVER): 11 00 00 70 ff 28 33 -> Sim Mode Incline -1.440000. Responding: 80 11 01 + 135657 [228943][E](DirConManager): Sending response message type 0x04 to client 0 + 135658 [229860][E](FTMS_SERVER): 11 00 00 7b ff 28 33 -> Sim Mode Incline -1.330000. Responding: 80 11 01 + 135659 [229867][E](DirConManager): Sending response message type 0x04 to client 0 + 135660 [230877][E](FTMS_SERVER): 11 00 00 84 ff 28 33 -> Sim Mode Incline -1.240000. Responding: 80 11 01 + 135661 [230884][E](DirConManager): Sending response message type 0x04 to client 0 + 135662 [231841][E](FTMS_SERVER): 11 00 00 8d ff 28 33 -> Sim Mode Incline -1.150000. Responding: 80 11 01 + 135663 [231848][E](DirConManager): Sending response message type 0x04 to client 0 + 135664 [231892][E](PTable): Averaged Entry: watts=22.900000, cad=63.900002, targetPosition=850.900024, (1)(1) + 135665 [231894][E](PTData): Existing entry averaged (1)(1)(901), readings(4) + 135666 [231904][E](PTData): Greater Down Found 2, 1, tp905 + 135667 [231905][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 0 ms + 135668 [231917][E](PTable): New Entry Processed in 25 ms + 135669 [231917][E](PTable): Power Buffer Reset + 135670 [232523][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 18, Cad 63, HR 94, Gear 8, Res 29, Current Pos 8795, Target Pos 8795 + 135671 [232853][E](FTMS_SERVER): 11 00 00 8e ff 28 33 -> Sim Mode Incline -1.140000. Responding: 80 11 01 + 135672 [232860][E](DirConManager): Sending response message type 0x04 to client 0 + 135673 [233855][E](FTMS_SERVER): 11 00 00 90 ff 28 33 -> Sim Mode Incline -1.120000. Responding: 80 11 01 + 135674 [233860][E](DirConManager): Sending response message type 0x04 to client 0 + 135675 [235583][E](FTMS_SERVER): 11 00 00 92 ff 28 33 -> Sim Mode Incline -1.100000. Responding: 80 11 01 + 135676 [235590][E](DirConManager): Sending response message type 0x04 to client 0 + 135677 [236547][E](FTMS_SERVER): 11 00 00 94 ff 28 33 -> Sim Mode Incline -1.080000. Responding: 80 11 01 + 135678 [236554][E](DirConManager): Sending response message type 0x04 to client 0 + 135679 [237552][E](FTMS_SERVER): 11 00 00 96 ff 28 33 -> Sim Mode Incline -1.060000. Responding: 80 11 01 + 135680 [237559][E](DirConManager): Sending response message type 0x04 to client 0 + 135681 [238247][E](PTable): Averaged Entry: watts=24.200001, cad=62.700001, targetPosition=881.700012, (0)(1) + 135682 [238248][E](PTData): Existing entry averaged (0)(1)(903), readings(2) + 135683 [238258][E](PTData): Greater Down Found 1, 1, tp914 + 135684 [238259][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 0 ms + 135685 [238271][E](PTable): New Entry Processed in 24 ms + 135686 [238271][E](PTable): Power Buffer Reset + 135687 [238456][E](FTMS_SERVER): 11 00 00 98 ff 28 33 -> Sim Mode Incline -1.040000. Responding: 80 11 01 + 135688 [238465][E](DirConManager): Sending response message type 0x04 to client 0 + 135689 [238534][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 24, Cad 63, HR 92, Gear 8, Res 30, Current Pos 8863, Target Pos 8872 + 135690 [239484][E](FTMS_SERVER): 11 00 00 9a ff 28 33 -> Sim Mode Incline -1.020000. Responding: 80 11 01 + 135691 [239491][E](DirConManager): Sending response message type 0x04 to client 0 + 135692 [240504][E](FTMS_SERVER): 11 00 00 9d ff 28 33 -> Sim Mode Incline -0.990000. Responding: 80 11 01 + 135693 [240511][E](DirConManager): Sending response message type 0x04 to client 0 + 135694 [241535][E](FTMS_SERVER): 11 00 00 a0 ff 28 33 -> Sim Mode Incline -0.960000. Responding: 80 11 01 + 135695 [241542][E](DirConManager): Sending response message type 0x04 to client 0 + 135696 [242464][E](FTMS_SERVER): 11 00 00 a2 ff 28 33 -> Sim Mode Incline -0.940000. Responding: 80 11 01 + 135697 [242472][E](DirConManager): Sending response message type 0x04 to client 0 + 135698 [243368][E](FTMS_SERVER): 11 00 00 a5 ff 28 33 -> Sim Mode Incline -0.910000. Responding: 80 11 01 + 135699 [243373][E](DirConManager): Sending response message type 0x04 to client 0 + 135700 [244393][E](FTMS_SERVER): 11 00 00 a9 ff 28 33 -> Sim Mode Incline -0.870000. Responding: 80 11 01 + 135701 [244399][E](DirConManager): Sending response message type 0x04 to client 0 + 135702 [244543][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 19, Cad 61, HR 92, Gear 8, Res 30, Current Pos 8988, Target Pos 8991 + 135703 [244625][E](PTable): Averaged Entry: watts=22.600000, cad=62.099998, targetPosition=891.299988, (0)(1) + 135704 [244626][E](PTData): Existing entry averaged (0)(1)(907), readings(2) + 135705 [244636][E](PTData): Greater Down Found 1, 1, tp914 + 135706 [244637][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 0 ms + 135707 [244649][E](PTable): New Entry Processed in 24 ms + 135708 [244786][E](PTable): Writing File: /PowerTable.txt + 135709 [245029][E](PTable): Power table saved successfully with 312 readings + 135710 [245029][E](PTable): Power Buffer Reset + 135711 [245343][E](FTMS_SERVER): 11 00 00 ac ff 28 33 -> Sim Mode Incline -0.840000. Responding: 80 11 01 + 135712 [245352][E](DirConManager): Sending response message type 0x04 to client 0 + 135713 [246345][E](FTMS_SERVER): 11 00 00 b0 ff 28 33 -> Sim Mode Incline -0.800000. Responding: 80 11 01 + 135714 [246352][E](DirConManager): Sending response message type 0x04 to client 0 + 135715 [247270][E](FTMS_SERVER): 11 00 00 b5 ff 28 33 -> Sim Mode Incline -0.750000. Responding: 80 11 01 + 135716 [247275][E](DirConManager): Sending response message type 0x04 to client 0 + 135717 [248188][E](FTMS_SERVER): 11 00 00 b9 ff 28 33 -> Sim Mode Incline -0.710000. Responding: 80 11 01 + 135718 [248193][E](DirConManager): Sending response message type 0x04 to client 0 + 135719 [249227][E](FTMS_SERVER): 11 00 00 be ff 28 33 -> Sim Mode Incline -0.660000. Responding: 80 11 01 + 135720 [249232][E](DirConManager): Sending response message type 0x04 to client 0 + 135721 [250235][E](FTMS_SERVER): 11 00 00 c5 ff 28 33 -> Sim Mode Incline -0.590000. Responding: 80 11 01 + 135722 [250242][E](DirConManager): Sending response message type 0x04 to client 0 + 135723 [250559][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 24, Cad 60, HR 93, Gear 8, Res 31, Current Pos 9187, Target Pos 9187 + 135724 [250975][E](PTable): Averaged Entry: watts=21.900000, cad=60.099998, targetPosition=907.099976, (0)(1) + 135725 [250976][E](PTData): Existing entry averaged (0)(1)(912), readings(2) + 135726 [250987][E](PTData): Greater Down Found 1, 1, tp914 + 135727 [250987][E](PTData): Fit Valid: 1, N: 8, Quad: 0, Time: 0 ms + 135728 [250999][E](PTable): New Entry Processed in 24 ms + 135729 [250999][E](PTable): Power Buffer Reset + 135730 [251165][E](FTMS_SERVER): 11 00 00 cd ff 28 33 -> Sim Mode Incline -0.510000. Responding: 80 11 01 + 135731 [251172][E](DirConManager): Sending response message type 0x04 to client 0 + 135732 [252080][E](FTMS_SERVER): 11 00 00 d5 ff 28 33 -> Sim Mode Incline -0.430000. Responding: 80 11 01 + 135733 [252087][E](DirConManager): Sending response message type 0x04 to client 0 + 135734 [253104][E](FTMS_SERVER): 11 00 00 dd ff 28 33 -> Sim Mode Incline -0.350000. Responding: 80 11 01 + 135735 [253111][E](DirConManager): Sending response message type 0x04 to client 0 + 135736 [254067][E](FTMS_SERVER): 11 00 00 e5 ff 28 33 -> Sim Mode Incline -0.270000. Responding: 80 11 01 + 135737 [254074][E](DirConManager): Sending response message type 0x04 to client 0 + 135738 [254495][E](PTable): Using detected travel limits during homing + 135739 [255056][E](FTMS_SERVER): 11 00 00 ec ff 28 33 -> Sim Mode Incline -0.200000. Responding: 80 11 01 + 135740 [255063][E](DirConManager): Sending response message type 0x04 to client 0 + 135741 [256078][E](FTMS_SERVER): 11 00 00 f2 ff 28 33 -> Sim Mode Incline -0.140000. Responding: 80 11 01 + 135742 [256082][E](DirConManager): Sending response message type 0x04 to client 0 + 135743 [256572][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 154, Cad 88, HR 92, Gear 8, Res 32, Current Pos 9502, Target Pos 9502 + 135744 [256987][E](FTMS_SERVER): 11 00 00 f7 ff 28 33 -> Sim Mode Incline -0.090000. Responding: 80 11 01 + 135745 [256994][E](DirConManager): Sending response message type 0x04 to client 0 + 135746 [257318][E](PTable): Averaged Entry: watts=66.400002, cad=66.500000, targetPosition=937.500000, (1)(2) + 135747 [257319][E](PTData): Existing entry averaged (1)(2)(986), readings(1) + 135748 [257330][E](PTData): Greater Down Found 2, 2, tp997 + 135749 [257330][E](PTData): Fit Valid: 1, N: 8, Quad: 0, Time: 0 ms + 135750 [257342][E](PTable): New Entry Processed in 24 ms + 135751 [257342][E](PTable): Power Buffer Reset + 135752 [258026][E](FTMS_SERVER): 11 00 00 fc ff 28 33 -> Sim Mode Incline -0.040000. Responding: 80 11 01 + 135753 [258033][E](DirConManager): Sending response message type 0x04 to client 0 + 135754 [258958][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 135755 [258965][E](DirConManager): Sending response message type 0x04 to client 0 + 135756 [259862][E](FTMS_SERVER): 11 00 00 06 00 28 33 -> Sim Mode Incline 0.060000. Responding: 80 11 01 + 135757 [259869][E](DirConManager): Sending response message type 0x04 to client 0 + 135758 [260786][E](FTMS_SERVER): 11 00 00 0c 00 28 33 -> Sim Mode Incline 0.120000. Responding: 80 11 01 + 135759 [260791][E](DirConManager): Sending response message type 0x04 to client 0 + 135760 [261798][E](FTMS_SERVER): 11 00 00 11 00 28 33 -> Sim Mode Incline 0.170000. Responding: 80 11 01 + 135761 [261804][E](DirConManager): Sending response message type 0x04 to client 0 + 135762 [262586][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 77, Cad 98, HR 92, Gear 8, Res 33, Current Pos 9719, Target Pos 9719 + 135763 [262834][E](FTMS_SERVER): 11 00 00 16 00 28 33 -> Sim Mode Incline 0.220000. Responding: 80 11 01 + 135764 [262839][E](DirConManager): Sending response message type 0x04 to client 0 + 135765 [263689][E](PTable): Averaged Entry: watts=75.400002, cad=98.099998, targetPosition=963.900024, (8)(3) + 135766 [263690][E](PTData): Cleaned 1 readings + 135767 [263700][E](PTData): Existing entry averaged (8)(3)(922), readings(1) + 135768 [263701][E](PTData): Lower Up Found 7, 3, tp920 + 135769 [263712][E](PTData): Fit Valid: 1, N: 8, Quad: 0, Time: 1 ms + 135770 [263713][E](PTable): New Entry Processed in 24 ms + 135771 [263713][E](PTable): Power Buffer Reset + 135772 [263866][E](FTMS_SERVER): 11 00 00 1a 00 28 33 -> Sim Mode Incline 0.260000. Responding: 80 11 01 + 135773 [263871][E](DirConManager): Sending response message type 0x04 to client 0 + 135774 [264888][E](FTMS_SERVER): 11 00 00 1c 00 28 33 -> Sim Mode Incline 0.280000. Responding: 80 11 01 + 135775 [264893][E](DirConManager): Sending response message type 0x04 to client 0 + 135776 [265798][E](FTMS_SERVER): 11 00 00 1e 00 28 33 -> Sim Mode Incline 0.300000. Responding: 80 11 01 + 135777 [265806][E](DirConManager): Sending response message type 0x04 to client 0 + 135778 [266819][E](FTMS_SERVER): 11 00 00 1f 00 28 33 -> Sim Mode Incline 0.310000. Responding: 80 11 01 + 135779 [266826][E](DirConManager): Sending response message type 0x04 to client 0 + 135780 [268566][E](FTMS_SERVER): 11 00 00 1e 00 28 33 -> Sim Mode Incline 0.300000. Responding: 80 11 01 + 135781 [268573][E](DirConManager): Sending response message type 0x04 to client 0 + 135782 [268596][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 74, Cad 95, HR 95, Gear 8, Res 33, Current Pos 9816, Target Pos 9810 + 135783 [269498][E](FTMS_SERVER): 11 00 00 1c 00 28 33 -> Sim Mode Incline 0.280000. Responding: 80 11 01 + 135784 [269505][E](DirConManager): Sending response message type 0x04 to client 0 + 135785 [270056][E](PTable): Averaged Entry: watts=74.699997, cad=96.000000, targetPosition=979.799988, (7)(2) + 135786 [270057][E](PTData): Cleaned 1 readings + 135787 [270067][E](PTData): Existing entry averaged (7)(2)(892), readings(1) + 135788 [270068][E](PTData): Lower Up Found 6, 2, tp844 + 135789 [270079][E](PTData): Fit Valid: 1, N: 8, Quad: 0, Time: 1 ms + 135790 [270080][E](PTable): New Entry Processed in 24 ms + 135791 [270080][E](PTable): Power Buffer Reset + 135792 [270503][E](FTMS_SERVER): 11 00 00 1a 00 28 33 -> Sim Mode Incline 0.260000. Responding: 80 11 01 + 135793 [270511][E](DirConManager): Sending response message type 0x04 to client 0 + 135794 [271523][E](FTMS_SERVER): 11 00 00 16 00 28 33 -> Sim Mode Incline 0.220000. Responding: 80 11 01 + 135795 [271531][E](DirConManager): Sending response message type 0x04 to client 0 + 135796 [272488][E](FTMS_SERVER): 11 00 00 11 00 28 33 -> Sim Mode Incline 0.170000. Responding: 80 11 01 + 135797 [272494][E](DirConManager): Sending response message type 0x04 to client 0 + 135798 [273489][E](FTMS_SERVER): 11 00 00 0c 00 28 33 -> Sim Mode Incline 0.120000. Responding: 80 11 01 + 135799 [273495][E](DirConManager): Sending response message type 0x04 to client 0 + 135800 [274496][E](FTMS_SERVER): 11 00 00 05 00 28 33 -> Sim Mode Incline 0.050000. Responding: 80 11 01 + 135801 [274503][E](DirConManager): Sending response message type 0x04 to client 0 + 135802 [274607][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 86, Cad 96, HR 103, Gear 8, Res 32, Current Pos 9666, Target Pos 9635 + 135803 [275522][E](FTMS_SERVER): 11 00 00 02 00 28 33 -> Sim Mode Incline 0.020000. Responding: 80 11 01 + 135804 [275529][E](DirConManager): Sending response message type 0x04 to client 0 + 135805 [276412][E](PTable): Averaged Entry: watts=79.800003, cad=95.500000, targetPosition=970.400024, (7)(3) + 135806 [276413][E](PTData): Cleaned 1 readings + 135807 [276423][E](PTData): New entry recorded (7)(3)(970) + 135808 [276424][E](PTData): Lower Up Found 6, 3, tp957 + 135809 [276424][E](PTData): Fit Valid: 1, N: 8, Quad: 0, Time: 0 ms + 135810 [276436][E](PTable): New Entry Processed in 24 ms + 135811 [276437][E](PTable): Power Buffer Reset + 135812 [277189][E](FTMS_SERVER): 11 00 00 03 00 28 33 -> Sim Mode Incline 0.030000. Responding: 80 11 01 + 135813 [277197][E](DirConManager): Sending response message type 0x04 to client 0 + 135814 [280544][E](FTMS_SERVER): 11 00 00 04 00 28 33 -> Sim Mode Incline 0.040000. Responding: 80 11 01 + 135815 [280551][E](DirConManager): Sending response message type 0x04 to client 0 + 135816 [280617][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 77, Cad 96, HR 105, Gear 8, Res 32, Current Pos 9626, Target Pos 9628 + 135817 [282759][E](PTable): Averaged Entry: watts=77.699997, cad=96.400002, targetPosition=961.799988, (7)(3) + 135818 [282760][E](PTData): Cleaned 1 readings + 135819 [282770][E](PTData): New entry recorded (7)(3)(961) + 135820 [282771][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 135821 [282781][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 135822 [282782][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 0 ms + 135823 [282797][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 135824 [282798][E](PTable): New Entry Processed in 39 ms + 135825 [282798][E](PTable): Power Buffer Reset + 135826 [286625][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 78, Cad 93, HR 108, Gear 8, Res 32, Current Pos 9628, Target Pos 9628 + 135827 [289038][E](FTMS_SERVER): 11 00 00 05 00 28 33 -> Sim Mode Incline 0.050000. Responding: 80 11 01 + 135828 [289046][E](DirConManager): Sending response message type 0x04 to client 0 + 135829 [289120][E](PTable): Averaged Entry: watts=77.400002, cad=93.699997, targetPosition=962.099976, (7)(3) + 135830 [289121][E](PTData): Existing entry averaged (7)(3)(960), readings(2) + 135831 [289132][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 135832 [289133][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 135833 [289148][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 135834 [289149][E](PTable): New Entry Processed in 30 ms + 135835 [289149][E](PTable): Power Buffer Reset + 135836 [290530][E](PTable): Using detected travel limits during homing + 135837 [291391][E](FTMS_SERVER): 11 00 00 04 00 28 33 -> Sim Mode Incline 0.040000. Responding: 80 11 01 + 135838 [291398][E](DirConManager): Sending response message type 0x04 to client 0 + 135839 [292642][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 81, Cad 94, HR 109, Gear 8, Res 32, Current Pos 9628, Target Pos 9628 + 135840 [295478][E](PTable): Averaged Entry: watts=83.800003, cad=95.099998, targetPosition=962.400024, (7)(3) + 135841 [295479][E](PTData): Cleaned 1 readings + 135842 [295490][E](PTData): Existing entry averaged (7)(3)(960), readings(3) + 135843 [295490][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 135844 [295501][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 135845 [295501][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 0 ms + 135846 [295516][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 0 ms + 135847 [295517][E](PTable): New Entry Processed in 39 ms + 135848 [295518][E](PTable): Power Buffer Reset + 135849 [298658][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 89, Cad 101, HR 111, Gear 8, Res 32, Current Pos 9628, Target Pos 9628 + 135850 [299106][E](FTMS_SERVER): 11 00 00 03 00 28 33 -> Sim Mode Incline 0.030000. Responding: 80 11 01 + 135851 [299113][E](DirConManager): Sending response message type 0x04 to client 0 + 135852 [301641][E](FTMS_SERVER): 11 00 00 02 00 28 33 -> Sim Mode Incline 0.020000. Responding: 80 11 01 + 135853 [301646][E](DirConManager): Sending response message type 0x04 to client 0 + 135854 [301811][E](PTable): Averaged Entry: watts=87.900002, cad=100.900002, targetPosition=961.900024, (8)(3) + 135855 [301812][E](PTData): Existing entry averaged (8)(3)(940), readings(1) + 135856 [301823][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 135857 [301823][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 135858 [301835][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 135859 [301853][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 135860 [301854][E](PTable): New Entry Processed in 43 ms + 135861 [301854][E](PTable): Power Buffer Reset + 135862 [304125][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 135863 [304131][E](DirConManager): Sending response message type 0x04 to client 0 + 135864 [304670][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 84, Cad 103, HR 112, Gear 8, Res 32, Current Pos 9600, Target Pos 9600 + 135865 [305844][E](FTMS_SERVER): 11 00 00 ff ff 28 33 -> Sim Mode Incline -0.010000. Responding: 80 11 01 + 135866 [305850][E](DirConManager): Sending response message type 0x04 to client 0 + 135867 [306866][E](FTMS_SERVER): 11 00 00 fe ff 28 33 -> Sim Mode Incline -0.020000. Responding: 80 11 01 + 135868 [306871][E](DirConManager): Sending response message type 0x04 to client 0 + 135869 [307803][E](FTMS_SERVER): 11 00 00 fd ff 28 33 -> Sim Mode Incline -0.030000. Responding: 80 11 01 + 135870 [307808][E](DirConManager): Sending response message type 0x04 to client 0 + 135871 [308173][E](PTable): Averaged Entry: watts=83.000000, cad=101.500000, targetPosition=959.700012, (8)(3) + 135872 [308175][E](PTData): Cleaned 15 readings + 135873 [308185][E](PTData): Existing entry averaged (8)(3)(946), readings(2) + 135874 [308186][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 135875 [308197][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 135876 [308198][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 3 + 135877 [308209][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 135878 [308217][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 135879 [308218][E](PTable): New Entry Processed in 45 ms + 135880 [308229][E](PTable): Power Buffer Reset + 135881 [310685][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 78, Cad 99, HR 115, Gear 8, Res 32, Current Pos 9579, Target Pos 9579 + 135882 [311053][E](FTMS_SERVER): 11 00 00 fc ff 28 33 -> Sim Mode Incline -0.040000. Responding: 80 11 01 + 135883 [311059][E](DirConManager): Sending response message type 0x04 to client 0 + 135884 [314515][E](PTable): Averaged Entry: watts=82.699997, cad=98.900002, targetPosition=957.000000, (8)(3) + 135885 [314516][E](PTData): Cleaned 1 readings + 135886 [314526][E](PTData): Existing entry averaged (8)(3)(948), readings(3) + 135887 [314528][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 135888 [314539][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 135889 [314539][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 3 + 135890 [314551][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 135891 [314559][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 135892 [314560][E](PTable): New Entry Processed in 45 ms + 135893 [314560][E](PTable): Power Buffer Reset + 135894 [316698][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 82, Cad 98, HR 116, Gear 8, Res 32, Current Pos 9572, Target Pos 9572 + 135895 [320283][E](FTMS_SERVER): 11 00 00 fd ff 28 33 -> Sim Mode Incline -0.030000. Responding: 80 11 01 + 135896 [320290][E](DirConManager): Sending response message type 0x04 to client 0 + 135897 [320879][E](PTable): Averaged Entry: watts=82.699997, cad=98.300003, targetPosition=957.000000, (8)(3) + 135898 [320881][E](PTData): Cleaned 3 readings + 135899 [320892][E](PTData): Existing entry averaged (8)(3)(949), readings(4) + 135900 [320893][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 135901 [320904][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 135902 [320905][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 3 + 135903 [320916][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 135904 [320924][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 135905 [320925][E](PTable): New Entry Processed in 46 ms + 135906 [320926][E](PTable): Power Buffer Reset + 135907 [322708][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 79, Cad 99, HR 117, Gear 8, Res 32, Current Pos 9579, Target Pos 9579 + 135908 [324262][E](FTMS_SERVER): 11 00 00 fe ff 28 33 -> Sim Mode Incline -0.020000. Responding: 80 11 01 + 135909 [324270][E](DirConManager): Sending response message type 0x04 to client 0 + 135910 [326519][E](PTable): Using detected travel limits during homing + 135911 [327220][E](PTable): Averaged Entry: watts=80.300003, cad=98.000000, targetPosition=957.500000, (8)(3) + 135912 [327222][E](PTData): Cleaned 1 readings + 135913 [327233][E](PTData): Existing entry averaged (8)(3)(950), readings(5) + 135914 [327234][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 135915 [327245][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 135916 [327246][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 3 + 135917 [327257][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 135918 [327265][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 135919 [327267][E](PTable): New Entry Processed in 47 ms + 135920 [327267][E](PTable): Power Buffer Reset + 135921 [327442][E](FTMS_SERVER): 11 00 00 ff ff 28 33 -> Sim Mode Incline -0.010000. Responding: 80 11 01 + 135922 [327449][E](DirConManager): Sending response message type 0x04 to client 0 + 135923 [328723][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 90, Cad 98, HR 117, Gear 8, Res 32, Current Pos 9593, Target Pos 9593 + 135924 [329189][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 135925 [329196][E](DirConManager): Sending response message type 0x04 to client 0 + 135926 [331634][E](FTMS_SERVER): 11 00 00 01 00 28 33 -> Sim Mode Incline 0.010000. Responding: 80 11 01 + 135927 [331642][E](DirConManager): Sending response message type 0x04 to client 0 + 135928 [332559][E](FTMS_SERVER): 11 00 00 03 00 28 33 -> Sim Mode Incline 0.030000. Responding: 80 11 01 + 135929 [332566][E](DirConManager): Sending response message type 0x04 to client 0 + 135930 [333579][E](PTable): Averaged Entry: watts=85.099998, cad=97.599998, targetPosition=960.099976, (7)(3) + 135931 [333580][E](PTData): Cleaned 2 readings + 135932 [333591][E](PTData): Existing entry averaged (7)(3)(960), readings(4) + 135933 [333592][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 135934 [333603][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 135935 [333604][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 3 + 135936 [333615][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 135937 [333623][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 135938 [333625][E](PTable): New Entry Processed in 46 ms + 135939 [333625][E](PTable): Power Buffer Reset + 135940 [333639][E](FTMS_SERVER): 11 00 00 05 00 28 33 -> Sim Mode Incline 0.050000. Responding: 80 11 01 + 135941 [333644][E](DirConManager): Sending response message type 0x04 to client 0 + 135942 [334539][E](FTMS_SERVER): 11 00 00 08 00 28 33 -> Sim Mode Incline 0.080000. Responding: 80 11 01 + 135943 [334545][E](DirConManager): Sending response message type 0x04 to client 0 + 135944 [334740][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 76, Cad 98, HR 116, Gear 8, Res 32, Current Pos 9656, Target Pos 9656 + 135945 [335439][E](FTMS_SERVER): 11 00 00 0b 00 28 33 -> Sim Mode Incline 0.110000. Responding: 80 11 01 + 135946 [335446][E](DirConManager): Sending response message type 0x04 to client 0 + 135947 [336348][E](FTMS_SERVER): 11 00 00 0e 00 28 33 -> Sim Mode Incline 0.140000. Responding: 80 11 01 + 135948 [336356][E](DirConManager): Sending response message type 0x04 to client 0 + 135949 [337266][E](FTMS_SERVER): 11 00 00 13 00 28 33 -> Sim Mode Incline 0.190000. Responding: 80 11 01 + 135950 [337274][E](DirConManager): Sending response message type 0x04 to client 0 + 135951 [338232][E](FTMS_SERVER): 11 00 00 18 00 28 33 -> Sim Mode Incline 0.240000. Responding: 80 11 01 + 135952 [338238][E](DirConManager): Sending response message type 0x04 to client 0 + 135953 [339235][E](FTMS_SERVER): 11 00 00 20 00 28 33 -> Sim Mode Incline 0.320000. Responding: 80 11 01 + 135954 [339241][E](DirConManager): Sending response message type 0x04 to client 0 + 135955 [339941][E](PTable): Averaged Entry: watts=85.000000, cad=97.199997, targetPosition=970.200012, (7)(3) + 135956 [339942][E](PTData): Cleaned 3 readings + 135957 [339952][E](PTData): Existing entry averaged (7)(3)(961), readings(5) + 135958 [339954][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 135959 [339965][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 135960 [339966][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 3 + 135961 [339977][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 135962 [339985][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 135963 [339986][E](PTable): New Entry Processed in 45 ms + 135964 [339987][E](PTable): Power Buffer Reset + 135965 [340260][E](FTMS_SERVER): 11 00 00 29 00 28 33 -> Sim Mode Incline 0.410000. Responding: 80 11 01 + 135966 [340265][E](DirConManager): Sending response message type 0x04 to client 0 + 135967 [340757][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 83, Cad 96, HR 116, Gear 8, Res 33, Current Pos 9887, Target Pos 9887 + 135968 [341277][E](FTMS_SERVER): 11 00 00 36 00 28 33 -> Sim Mode Incline 0.540000. Responding: 80 11 01 + 135969 [341282][E](DirConManager): Sending response message type 0x04 to client 0 + 135970 [342305][E](FTMS_SERVER): 11 00 00 43 00 28 33 -> Sim Mode Incline 0.670000. Responding: 80 11 01 + 135971 [342312][E](DirConManager): Sending response message type 0x04 to client 0 + 135972 [343326][E](FTMS_SERVER): 11 00 00 4f 00 28 33 -> Sim Mode Incline 0.790000. Responding: 80 11 01 + 135973 [343333][E](DirConManager): Sending response message type 0x04 to client 0 + 135974 [344244][E](FTMS_SERVER): 11 00 00 58 00 28 33 -> Sim Mode Incline 0.880000. Responding: 80 11 01 + 135975 [344251][E](DirConManager): Sending response message type 0x04 to client 0 + 135976 [345166][E](FTMS_SERVER): 11 00 00 5e 00 28 33 -> Sim Mode Incline 0.940000. Responding: 80 11 01 + 135977 [345173][E](DirConManager): Sending response message type 0x04 to client 0 + 135978 [346076][E](FTMS_SERVER): 11 00 00 62 00 28 33 -> Sim Mode Incline 0.980000. Responding: 80 11 01 + 135979 [346081][E](DirConManager): Sending response message type 0x04 to client 0 + 135980 [346286][E](PTable): Averaged Entry: watts=89.400002, cad=97.400002, targetPosition=1006.700012, (7)(3) + 135981 [346287][E](PTData): Cleaned 4 readings + 135982 [346297][E](PTData): Existing entry averaged (7)(3)(967), readings(6) + 135983 [346299][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 135984 [346310][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 135985 [346311][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 3 + 135986 [346322][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 135987 [346330][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 135988 [346331][E](PTable): New Entry Processed in 45 ms + 135989 [346331][E](PTable): Power Buffer Reset + 135990 [346769][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 97, Cad 100, HR 118, Gear 8, Res 35, Current Pos 10286, Target Pos 10286 + 135991 [347096][E](FTMS_SERVER): 11 00 00 64 00 28 33 -> Sim Mode Incline 1.000000. Responding: 80 11 01 + 135992 [347101][E](DirConManager): Sending response message type 0x04 to client 0 + 135993 [348120][E](FTMS_SERVER): 11 00 00 65 00 28 33 -> Sim Mode Incline 1.010000. Responding: 80 11 01 + 135994 [348125][E](DirConManager): Sending response message type 0x04 to client 0 + 135995 [348342][E](FTMS_SERVER): 05 91 00 -> ERG Mode Target: 145 Current: 91 Incline: 1.010000. Responding: 80 05 01 + 135996 [348349][E](DirConManager): Sending response message type 0x04 to client 0 + 135997 [348404][E](ERG_Mode): SetPoint changed:115w Waiting:783ms PowerTable Result: 10590 + 135998 [350595][E](ERG_Mode): ERG wait expired, pos: 10590, tgt: 0 + 135999 [350596][E](ERG_Mode): Proportional: 76.500000 + 136000 [352716][E](ERG_Mode): Watts previously processed. + 136001 [352778][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 113, Cad 99, HR 118, Gear 8, Res 36, Current Pos 10805, Target Pos 10805 + 136002 [354119][E](PTable): Averaged Entry: watts=104.199997, cad=98.900002, targetPosition=1056.300049, (8)(3) + 136003 [354120][E](PTData): Cleaned 2 readings + 136004 [354130][E](PTData): Existing entry averaged (8)(3)(965), readings(6) + 136005 [354132][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 136006 [354143][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 136007 [354144][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 3 + 136008 [354155][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 136009 [354163][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 136010 [354164][E](PTable): New Entry Processed in 45 ms + 136011 [354164][E](PTable): Power Buffer Reset + 136012 [354175][E](ERG_Mode): Watts previously processed. + 136013 [356229][E](ERG_Mode): Watts previously processed. + 136014 [356936][E](ERG_Mode): Proportional: 54.000000 + 136015 [358341][E](ERG_Mode): Watts previously processed. + 136016 [358788][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 120, Cad 97, HR 121, Gear 8, Res 37, Current Pos 11041, Target Pos 11041 + 136017 [360463][E](PTable): Averaged Entry: watts=125.500000, cad=97.300003, targetPosition=1099.500000, (7)(4) + 136018 [360464][E](PTData): Cleaned 2 readings + 136019 [360474][E](PTData): Existing entry averaged (7)(4)(1088), readings(1) + 136020 [360475][E](PTData): Lower Up Found 6, 4, tp1080 + 136021 [360486][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 136022 [360488][E](PTable): New Entry Processed in 25 ms + 136023 [360488][E](PTable): Power Buffer Reset + 136024 [360498][E](ERG_Mode): Watts previously processed. + 136025 [362593][E](ERG_Mode): Watts previously processed. + 136026 [363296][E](ERG_Mode): Proportional: 49.500000 + 136027 [363997][E](PTable): Using detected travel limits during homing + 136028 [364704][E](ERG_Mode): Watts previously processed. + 136029 [364805][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 145, Cad 97, HR 124, Gear 8, Res 38, Current Pos 11328, Target Pos 11328 + 136030 [366112][E](ERG_Mode): Watts previously processed. + 136031 [366818][E](PTable): Averaged Entry: watts=130.199997, cad=97.000000, targetPosition=1126.699951, (7)(4) + 136032 [366819][E](PTData): Cleaned 1 readings + 136033 [366829][E](PTData): Existing entry averaged (7)(4)(1102), readings(1) + 136034 [366830][E](PTData): Lower Up Found 4, 4, tp1073 + 136035 [366841][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 136036 [366842][E](PTable): New Entry Processed in 25 ms + 136037 [366843][E](PTable): Power Buffer Reset + 136038 [368230][E](ERG_Mode): Watts previously processed. + 136039 [368940][E](ERG_Mode): Proportional: 40.500000 + 136040 [370351][E](ERG_Mode): Watts previously processed. + 136041 [370818][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 133, Cad 96, HR 123, Gear 8, Res 39, Current Pos 11471, Target Pos 11471 + 136042 [372474][E](ERG_Mode): Watts previously processed. + 136043 [373182][E](PTable): Averaged Entry: watts=131.899994, cad=96.699997, targetPosition=1143.699951, (7)(4) + 136044 [373183][E](PTData): Existing entry averaged (7)(4)(1110), readings(1) + 136045 [373194][E](PTData): Lower Right Found 7, 5, tp1105 + 136046 [373194][E](PTData): Lower Up Found 4, 4, tp1073 + 136047 [373205][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 136048 [373206][E](PTable): New Entry Processed in 25 ms + 136049 [373207][E](PTable): Power Buffer Reset + 136050 [374596][E](ERG_Mode): Watts previously processed. + 136051 [375306][E](ERG_Mode): Proportional: -24.750000 + 136052 [376831][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 145, Cad 101, HR 122, Gear 8, Res 38, Current Pos 11405, Target Pos 11405 + 136053 [378148][E](ERG_Mode): Watts previously processed. + 136054 [379562][E](PTable): Averaged Entry: watts=158.100006, cad=100.800003, targetPosition=1142.500000, (8)(5) + 136055 [379563][E](PTData): Cleaned 2 readings + 136056 [379573][E](PTData): Existing entry averaged (8)(5)(1126), readings(1) + 136057 [379574][E](PTData): Lower Right Found 8, 6, tp1118 + 136058 [379584][E](PTData): Lower Up Found 6, 5, tp1096 + 136059 [379585][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 136060 [379586][E](PTable): New Entry Processed in 25 ms + 136061 [379596][E](PTable): Power Buffer Reset + 136062 [380268][E](ERG_Mode): Watts previously processed. + 136063 [380972][E](ERG_Mode): Proportional: 4.500000 + 136064 [382381][E](ERG_Mode): Watts previously processed. + 136065 [382840][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 139, Cad 99, HR 123, Gear 8, Res 38, Current Pos 11395, Target Pos 11395 + 136066 [384501][E](ERG_Mode): Watts previously processed. + 136067 [385916][E](PTable): Averaged Entry: watts=143.000000, cad=98.900002, targetPosition=1139.300049, (8)(5) + 136068 [385917][E](PTData): Cleaned 2 readings + 136069 [385928][E](PTData): Existing entry averaged (8)(5)(1124), readings(1) + 136070 [385928][E](PTData): Lower Right Found 8, 7, tp1117 + 136071 [385938][E](PTData): Lower Up Found 5, 5, tp1087 + 136072 [385939][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 136073 [385940][E](PTable): New Entry Processed in 24 ms + 136074 [385951][E](PTable): Power Buffer Reset + 136075 [386624][E](ERG_Mode): Watts previously processed. + 136076 [387333][E](ERG_Mode): Proportional: 1.500000 + 136077 [388858][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 172, Cad 98, HR 125, Gear 8, Res 38, Current Pos 11390, Target Pos 11354 + 136078 [389442][E](ERG_Mode): Watts previously processed. + 136079 [392269][E](PTable): Averaged Entry: watts=150.899994, cad=97.599998, targetPosition=1135.800049, (7)(5) + 136080 [392270][E](PTData): Cleaned 2 readings + 136081 [392280][E](PTData): New entry recorded (7)(5)(1135) + 136082 [392281][E](PTData): Lower Right Found 7, 6, tp1108 + 136083 [392281][E](PTData): Lower Up Found 4, 5, tp1077 + 136084 [392292][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 136085 [392293][E](PTable): New Entry Processed in 25 ms + 136086 [392304][E](PTable): Power Buffer Reset + 136087 [392304][E](ERG_Mode): Watts previously processed. + 136088 [392975][E](ERG_Mode): Proportional: 4.500000 + 136089 [394393][E](ERG_Mode): Watts previously processed. + 136090 [394871][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 143, Cad 98, HR 126, Gear 8, Res 38, Current Pos 11297, Target Pos 11297 + 136091 [396516][E](ERG_Mode): Watts previously processed. + 136092 [398633][E](PTable): Averaged Entry: watts=133.399994, cad=97.300003, targetPosition=1131.300049, (7)(4) + 136093 [398634][E](PTData): Cleaned 2 readings + 136094 [398644][E](PTData): Existing entry averaged (7)(4)(1104), readings(1) + 136095 [398645][E](PTData): Lower Up Found 3, 4, tp1063 + 136096 [398655][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 0 ms + 136097 [398657][E](PTable): New Entry Processed in 24 ms + 136098 [398657][E](PTable): Power Buffer Reset + 136099 [398667][E](ERG_Mode): Proportional: 83.250000 + 136100 [399339][E](ERG_Mode): Watts previously processed. + 136101 [400048][E](PTable): Using detected travel limits during homing + 136102 [400886][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 116, Cad 90, HR 127, Gear 8, Res 39, Current Pos 11605, Target Pos 11642 + 136103 [401460][E](ERG_Mode): Watts previously processed. + 136104 [403578][E](ERG_Mode): Watts previously processed. + 136105 [404235][E](FTMS_SERVER): 05 f5 00 -> ERG Mode Target: 245 Current: 122 Incline: 116.690002. Responding: 80 05 01 + 136106 [404241][E](DirConManager): Sending response message type 0x04 to client 0 + 136107 [404285][E](ERG_Mode): SetPoint changed:215w Waiting:1437ms PowerTable Result: 14250 + 136108 [406900][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 151, Cad 91, HR 128, Gear 8, Res 48, Current Pos 14250, Target Pos 14250 + 136109 [407131][E](ERG_Mode): ERG wait expired, pos: 14250, tgt: 0 + 136110 [407132][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 136111 [407142][E](PTable): Power Buffer Reset + 136112 [407143][E](ERG_Mode): Proportional: 282.000000 + 136113 [409237][E](ERG_Mode): Watts previously processed. + 136114 [411352][E](ERG_Mode): Watts previously processed. + 136115 [412769][E](ERG_Mode): Proportional: -96.750000 + 136116 [412911][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 288, Cad 96, HR 128, Gear 8, Res 48, Current Pos 14153, Target Pos 14089 + 136117 [413478][E](PTable): Averaged Entry: watts=276.100006, cad=94.099998, targetPosition=1438.400024, (7)(9) + 136118 [413479][E](PTData): Cleaned 1 readings + 136119 [413490][E](PTData): Existing entry averaged (7)(9)(1273), readings(1) + 136120 [413490][E](PTData): Lower Right Found 7, 10, tp1109 + 136121 [413500][E](PTData): Lower Up Found 6, 9, tp1098 + 136122 [413501][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 136123 [413502][E](PTable): New Entry Processed in 24 ms + 136124 [413513][E](PTable): Power Buffer Reset + 136125 [413513][E](ERG_Mode): Watts previously processed. + 136126 [415591][E](ERG_Mode): Watts previously processed. + 136127 [417704][E](ERG_Mode): Watts previously processed. + 136128 [418407][E](ERG_Mode): Proportional: -4.500000 + 136129 [418925][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 251, Cad 94, HR 129, Gear 8, Res 47, Current Pos 13851, Target Pos 13851 + 136130 [419822][E](PTable): Averaged Entry: watts=265.299988, cad=95.000000, targetPosition=1393.300049, (7)(9) + 136131 [419823][E](PTData): Cleaned 2 readings + 136132 [419833][E](PTData): Existing entry averaged (7)(9)(1250), readings(1) + 136133 [419834][E](PTData): Lower Right Found 7, 11, tp1108 + 136134 [419844][E](PTData): Lower Up Found 5, 9, tp1089 + 136135 [419845][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 136136 [419846][E](PTable): New Entry Processed in 24 ms + 136137 [419856][E](PTable): Power Buffer Reset + 136138 [419857][E](ERG_Mode): Watts previously processed. + 136139 [421229][E](ERG_Mode): Watts previously processed. + 136140 [423347][E](ERG_Mode): Watts previously processed. + 136141 [424054][E](ERG_Mode): Proportional: 1.500000 + 136142 [424938][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 244, Cad 93, HR 132, Gear 8, Res 47, Current Pos 13844, Target Pos 13844 + 136143 [425464][E](ERG_Mode): Watts previously processed. + 136144 [426184][E](PTable): Averaged Entry: watts=245.699997, cad=93.099998, targetPosition=1384.000000, (7)(8) + 136145 [426186][E](PTData): Cleaned 2 readings + 136146 [426196][E](PTData): Existing entry averaged (7)(8)(1246), readings(1) + 136147 [426197][E](PTData): Lower Right Found 7, 9, tp1108 + 136148 [426207][E](PTData): Lower Up Found 6, 8, tp1099 + 136149 [426208][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 136150 [426209][E](PTable): New Entry Processed in 25 ms + 136151 [426219][E](PTable): Power Buffer Reset + 136152 [427597][E](ERG_Mode): Watts previously processed. + 136153 [429718][E](ERG_Mode): Watts previously processed. + 136154 [430420][E](ERG_Mode): Proportional: 6.000000 + 136155 [430949][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 235, Cad 91, HR 135, Gear 8, Res 47, Current Pos 13863, Target Pos 13863 + 136156 [432532][E](PTable): Averaged Entry: watts=241.399994, cad=92.099998, targetPosition=1385.099976, (6)(8) + 136157 [432533][E](PTData): Cleaned 2 readings + 136158 [432543][E](PTData): New entry recorded (6)(8)(1385) + 136159 [432544][E](PTData): Lower Right Found 6, 10, tp1099 + 136160 [432544][E](PTData): Lower Up Found 5, 8, tp1089 + 136161 [432555][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 136162 [432556][E](PTable): New Entry Processed in 24 ms + 136163 [432566][E](PTable): Power Buffer Reset + 136164 [433235][E](ERG_Mode): Watts previously processed. + 136165 [435355][E](ERG_Mode): Watts previously processed. + 136166 [436061][E](ERG_Mode): Proportional: -40.500000 + 136167 [436966][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 251, Cad 95, HR 138, Gear 8, Res 46, Current Pos 13789, Target Pos 13789 + 136168 [437472][E](ERG_Mode): Watts previously processed. + 136169 [438181][E](PTable): Using detected travel limits during homing + 136170 [438890][E](PTable): Averaged Entry: watts=249.800003, cad=94.300003, targetPosition=1381.199951, (7)(8) + 136171 [438891][E](PTData): Cleaned 2 readings + 136172 [438901][E](PTData): Existing entry averaged (7)(8)(1245), readings(1) + 136173 [438902][E](PTData): Lower Right Found 7, 12, tp1108 + 136174 [438912][E](PTData): Lower Up Found 4, 8, tp1080 + 136175 [438913][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 136176 [438914][E](PTable): New Entry Processed in 25 ms + 136177 [438924][E](PTable): Power Buffer Reset + 136178 [439596][E](ERG_Mode): Watts previously processed. + 136179 [441712][E](ERG_Mode): Watts previously processed. + 136180 [442415][E](ERG_Mode): Proportional: 1.500000 + 136181 [442982][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 243, Cad 93, HR 142, Gear 8, Res 46, Current Pos 13793, Target Pos 13793 + 136182 [443124][E](ERG_Mode): Watts previously processed. + 136183 [445242][E](PTable): Averaged Entry: watts=244.699997, cad=93.000000, targetPosition=1379.000000, (7)(8) + 136184 [445243][E](PTData): Cleaned 2 readings + 136185 [445253][E](PTData): Existing entry averaged (7)(8)(1244), readings(1) + 136186 [445254][E](PTData): Lower Right Found 7, 13, tp1109 + 136187 [445264][E](PTData): Lower Up Found 3, 8, tp1070 + 136188 [445265][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 136189 [445266][E](PTable): New Entry Processed in 24 ms + 136190 [445276][E](PTable): Power Buffer Reset + 136191 [445277][E](ERG_Mode): Watts previously processed. + 136192 [447362][E](ERG_Mode): Watts previously processed. + 136193 [448069][E](ERG_Mode): Proportional: -2.250000 + 136194 [448996][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 250, Cad 95, HR 144, Gear 8, Res 46, Current Pos 13736, Target Pos 13736 + 136195 [449486][E](ERG_Mode): Watts previously processed. + 136196 [451601][E](PTable): Averaged Entry: watts=257.200012, cad=94.900002, targetPosition=1374.000000, (7)(9) + 136197 [451602][E](PTData): Cleaned 2 readings + 136198 [451612][E](PTData): New entry recorded (7)(9)(1374) + 136199 [451613][E](PTData): Lower Right Found 7, 14, tp1109 + 136200 [451613][E](PTData): Lower Up Found 4, 9, tp1079 + 136201 [451624][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 136202 [451625][E](PTable): New Entry Processed in 24 ms + 136203 [451635][E](PTable): Power Buffer Reset + 136204 [451636][E](ERG_Mode): Watts previously processed. + 136205 [453721][E](ERG_Mode): Proportional: 40.500000 + 136206 [455013][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 248, Cad 93, HR 144, Gear 8, Res 46, Current Pos 13754, Target Pos 13754 + 136207 [455145][E](ERG_Mode): Watts previously processed. + 136208 [457261][E](ERG_Mode): Watts previously processed. + 136209 [457970][E](PTable): Averaged Entry: watts=238.199997, cad=93.900002, targetPosition=1372.699951, (7)(8) + 136210 [457971][E](PTData): Cleaned 2 readings + 136211 [457982][E](PTData): Existing entry averaged (7)(8)(1240), readings(1) + 136212 [457982][E](PTData): Lower Right Found 7, 15, tp1110 + 136213 [457992][E](PTData): Lower Up Found 2, 8, tp1061 + 136214 [457993][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 136215 [457995][E](PTable): New Entry Processed in 25 ms + 136216 [458005][E](PTable): Power Buffer Reset + 136217 [459376][E](ERG_Mode): Watts previously processed. + 136218 [460082][E](ERG_Mode): Proportional: 33.750000 + 136219 [461021][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 242, Cad 91, HR 146, Gear 8, Res 47, Current Pos 13841, Target Pos 13841 + 136220 [461500][E](ERG_Mode): Watts previously processed. + 136221 [463618][E](ERG_Mode): Watts previously processed. + 136222 [464327][E](PTable): Averaged Entry: watts=238.199997, cad=92.699997, targetPosition=1381.199951, (6)(8) + 136223 [464328][E](PTData): Cleaned 2 readings + 136224 [464339][E](PTData): New entry recorded (6)(8)(1381) + 136225 [464339][E](PTData): Lower Right Found 6, 11, tp1099 + 136226 [464339][E](PTData): Lower Up Found 1, 8, tp1052 + 136227 [464350][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 136228 [464351][E](PTable): New Entry Processed in 24 ms + 136229 [464362][E](PTable): Power Buffer Reset + 136230 [464365][E](FTMS_SERVER): 05 91 00 -> ERG Mode Target: 145 Current: 231 Incline: 138.619995. Responding: 80 05 01 + 136231 [464382][E](DirConManager): Sending response message type 0x04 to client 0 + 136232 [465035][E](ERG_Mode): SetPoint changed:175w Waiting:992ms PowerTable Result: 12840 + 136233 [467016][E](FTMS_SERVER): 11 00 00 39 03 28 33 -> Sim Mode Incline 8.250000. Responding: 80 11 01 + 136234 [467023][E](DirConManager): Sending response message type 0x04 to client 0 + 136235 [467046][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 207, Cad 89, HR 148, Gear 8, Res 43, Current Pos 12840, Target Pos 15375 + 136236 [467427][E](ERG_Mode): ERG wait expired, pos: 13081, tgt: 0 + 136237 [467970][E](FTMS_SERVER): 11 00 00 29 03 28 33 -> Sim Mode Incline 8.090000. Responding: 80 11 01 + 136238 [467977][E](DirConManager): Sending response message type 0x04 to client 0 + 136239 [468956][E](FTMS_SERVER): 11 00 00 25 03 28 33 -> Sim Mode Incline 8.050000. Responding: 80 11 01 + 136240 [468963][E](DirConManager): Sending response message type 0x04 to client 0 + 136241 [469886][E](FTMS_SERVER): 11 00 00 1a 03 28 33 -> Sim Mode Incline 7.940000. Responding: 80 11 01 + 136242 [469893][E](DirConManager): Sending response message type 0x04 to client 0 + 136243 [470809][E](FTMS_SERVER): 11 00 00 12 03 28 33 -> Sim Mode Incline 7.860000. Responding: 80 11 01 + 136244 [470814][E](DirConManager): Sending response message type 0x04 to client 0 + 136245 [471760][E](FTMS_SERVER): 11 00 00 09 03 28 33 -> Sim Mode Incline 7.770000. Responding: 80 11 01 + 136246 [471765][E](DirConManager): Sending response message type 0x04 to client 0 + 136247 [472374][E](PTable): Averaged Entry: watts=184.699997, cad=83.300003, targetPosition=1463.599976, (5)(6) + 136248 [472375][E](PTData): Cleaned 2 readings + 136249 [472386][E](PTData): Existing entry averaged (5)(6)(1276), readings(1) + 136250 [472386][E](PTData): Lower Right Found 5, 7, tp1088 + 136251 [472396][E](PTData): Lower Up Found 4, 6, tp1079 + 136252 [472397][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 1 ms + 136253 [472398][E](PTable): New Entry Processed in 24 ms + 136254 [472409][E](PTable): Power Buffer Reset + 136255 [472854][E](FTMS_SERVER): 11 00 00 03 03 28 33 -> Sim Mode Incline 7.710000. Responding: 80 11 01 + 136256 [472860][E](DirConManager): Sending response message type 0x04 to client 0 + 136257 [473064][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 184, Cad 68, HR 149, Gear 8, Res 51, Current Pos 14998, Target Pos 14997 + 136258 [473775][E](FTMS_SERVER): 11 00 00 fe 02 28 33 -> Sim Mode Incline 7.660000. Responding: 80 11 01 + 136259 [473782][E](DirConManager): Sending response message type 0x04 to client 0 + 136260 [475521][E](FTMS_SERVER): 11 00 00 f7 02 28 33 -> Sim Mode Incline 7.590000. Responding: 80 11 01 + 136261 [475526][E](DirConManager): Sending response message type 0x04 to client 0 + 136262 [475926][E](PTable): Using detected travel limits during homing + 136263 [476479][E](FTMS_SERVER): 11 00 00 f8 02 28 33 -> Sim Mode Incline 7.600000. Responding: 80 11 01 + 136264 [476484][E](DirConManager): Sending response message type 0x04 to client 0 + 136265 [477366][E](FTMS_SERVER): 11 00 00 f6 02 28 33 -> Sim Mode Incline 7.580000. Responding: 80 11 01 + 136266 [477373][E](DirConManager): Sending response message type 0x04 to client 0 + 136267 [478276][E](FTMS_SERVER): 11 00 00 f3 02 28 33 -> Sim Mode Incline 7.550000. Responding: 80 11 01 + 136268 [478283][E](DirConManager): Sending response message type 0x04 to client 0 + 136269 [479073][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 16, Cad 0, HR 149, Gear 8, Res 50, Current Pos 14885, Target Pos 14885 + 136270 [480021][E](FTMS_SERVER): 11 00 00 f7 02 28 33 -> Sim Mode Incline 7.590000. Responding: 80 11 01 + 136271 [480028][E](DirConManager): Sending response message type 0x04 to client 0 + 136272 [480981][E](FTMS_SERVER): 11 00 00 f6 02 28 33 -> Sim Mode Incline 7.580000. Responding: 80 11 01 + 136273 [480988][E](DirConManager): Sending response message type 0x04 to client 0 + 136274 [485090][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 146, Gear 8, Res 50, Current Pos 14906, Target Pos 14906 + 136275 [491102][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 138, Gear 8, Res 50, Current Pos 14906, Target Pos 14906 + 136276 [493236][E](FTMS_SERVER): 11 00 00 02 03 28 33 -> Sim Mode Incline 7.700000. Responding: 80 11 01 + 136277 [493241][E](DirConManager): Sending response message type 0x04 to client 0 + 136278 [494262][E](FTMS_SERVER): 11 00 00 06 03 28 33 -> Sim Mode Incline 7.740000. Responding: 80 11 01 + 136279 [494267][E](DirConManager): Sending response message type 0x04 to client 0 + 136280 [495293][E](FTMS_SERVER): 11 00 00 f2 02 28 33 -> Sim Mode Incline 7.540000. Responding: 80 11 01 + 136281 [495298][E](DirConManager): Sending response message type 0x04 to client 0 + 136282 [496192][E](FTMS_SERVER): 11 00 00 e6 02 28 33 -> Sim Mode Incline 7.420000. Responding: 80 11 01 + 136283 [496199][E](DirConManager): Sending response message type 0x04 to client 0 + 136284 [497110][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 134, Gear 8, Res 50, Current Pos 14794, Target Pos 14794 + 136285 [503126][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 125, Gear 8, Res 50, Current Pos 14794, Target Pos 14794 + 136286 [509140][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 117, Gear 8, Res 50, Current Pos 14794, Target Pos 14794 + 136287 [515156][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 103, Gear 8, Res 50, Current Pos 14794, Target Pos 14794 + 136288 [521164][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 94, Gear 8, Res 50, Current Pos 14794, Target Pos 14794 + 136289 [523440][E](FTMS_SERVER): 11 00 00 f1 02 28 33 -> Sim Mode Incline 7.530000. Responding: 80 11 01 + 136290 [523448][E](DirConManager): Sending response message type 0x04 to client 0 + 136291 [524359][E](FTMS_SERVER): 11 00 00 f6 02 28 33 -> Sim Mode Incline 7.580000. Responding: 80 11 01 + 136292 [524366][E](DirConManager): Sending response message type 0x04 to client 0 + 136293 [526827][E](FTMS_SERVER): 11 00 00 f8 02 28 33 -> Sim Mode Incline 7.600000. Responding: 80 11 01 + 136294 [526834][E](DirConManager): Sending response message type 0x04 to client 0 + 136295 [527174][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 86, Gear 8, Res 50, Current Pos 14920, Target Pos 14920 + 136296 [527834][E](FTMS_SERVER): 11 00 00 06 03 28 33 -> Sim Mode Incline 7.740000. Responding: 80 11 01 + 136297 [527841][E](DirConManager): Sending response message type 0x04 to client 0 + 136298 [528773][E](FTMS_SERVER): 11 00 00 07 03 28 33 -> Sim Mode Incline 7.750000. Responding: 80 11 01 + 136299 [528778][E](DirConManager): Sending response message type 0x04 to client 0 + 136300 [533186][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 83, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136301 [539200][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 84, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136302 [545210][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 88, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136303 [551222][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 89, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136304 [557239][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 92, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136305 [563254][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 84, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136306 [569272][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 83, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136307 [575285][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 86, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136308 [581300][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 83, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136309 [587317][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 87, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136310 [593334][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 89, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136311 [599346][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 81, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136312 [605358][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 76, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136313 [611371][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 75, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136314 [617389][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 78, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136315 [623405][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 79, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136316 [629421][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 78, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136317 [635437][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 77, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136318 [641446][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 77, Gear 8, Res 51, Current Pos 15025, Target Pos 15025 + 136319 [ 55][E](Main): Compiled Jan 4 202618:05:42 + 136320 [ 56][E](Main): Current Board Revision is: Revision Two + 136321 [ 58][E](Main): Mounting Filesystem + 136322 [ 66][E](Config): Reading File: /config.txt + 136323 [ 97][E](Config): Config File Loaded: /config.txt + 136324 [ 98][E](Config): Contents of file: /config.txt + 136325 [ 130][E](Config): Writing File: /config.txt + 136326 [ 220][E](Main): Using homing data from config file. + 136327 [ 421][E](HTTP_Server): Build version check. FS:'25.12.28-Marc_Roy-15-g808c554' CUR:'25.12.28-Marc_Roy-15-g808c554' + 136328 [ 422][E](HTTP_Server): Connecting to: NetwalkerLair + 136329 [ 1588][E](HTTP_Server): Waiting for connection to be established... + 136330 [ 2588][E](HTTP_Server): Waiting for connection to be established... + 136331 [ 2596][E](HTTP_Server): Connected to NetwalkerLair IP address: 192.168.1.180 + 136332 [ 2597][E](HTTP_Server): Open http://SmartPelo.local/ + 136333 [ 2607][E](DirConManager): Adding DirCon MDNS service: _wahoo-fitness-tnp.tcp on port 8081 + 136334 [ 4793][E](Config): Writing File: /config.txt + 136335 [ 5118][E](BLE_Server): Bluetooth Remote Client Connected: 58:14:3c:fd:ec:38 Connected Clients: 1 + 136336 [ 6182][E](BLE_Server): MTU updated: 512 for connection ID: 0 + 136337 [ 6570][E](BLE_Server): MTU updated: 512 for connection ID: 0 + 136338 [ 7177][E](BLE_Server): MTU updated: 515 for connection ID: 0 + 136339 [ 7210][E](BLE_Server): Client ID: 0 Address: 58:14:3c:fd:ec:38 Subscribed to notifications for 0x2ad2 + 136340 [ 7255][E](Custom_C): Subscribe from 58:14:3c:fd:ec:38 + 136341 [ 8966][E](BLE_Server): MTU updated: 515 for connection ID: 0 + 136342 [ 9427][E](BLE_Server): MTU updated: 515 for connection ID: 0 + 136343 [ 10151][E](Main): PM Con 0, CAD con 0, HRM Con 0, W 0, Cad 0, HR 0, Gear 0, Res 0, Current Pos 0, Target Pos 0 + 136344 [ 10246][E](BLE_Client): Devices not connected: HRM PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 136345 [ 10256][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 136346 [ 10721][E](BLE_Client): Found device Polar OH1 B9B6D624 d6 with services: 0x180d 0xfeee + 136347 [ 10721][E](BLE_Client): Supported Device: Polar OH1 B9B6D624 d6 with service Heart Rate Service + 136348 [ 10732][E](BLE_Client): HRM Name Matched Polar OH1 B9B6D624 d6 + 136349 [ 10733][E](BLE_Client): Setting Device Polar OH1 B9B6D624 d6 + 136350 [ 10744][E](BLE_Client): Set Polar OH1 B9B6D624 d6 with no current connection. + 136351 [ 10754][E](BLE_Client): Polar OH1 B9B6D624 d6 assigned slot: 0 + 136352 [ 10764][E](BLE_Client): Stopping scan before connecting Polar OH1 B9B6D624 d6 on slot 0 ... + 136353 [ 10866][E](BLE_Client): Connecting Polar OH1 B9B6D624 d6 on slot 0 ... + 136354 [ 10867][E](BLE_Client): Initiating Server Connection + 136355 [ 10867][E](BLE_Client): Connecting slot 0 + 136356 [ 10878][E](BLE_Client): Getting service info for device: Polar OH1 B9B6D624 with 2 services + 136357 [ 10889][E](BLE_Client): Trying to connect to Heart Rate Service (Service UUID: 0x180d) + 136358 [ 10900][E](BLE_Client): - Created new client + 136359 [ 11589][E](BLE_Client): Connected, a0:9e:1a:b9:b6:d6 + 136360 [ 11590][E](BLE_Client): Connected to: Polar OH1 B9B6D624 d6 - a0:9e:1a:b9:b6:d6 RSSI -62 + 136361 [ 11591][E](BLE_Client): Setting Device Polar OH1 B9B6D624 d6 + 136362 [ 12491][E](BLE_Client): Registered HRM on Connect + 136363 [ 12498][E](BLE_Client): Device Connected + 136364 [ 12498][E](BLE_Client): We are now connected to Polar OH1 B9B6D624 d6 + 136365 [ 12600][E](BLE_Client): Post connecting: Polar OH1 B9B6D624 d6 , ConnID 1, PrimaryChar 0x2a37 + 136366 [ 13228][E](BLE_Client): Found Heart Rate Service + 136367 [ 13566][E](BLE_Client): Found 0x180d, 0x2a37 + 136368 [ 13848][E](BLE_Client): Subscribed to Heart Rate Service 0x2a37 handle: 40 + 136369 [ 15254][E](BLE_Client): a0:9e:1a:b9:b6:d6 Battery updated 90 + 136370 [ 16161][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 78, Gear 0, Res 0, Current Pos 0, Target Pos 0 + 136371 [ 16298][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 136372 [ 16298][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 136373 [ 16340][E](BLE_Client): Found device ASSIOMA59350R d5 with services: 0x180f 6e400001-b5a3-f393-e0a9-e50e24dcca9e + 136374 [ 16829][E](BLE_Client): Found device ASSIOMA17287L 16 with services: 0x1818 0x180f 6e400001-b5a3-f393-e0a9-e50e24dcca9e + 136375 [ 16830][E](BLE_Client): Supported Device: ASSIOMA17287L 16 with service Cycling Power Service + 136376 [ 16840][E](BLE_Client): PM Name Matched ASSIOMA17287L 16 + 136377 [ 16851][E](BLE_Client): Slot 0 contains Polar OH1 B9B6D624 d6 + 136378 [ 16852][E](BLE_Client): Setting Device ASSIOMA17287L 16 + 136379 [ 16864][E](BLE_Client): Set ASSIOMA17287L 16 with no current connection. + 136380 [ 16865][E](BLE_Client): ASSIOMA17287L 16 assigned slot: 1 + 136381 [ 16920][E](BLE_Client): Stopping scan before connecting ASSIOMA17287L 16 on slot 1 ... + 136382 [ 17022][E](BLE_Client): Connecting ASSIOMA17287L 16 on slot 1 ... + 136383 [ 17023][E](BLE_Client): Initiating Server Connection + 136384 [ 17023][E](BLE_Client): doConnect on slot 0 not set + 136385 [ 17033][E](BLE_Client): Connecting slot 1 + 136386 [ 17034][E](BLE_Client): Getting service info for device: ASSIOMA17287L with 3 services + 136387 [ 19557][E](BLE_Client): Connected, e8:fe:6e:91:9f:16 + 136388 [ 19559][E](BLE_Client): Connected to: ASSIOMA17287L 16 - e8:fe:6e:91:9f:16 RSSI -64 + 136389 [ 19560][E](BLE_Client): Setting Device ASSIOMA17287L 16 + 136390 [ 20121][E](BLE_Client): Registered PM on Connect + 136391 [ 20123][E](BLE_Client): Device Connected + 136392 [ 20123][E](BLE_Client): We are now connected to ASSIOMA17287L 16 + 136393 [ 20235][E](BLE_Client): Post connecting: ASSIOMA17287L 16 , ConnID 2, PrimaryChar 0x2a63 + 136394 [ 20239][E](BLE_Client): Found Cycling Power Service + 136395 [ 20627][E](BLE_Client): Found 0x1818, 0x2a63 + 136396 [ 20851][E](BLE_Client): Subscribed to Cycling Power Service 0x2a63 handle: 22 + 136397 [ 20852][E](BLE_Client): Found 0x1818, 0x2a65 + 136398 [ 20852][E](BLE_Client): Found 0x1818, 0x2a66 + 136399 [ 21132][E](BLE_Client): Subscribed to Cycling Power Service 0x2a66 handle: 27 + 136400 [ 21133][E](BLE_Client): Found 0x1818, 0x2a5d + 136401 [ 22177][E](Main): PM Con 1, CAD con 0, HRM Con 1, W 124, Cad 0, HR 81, Gear 0, Res 0, Current Pos 0, Target Pos 0 + 136402 [ 22595][E](BLE_Client): Found Flywheel UART Service + 136403 [ 23158][E](BLE_Client): Found 6e400001-b5a3-f393-e0a9-e50e24dcca9e, 6e400003-b5a3-f393-e0a9-e50e24dcca9e + 136404 [ 23439][E](BLE_Client): Subscribed to Flywheel UART Service 6e400003-b5a3-f393-e0a9-e50e24dcca9e handle: 13 + 136405 [ 23440][E](BLE_Client): Found 6e400001-b5a3-f393-e0a9-e50e24dcca9e, 6e400004-b5a3-f393-e0a9-e50e24dcca9e + 136406 [ 23720][E](BLE_Client): Subscribed to Flywheel UART Service 6e400004-b5a3-f393-e0a9-e50e24dcca9e handle: 16 + 136407 [ 23721][E](BLE_Client): Found 6e400001-b5a3-f393-e0a9-e50e24dcca9e, 6e400002-b5a3-f393-e0a9-e50e24dcca9e + 136408 [ 24114][E](BLE_Client): e8:fe:6e:91:9f:16 Battery updated 98 + 136409 [ 25091][E](DirConManager): New DirCon client connected from 192.168.1.106, assigned slot 0 + 136410 [ 25174][E](DirConMessage): Discover services response contains 0 UUIDs + 136411 [ 25175][E](DirConManager): Initialized service discovery with 4 services + 136412 [ 25185][E](DirConManager): Received service discovery request from client 0 + 136413 [ 25186][E](DirConManager): Responding with 4 service UUIDs + 136414 [ 25196][E](DirConManager): Sending response message type 0x01 to client 0 + 136415 [ 25196][E](DirConManager): Discover services response contains 4 UUIDs + 136416 [ 25207][E](DirConManager): Service 0: 0x1818 + 136417 [ 25207][E](DirConManager): Service 1: 0x1816 + 136418 [ 25218][E](DirConManager): Service 2: 0x180d + 136419 [ 25218][E](DirConManager): Service 3: 0x1826 + 136420 [ 25218][E](DirConMessage): Adding 4 service UUIDs to discovery response + 136421 [ 25229][E](DirConMessage): Adding service 0 UUID: 0x1818 + 136422 [ 25229][E](DirConMessage): Adding service 1 UUID: 0x1816 + 136423 [ 25239][E](DirConMessage): Adding service 2 UUID: 0x180d + 136424 [ 25405][E](DirConManager): Sending response message type 0x02 to client 0 + 136425 [ 25514][E](DirConManager): Sending response message type 0x02 to client 0 + 136426 [ 25529][E](DirConManager): Sending response message type 0x02 to client 0 + 136427 [ 25553][E](DirConManager): Sending response message type 0x02 to client 0 + 136428 [ 25599][E](DirConManager): Sending response message type 0x03 to client 0 + 136429 [ 25602][E](DirConManager): Client 0 subscribed to characteristic 00002a63-0000-1000-8000-00805f9b34fb + 136430 [ 25613][E](DirConManager): Sending response message type 0x05 to client 0 + 136431 [ 25692][E](DirConManager): Client 0 subscribed to characteristic 00002a5b-0000-1000-8000-00805f9b34fb + 136432 [ 25693][E](DirConManager): Sending response message type 0x05 to client 0 + 136433 [ 25707][E](DirConManager): Sending response message type 0x03 to client 0 + 136434 [ 25710][E](DirConManager): Client 0 subscribed to characteristic 00002a37-0000-1000-8000-00805f9b34fb + 136435 [ 26269][E](BLE_Client): Spin Down initiated via BLE Client task. + 136436 [ 26270][E](Main): Starting homing procedure... + 136437 [ 27530][E](Main): Stepper power is now 720. read:703 + 136438 [ 28056][E](FTMS_SERVER): 11 00 00 eb 02 28 33 -> Sim Mode Incline 7.470000. Responding: 80 11 01 + 136439 [ 28062][E](DirConManager): Sending response message type 0x04 to client 0 + 136440 [ 28078][E](Main): Homing backward (min). Stable Threshold: 302, Sensitivity: 50 + 136441 [ 28088][E](Main): Homing... Current SG: 358, Baseline: 302, Target: < 252 + 136442 [ 28188][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 157, Cad 63, HR 90, Gear 0, Res 0, Current Pos 0, Target Pos 0 + 136443 [ 28974][E](FTMS_SERVER): 11 00 00 e3 02 28 33 -> Sim Mode Incline 7.390000. Responding: 80 11 01 + 136444 [ 28981][E](DirConManager): Sending response message type 0x04 to client 0 + 136445 [ 29096][E](Main): Homing... Current SG: 366, Baseline: 302, Target: < 252 + 136446 [ 29878][E](FTMS_SERVER): 11 00 00 de 02 28 33 -> Sim Mode Incline 7.340000. Responding: 80 11 01 + 136447 [ 29886][E](DirConManager): Sending response message type 0x04 to client 0 + 136448 [ 30131][E](Main): Homing... Current SG: 356, Baseline: 302, Target: < 252 + 136449 [ 30855][E](FTMS_SERVER): 11 00 00 db 02 28 33 -> Sim Mode Incline 7.310000. Responding: 80 11 01 + 136450 [ 30862][E](DirConManager): Sending response message type 0x04 to client 0 + 136451 [ 31140][E](Main): Homing... Current SG: 360, Baseline: 302, Target: < 252 + 136452 [ 31847][E](FTMS_SERVER): 11 00 00 e2 02 28 33 -> Sim Mode Incline 7.380000. Responding: 80 11 01 + 136453 [ 31854][E](DirConManager): Sending response message type 0x04 to client 0 + 136454 [ 32149][E](Main): Homing... Current SG: 346, Baseline: 302, Target: < 252 + 136455 [ 32763][E](FTMS_SERVER): 11 00 00 e4 02 28 33 -> Sim Mode Incline 7.400000. Responding: 80 11 01 + 136456 [ 32768][E](DirConManager): Sending response message type 0x04 to client 0 + 136457 [ 33158][E](Main): Homing... Current SG: 358, Baseline: 302, Target: < 252 + 136458 [ 33682][E](FTMS_SERVER): 11 00 00 e5 02 28 33 -> Sim Mode Incline 7.410000. Responding: 80 11 01 + 136459 [ 33689][E](DirConManager): Sending response message type 0x04 to client 0 + 136460 [ 34169][E](Main): Homing... Current SG: 346, Baseline: 302, Target: < 252 + 136461 [ 34200][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 64, Cad 85, HR 101, Gear 0, Res 0, Current Pos 0, Target Pos 0 + 136462 [ 34699][E](FTMS_SERVER): 11 00 00 e4 02 28 33 -> Sim Mode Incline 7.400000. Responding: 80 11 01 + 136463 [ 34707][E](DirConManager): Sending response message type 0x04 to client 0 + 136464 [ 35173][E](Main): Homing... Current SG: 358, Baseline: 302, Target: < 252 + 136465 [ 35660][E](FTMS_SERVER): 11 00 00 df 02 28 33 -> Sim Mode Incline 7.350000. Responding: 80 11 01 + 136466 [ 35667][E](DirConManager): Sending response message type 0x04 to client 0 + 136467 [ 36177][E](Main): Homing... Current SG: 356, Baseline: 302, Target: < 252 + 136468 [ 36659][E](FTMS_SERVER): 11 00 00 dd 02 28 33 -> Sim Mode Incline 7.330000. Responding: 80 11 01 + 136469 [ 36666][E](DirConManager): Sending response message type 0x04 to client 0 + 136470 [ 37179][E](Main): Homing... Current SG: 368, Baseline: 302, Target: < 252 + 136471 [ 38181][E](Main): Homing... Current SG: 352, Baseline: 302, Target: < 252 + 136472 [ 38378][E](FTMS_SERVER): 11 00 00 df 02 28 33 -> Sim Mode Incline 7.350000. Responding: 80 11 01 + 136473 [ 38386][E](DirConManager): Sending response message type 0x04 to client 0 + 136474 [ 39187][E](Main): Homing... Current SG: 360, Baseline: 302, Target: < 252 + 136475 [ 39406][E](FTMS_SERVER): 11 00 00 e2 02 28 33 -> Sim Mode Incline 7.380000. Responding: 80 11 01 + 136476 [ 39413][E](DirConManager): Sending response message type 0x04 to client 0 + 136477 [ 39419][E](Main): Stall detected! SG dropped to 236. Threshold: 252 + 136478 [ 39550][E](Main): StealthChop is now 1 + 136479 [ 39568][E](Main): Stepper power is now 900. read:703 + 136480 [ 40210][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 4, Cad 85, HR 106, Gear 0, Res 0, Current Pos -16313, Target Pos 0 + 136481 [ 40827][E](Main): Stepper power is now 720. read:703 + 136482 [ 41351][E](Main): Homing backward (min). Stable Threshold: 325, Sensitivity: 50 + 136483 [ 41361][E](Main): Homing... Current SG: 364, Baseline: 325, Target: < 275 + 136484 [ 41901][E](Main): Stall detected! SG dropped to 246. Threshold: 275 + 136485 [ 42020][E](Main): StealthChop is now 1 + 136486 [ 42038][E](Main): Stepper power is now 900. read:703 + 136487 [ 43284][E](Main): Min position found and set to 0. + 136488 [ 43304][E](Main): StealthChop is now 1 + 136489 [ 43322][E](Main): Stepper power is now 900. read:887 + 136490 [ 43323][E](Main): Homing procedure complete. + 136491 [ 43329][E](Main): Shift +8 pos 8 tgt 14766 min 0 max 29356 r_min -2000 r_max 2000 + 136492 [ 43330][E](PTable): Loading Power Table.... + 136493 [ 43360][E](PTable): Loading power table version 6, Size 312, Homed 1 + 136494 [ 43387][E](PTable): Loaded values directly + 136495 [ 45556][E](FTMS_SERVER): 11 00 00 db 02 28 33 -> Sim Mode Incline 7.310000. Responding: 80 11 01 + 136496 [ 45563][E](DirConManager): Sending response message type 0x04 to client 0 + 136497 [ 46224][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 16, Cad 87, HR 108, Gear 8, Res 22, Current Pos 8161, Target Pos 14717 + 136498 [ 46475][E](FTMS_SERVER): 11 00 00 e0 02 28 33 -> Sim Mode Incline 7.360000. Responding: 80 11 01 + 136499 [ 46481][E](DirConManager): Sending response message type 0x04 to client 0 + 136500 [ 47581][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 136501 [ 47581][E](PTable): Power Buffer Reset + 136502 [ 47616][E](FTMS_SERVER): 11 00 00 da 02 28 33 -> Sim Mode Incline 7.300000. Responding: 80 11 01 + 136503 [ 47623][E](DirConManager): Sending response message type 0x04 to client 0 + 136504 [ 48560][E](FTMS_SERVER): 11 00 00 df 02 28 33 -> Sim Mode Incline 7.350000. Responding: 80 11 01 + 136505 [ 48568][E](DirConManager): Sending response message type 0x04 to client 0 + 136506 [ 50368][E](FTMS_SERVER): 11 00 00 de 02 28 33 -> Sim Mode Incline 7.340000. Responding: 80 11 01 + 136507 [ 50376][E](DirConManager): Sending response message type 0x04 to client 0 + 136508 [ 51289][E](FTMS_SERVER): 11 00 00 dc 02 28 33 -> Sim Mode Incline 7.320000. Responding: 80 11 01 + 136509 [ 51296][E](DirConManager): Sending response message type 0x04 to client 0 + 136510 [ 52240][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 272, Cad 85, HR 106, Gear 8, Res 50, Current Pos 14724, Target Pos 14724 + 136511 [ 52962][E](FTMS_SERVER): 11 00 00 da 02 28 33 -> Sim Mode Incline 7.300000. Responding: 80 11 01 + 136512 [ 52969][E](DirConManager): Sending response message type 0x04 to client 0 + 136513 [ 53933][E](PTable): Averaged Entry: watts=165.199997, cad=86.000000, targetPosition=1468.099976, (5)(6) + 136514 [ 53934][E](PTData): Cleaned 291 readings + 136515 [ 53945][E](PTData): New entry recorded (5)(6)(1468) + 136516 [ 53946][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136517 [ 53957][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 136518 [ 53964][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 136519 [ 53965][E](PTable): New Entry Processed in 33 ms + 136520 [ 53966][E](PTable): Power Buffer Reset + 136521 [ 53980][E](FTMS_SERVER): 11 00 00 d6 02 28 33 -> Sim Mode Incline 7.260000. Responding: 80 11 01 + 136522 [ 53987][E](DirConManager): Sending response message type 0x04 to client 0 + 136523 [ 55805][E](FTMS_SERVER): 11 00 00 d5 02 28 33 -> Sim Mode Incline 7.250000. Responding: 80 11 01 + 136524 [ 55810][E](DirConManager): Sending response message type 0x04 to client 0 + 136525 [ 56712][E](FTMS_SERVER): 11 00 00 d0 02 28 33 -> Sim Mode Incline 7.200000. Responding: 80 11 01 + 136526 [ 56719][E](DirConManager): Sending response message type 0x04 to client 0 + 136527 [ 57676][E](FTMS_SERVER): 11 00 00 d1 02 28 33 -> Sim Mode Incline 7.210000. Responding: 80 11 01 + 136528 [ 57684][E](DirConManager): Sending response message type 0x04 to client 0 + 136529 [ 58255][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 241, Cad 82, HR 106, Gear 8, Res 49, Current Pos 14647, Target Pos 14647 + 136530 [ 59473][E](FTMS_SERVER): 11 00 00 d0 02 28 33 -> Sim Mode Incline 7.200000. Responding: 80 11 01 + 136531 [ 59478][E](DirConManager): Sending response message type 0x04 to client 0 + 136532 [ 60297][E](PTable): Averaged Entry: watts=241.100006, cad=84.000000, targetPosition=1465.800049, (5)(8) + 136533 [ 60298][E](PTData): Cleaned 290 readings + 136534 [ 60308][E](PTData): New entry recorded (5)(8)(1465) + 136535 [ 60309][E](PTData): Greater Left Found 5, 6, tp1468 + 136536 [ 60319][E](PTData): Fit Valid: 1, N: 9, Quad: 0, Time: 0 ms + 136537 [ 60321][E](PTable): New Entry Processed in 25 ms + 136538 [ 60321][E](PTable): Power Buffer Reset + 136539 [ 60396][E](FTMS_SERVER): 11 00 00 ce 02 28 33 -> Sim Mode Incline 7.180000. Responding: 80 11 01 + 136540 [ 60404][E](DirConManager): Sending response message type 0x04 to client 0 + 136541 [ 61432][E](FTMS_SERVER): 11 00 00 c8 02 28 33 -> Sim Mode Incline 7.120000. Responding: 80 11 01 + 136542 [ 61439][E](DirConManager): Sending response message type 0x04 to client 0 + 136543 [ 62377][E](FTMS_SERVER): 11 00 00 cc 02 28 33 -> Sim Mode Incline 7.160000. Responding: 80 11 01 + 136544 [ 62385][E](DirConManager): Sending response message type 0x04 to client 0 + 136545 [ 63384][E](FTMS_SERVER): 11 00 00 cb 02 28 33 -> Sim Mode Incline 7.150000. Responding: 80 11 01 + 136546 [ 63391][E](DirConManager): Sending response message type 0x04 to client 0 + 136547 [ 64264][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 242, Cad 84, HR 108, Gear 8, Res 49, Current Pos 14605, Target Pos 14605 + 136548 [ 64288][E](FTMS_SERVER): 11 00 00 cc 02 28 33 -> Sim Mode Incline 7.160000. Responding: 80 11 01 + 136549 [ 64293][E](DirConManager): Sending response message type 0x04 to client 0 + 136550 [ 65311][E](FTMS_SERVER): 11 00 00 c6 02 28 33 -> Sim Mode Incline 7.100000. Responding: 80 11 01 + 136551 [ 65318][E](DirConManager): Sending response message type 0x04 to client 0 + 136552 [ 66334][E](FTMS_SERVER): 11 00 00 c7 02 28 33 -> Sim Mode Incline 7.110000. Responding: 80 11 01 + 136553 [ 66339][E](DirConManager): Sending response message type 0x04 to client 0 + 136554 [ 66645][E](PTable): Averaged Entry: watts=235.800003, cad=83.699997, targetPosition=1459.699951, (5)(8) + 136555 [ 66646][E](PTData): Cleaned 1 readings + 136556 [ 66656][E](PTData): New entry recorded (5)(8)(1459) + 136557 [ 66658][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136558 [ 66669][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 136559 [ 66677][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 136560 [ 66678][E](PTable): New Entry Processed in 33 ms + 136561 [ 66679][E](PTable): Power Buffer Reset + 136562 [ 67290][E](FTMS_SERVER): 11 00 00 c6 02 28 33 -> Sim Mode Incline 7.100000. Responding: 80 11 01 + 136563 [ 67296][E](DirConManager): Sending response message type 0x04 to client 0 + 136564 [ 68294][E](FTMS_SERVER): 11 00 00 c5 02 28 33 -> Sim Mode Incline 7.090000. Responding: 80 11 01 + 136565 [ 68301][E](DirConManager): Sending response message type 0x04 to client 0 + 136566 [ 69212][E](FTMS_SERVER): 11 00 00 c7 02 28 33 -> Sim Mode Incline 7.110000. Responding: 80 11 01 + 136567 [ 69219][E](DirConManager): Sending response message type 0x04 to client 0 + 136568 [ 70132][E](FTMS_SERVER): 11 00 00 c2 02 28 33 -> Sim Mode Incline 7.060000. Responding: 80 11 01 + 136569 [ 70139][E](DirConManager): Sending response message type 0x04 to client 0 + 136570 [ 70273][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 236, Cad 83, HR 111, Gear 8, Res 49, Current Pos 14551, Target Pos 14542 + 136571 [ 71076][E](FTMS_SERVER): 11 00 00 c8 02 28 33 -> Sim Mode Incline 7.120000. Responding: 80 11 01 + 136572 [ 71083][E](DirConManager): Sending response message type 0x04 to client 0 + 136573 [ 72085][E](FTMS_SERVER): 11 00 00 c4 02 28 33 -> Sim Mode Incline 7.080000. Responding: 80 11 01 + 136574 [ 72091][E](DirConManager): Sending response message type 0x04 to client 0 + 136575 [ 72995][E](PTable): Averaged Entry: watts=238.199997, cad=84.300003, targetPosition=1456.300049, (5)(8) + 136576 [ 72996][E](PTData): Cleaned 290 readings + 136577 [ 73006][E](PTData): Existing entry averaged (5)(8)(1458), readings(2) + 136578 [ 73008][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136579 [ 73019][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 136580 [ 73027][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 136581 [ 73029][E](PTable): New Entry Processed in 34 ms + 136582 [ 73029][E](PTable): Power Buffer Reset + 136583 [ 73816][E](FTMS_SERVER): 11 00 00 c5 02 28 33 -> Sim Mode Incline 7.090000. Responding: 80 11 01 + 136584 [ 73823][E](DirConManager): Sending response message type 0x04 to client 0 + 136585 [ 76285][E](FTMS_SERVER): 11 00 00 c6 02 28 33 -> Sim Mode Incline 7.100000. Responding: 80 11 01 + 136586 [ 76290][E](DirConManager): Sending response message type 0x04 to client 0 + 136587 [ 76292][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 260, Cad 87, HR 118, Gear 8, Res 49, Current Pos 14563, Target Pos 14563 + 136588 [ 78851][E](FTMS_SERVER): 11 00 00 c3 02 28 33 -> Sim Mode Incline 7.070000. Responding: 80 11 01 + 136589 [ 78856][E](DirConManager): Sending response message type 0x04 to client 0 + 136590 [ 79356][E](PTable): Averaged Entry: watts=248.899994, cad=86.500000, targetPosition=1456.000000, (5)(8) + 136591 [ 79357][E](PTData): Cleaned 290 readings + 136592 [ 79368][E](PTData): Existing entry averaged (5)(8)(1457), readings(3) + 136593 [ 79369][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136594 [ 79380][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 136595 [ 79388][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 136596 [ 79390][E](PTable): New Entry Processed in 35 ms + 136597 [ 79390][E](PTable): Power Buffer Reset + 136598 [ 79400][E](PTable): Using detected travel limits during homing + 136599 [ 79887][E](FTMS_SERVER): 11 00 00 c2 02 28 33 -> Sim Mode Incline 7.060000. Responding: 80 11 01 + 136600 [ 79892][E](DirConManager): Sending response message type 0x04 to client 0 + 136601 [ 80796][E](FTMS_SERVER): 11 00 00 c6 02 28 33 -> Sim Mode Incline 7.100000. Responding: 80 11 01 + 136602 [ 80803][E](DirConManager): Sending response message type 0x04 to client 0 + 136603 [ 81689][E](FTMS_SERVER): 11 00 00 c7 02 28 33 -> Sim Mode Incline 7.110000. Responding: 80 11 01 + 136604 [ 81697][E](DirConManager): Sending response message type 0x04 to client 0 + 136605 [ 82319][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 255, Cad 87, HR 123, Gear 8, Res 49, Current Pos 14577, Target Pos 14577 + 136606 [ 82638][E](FTMS_SERVER): 11 00 00 c2 02 28 33 -> Sim Mode Incline 7.060000. Responding: 80 11 01 + 136607 [ 82643][E](DirConManager): Sending response message type 0x04 to client 0 + 136608 [ 83639][E](FTMS_SERVER): 11 00 00 c3 02 28 33 -> Sim Mode Incline 7.070000. Responding: 80 11 01 + 136609 [ 83645][E](DirConManager): Sending response message type 0x04 to client 0 + 136610 [ 84604][E](FTMS_SERVER): 11 00 00 c8 02 28 33 -> Sim Mode Incline 7.120000. Responding: 80 11 01 + 136611 [ 84610][E](DirConManager): Sending response message type 0x04 to client 0 + 136612 [ 85603][E](FTMS_SERVER): 11 00 00 c6 02 28 33 -> Sim Mode Incline 7.100000. Responding: 80 11 01 + 136613 [ 85610][E](DirConManager): Sending response message type 0x04 to client 0 + 136614 [ 85705][E](PTable): Averaged Entry: watts=251.300003, cad=86.699997, targetPosition=1455.300049, (5)(8) + 136615 [ 85706][E](PTData): Cleaned 290 readings + 136616 [ 85716][E](PTData): Existing entry averaged (5)(8)(1456), readings(4) + 136617 [ 85718][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136618 [ 85729][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 136619 [ 85738][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 136620 [ 85739][E](PTable): New Entry Processed in 34 ms + 136621 [ 85739][E](PTable): Power Buffer Reset + 136622 [ 86506][E](FTMS_SERVER): 11 00 00 c9 02 28 33 -> Sim Mode Incline 7.130000. Responding: 80 11 01 + 136623 [ 86513][E](DirConManager): Sending response message type 0x04 to client 0 + 136624 [ 88272][E](FTMS_SERVER): 11 00 00 c7 02 28 33 -> Sim Mode Incline 7.110000. Responding: 80 11 01 + 136625 [ 88277][E](DirConManager): Sending response message type 0x04 to client 0 + 136626 [ 88330][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 238, Cad 86, HR 128, Gear 8, Res 49, Current Pos 14586, Target Pos 14577 + 136627 [ 89283][E](FTMS_SERVER): 11 00 00 ca 02 28 33 -> Sim Mode Incline 7.140000. Responding: 80 11 01 + 136628 [ 89290][E](DirConManager): Sending response message type 0x04 to client 0 + 136629 [ 90202][E](FTMS_SERVER): 11 00 00 cb 02 28 33 -> Sim Mode Incline 7.150000. Responding: 80 11 01 + 136630 [ 90209][E](DirConManager): Sending response message type 0x04 to client 0 + 136631 [ 91122][E](FTMS_SERVER): 11 00 00 d1 02 28 33 -> Sim Mode Incline 7.210000. Responding: 80 11 01 + 136632 [ 91129][E](DirConManager): Sending response message type 0x04 to client 0 + 136633 [ 92072][E](PTable): Averaged Entry: watts=247.500000, cad=86.500000, targetPosition=1459.300049, (5)(8) + 136634 [ 92073][E](PTData): Cleaned 290 readings + 136635 [ 92084][E](PTData): Existing entry averaged (5)(8)(1456), readings(5) + 136636 [ 92085][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136637 [ 92097][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 136638 [ 92105][E](PTData): Fit Valid: 1, N: 10, Quad: 1, Time: 1 ms + 136639 [ 92106][E](PTable): New Entry Processed in 34 ms + 136640 [ 92106][E](PTable): Power Buffer Reset + 136641 [ 92141][E](FTMS_SERVER): 11 00 00 d3 02 28 33 -> Sim Mode Incline 7.230000. Responding: 80 11 01 + 136642 [ 92148][E](DirConManager): Sending response message type 0x04 to client 0 + 136643 [ 93103][E](FTMS_SERVER): 11 00 00 d4 02 28 33 -> Sim Mode Incline 7.240000. Responding: 80 11 01 + 136644 [ 93110][E](DirConManager): Sending response message type 0x04 to client 0 + 136645 [ 94106][E](FTMS_SERVER): 11 00 00 d8 02 28 33 -> Sim Mode Incline 7.280000. Responding: 80 11 01 + 136646 [ 94111][E](DirConManager): Sending response message type 0x04 to client 0 + 136647 [ 94346][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 247, Cad 86, HR 132, Gear 8, Res 49, Current Pos 14696, Target Pos 14696 + 136648 [ 95109][E](FTMS_SERVER): 11 00 00 d9 02 28 33 -> Sim Mode Incline 7.290000. Responding: 80 11 01 + 136649 [ 95114][E](DirConManager): Sending response message type 0x04 to client 0 + 136650 [ 96041][E](FTMS_SERVER): 11 00 00 db 02 28 33 -> Sim Mode Incline 7.310000. Responding: 80 11 01 + 136651 [ 96048][E](DirConManager): Sending response message type 0x04 to client 0 + 136652 [ 97063][E](FTMS_SERVER): 11 00 00 de 02 28 33 -> Sim Mode Incline 7.340000. Responding: 80 11 01 + 136653 [ 97070][E](DirConManager): Sending response message type 0x04 to client 0 + 136654 [ 98015][E](FTMS_SERVER): 11 00 00 e2 02 28 33 -> Sim Mode Incline 7.380000. Responding: 80 11 01 + 136655 [ 98022][E](DirConManager): Sending response message type 0x04 to client 0 + 136656 [ 98438][E](PTable): Averaged Entry: watts=258.100006, cad=87.500000, targetPosition=1469.599976, (5)(9) + 136657 [ 98439][E](PTData): Cleaned 290 readings + 136658 [ 98449][E](PTData): New entry recorded (5)(9)(1469) + 136659 [ 98451][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136660 [ 98462][E](PTData): Fit Valid: 1, N: 11, Quad: 1, Time: 1 ms + 136661 [ 98470][E](PTData): Fit Valid: 1, N: 11, Quad: 1, Time: 1 ms + 136662 [ 98472][E](PTable): New Entry Processed in 34 ms + 136663 [ 98472][E](PTable): Power Buffer Reset + 136664 [ 99018][E](FTMS_SERVER): 11 00 00 e3 02 28 33 -> Sim Mode Incline 7.390000. Responding: 80 11 01 + 136665 [ 99025][E](DirConManager): Sending response message type 0x04 to client 0 + 136666 [ 99924][E](FTMS_SERVER): 11 00 00 df 02 28 33 -> Sim Mode Incline 7.350000. Responding: 80 11 01 + 136667 [ 99929][E](DirConManager): Sending response message type 0x04 to client 0 + 136668 [100357][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 321, Cad 93, HR 135, Gear 8, Res 50, Current Pos 14745, Target Pos 14745 + 136669 [101671][E](FTMS_SERVER): 11 00 00 b1 02 28 33 -> Sim Mode Incline 6.890000. Responding: 80 11 01 + 136670 [101678][E](DirConManager): Sending response message type 0x04 to client 0 + 136671 [102621][E](FTMS_SERVER): 11 00 00 60 02 28 33 -> Sim Mode Incline 6.080000. Responding: 80 11 01 + 136672 [102628][E](DirConManager): Sending response message type 0x04 to client 0 + 136673 [103626][E](FTMS_SERVER): 11 00 00 01 02 28 33 -> Sim Mode Incline 5.130000. Responding: 80 11 01 + 136674 [103631][E](DirConManager): Sending response message type 0x04 to client 0 + 136675 [104529][E](FTMS_SERVER): 11 00 00 a4 01 28 33 -> Sim Mode Incline 4.200000. Responding: 80 11 01 + 136676 [104534][E](DirConManager): Sending response message type 0x04 to client 0 + 136677 [104789][E](PTable): Averaged Entry: watts=309.100006, cad=95.000000, targetPosition=1433.199951, (7)(10) + 136678 [104790][E](PTData): Cleaned 289 readings + 136679 [104800][E](PTData): New entry recorded (7)(10)(1433) + 136680 [104802][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136681 [104813][E](PTData): Fit Valid: 1, N: 12, Quad: 1, Time: 1 ms + 136682 [104821][E](PTData): Fit Valid: 1, N: 12, Quad: 1, Time: 1 ms + 136683 [104823][E](PTable): New Entry Processed in 35 ms + 136684 [104823][E](PTable): Power Buffer Reset + 136685 [105561][E](FTMS_SERVER): 11 00 00 40 01 28 33 -> Sim Mode Incline 3.200000. Responding: 80 11 01 + 136686 [105566][E](DirConManager): Sending response message type 0x04 to client 0 + 136687 [106367][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 266, Cad 99, HR 138, Gear 8, Res 41, Current Pos 11878, Target Pos 11840 + 136688 [106512][E](FTMS_SERVER): 11 00 00 cf 00 28 33 -> Sim Mode Incline 2.070000. Responding: 80 11 01 + 136689 [106519][E](DirConManager): Sending response message type 0x04 to client 0 + 136690 [107615][E](FTMS_SERVER): 11 00 00 58 00 28 33 -> Sim Mode Incline 0.880000. Responding: 80 11 01 + 136691 [107622][E](DirConManager): Sending response message type 0x04 to client 0 + 136692 [108536][E](FTMS_SERVER): 11 00 00 f7 ff 28 33 -> Sim Mode Incline -0.090000. Responding: 80 11 01 + 136693 [108543][E](DirConManager): Sending response message type 0x04 to client 0 + 136694 [109013][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 136695 [109013][E](PTable): Power Buffer Reset + 136696 [109443][E](FTMS_SERVER): 11 00 00 ce ff 28 33 -> Sim Mode Incline -0.500000. Responding: 80 11 01 + 136697 [109450][E](DirConManager): Sending response message type 0x04 to client 0 + 136698 [110468][E](FTMS_SERVER): 11 00 00 b1 ff 28 33 -> Sim Mode Incline -0.790000. Responding: 80 11 01 + 136699 [110475][E](DirConManager): Sending response message type 0x04 to client 0 + 136700 [111433][E](FTMS_SERVER): 11 00 00 a9 ff 28 33 -> Sim Mode Incline -0.870000. Responding: 80 11 01 + 136701 [111440][E](DirConManager): Sending response message type 0x04 to client 0 + 136702 [112382][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 62, Cad 104, HR 142, Gear 8, Res 30, Current Pos 8991, Target Pos 8991 + 136703 [112436][E](FTMS_SERVER): 11 00 00 bf ff 28 33 -> Sim Mode Incline -0.650000. Responding: 80 11 01 + 136704 [112441][E](DirConManager): Sending response message type 0x04 to client 0 + 136705 [113336][E](FTMS_SERVER): 11 00 00 ea ff 28 33 -> Sim Mode Incline -0.220000. Responding: 80 11 01 + 136706 [113343][E](DirConManager): Sending response message type 0x04 to client 0 + 136707 [114375][E](FTMS_SERVER): 11 00 00 4b 00 28 33 -> Sim Mode Incline 0.750000. Responding: 80 11 01 + 136708 [114382][E](DirConManager): Sending response message type 0x04 to client 0 + 136709 [115363][E](PTable): Using detected travel limits during homing + 136710 [115397][E](FTMS_SERVER): 11 00 00 d9 00 28 33 -> Sim Mode Incline 2.170000. Responding: 80 11 01 + 136711 [115403][E](DirConManager): Sending response message type 0x04 to client 0 + 136712 [116073][E](PTable): Averaged Entry: watts=107.699997, cad=103.500000, targetPosition=949.000000, (9)(4) + 136713 [116074][E](PTData): Cleaned 288 readings + 136714 [116084][E](PTData): New entry recorded (9)(4)(949) + 136715 [116086][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136716 [116098][E](PTData): Fit Valid: 1, N: 13, Quad: 1, Time: 2 ms + 136717 [116106][E](PTData): Fit Valid: 1, N: 13, Quad: 1, Time: 1 ms + 136718 [116107][E](PTable): New Entry Processed in 35 ms + 136719 [116108][E](PTable): Power Buffer Reset + 136720 [116323][E](FTMS_SERVER): 11 00 00 6b 01 28 33 -> Sim Mode Incline 3.630000. Responding: 80 11 01 + 136721 [116330][E](DirConManager): Sending response message type 0x04 to client 0 + 136722 [117236][E](FTMS_SERVER): 11 00 00 dc 01 28 33 -> Sim Mode Incline 4.760000. Responding: 80 11 01 + 136723 [117243][E](DirConManager): Sending response message type 0x04 to client 0 + 136724 [118163][E](FTMS_SERVER): 11 00 00 3b 02 28 33 -> Sim Mode Incline 5.710000. Responding: 80 11 01 + 136725 [118168][E](DirConManager): Sending response message type 0x04 to client 0 + 136726 [118391][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 90, Cad 102, HR 147, Gear 8, Res 43, Current Pos 12994, Target Pos 13597 + 136727 [119186][E](FTMS_SERVER): 11 00 00 88 02 28 33 -> Sim Mode Incline 6.480000. Responding: 80 11 01 + 136728 [119191][E](DirConManager): Sending response message type 0x04 to client 0 + 136729 [120218][E](FTMS_SERVER): 11 00 00 95 02 28 33 -> Sim Mode Incline 6.610000. Responding: 80 11 01 + 136730 [120223][E](DirConManager): Sending response message type 0x04 to client 0 + 136731 [120307][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 136732 [120307][E](PTable): Power Buffer Reset + 136733 [121241][E](FTMS_SERVER): 11 00 00 99 02 28 33 -> Sim Mode Incline 6.650000. Responding: 80 11 01 + 136734 [121246][E](DirConManager): Sending response message type 0x04 to client 0 + 136735 [122152][E](FTMS_SERVER): 11 00 00 98 02 28 33 -> Sim Mode Incline 6.640000. Responding: 80 11 01 + 136736 [122159][E](DirConManager): Sending response message type 0x04 to client 0 + 136737 [123882][E](FTMS_SERVER): 11 00 00 96 02 28 33 -> Sim Mode Incline 6.620000. Responding: 80 11 01 + 136738 [123887][E](DirConManager): Sending response message type 0x04 to client 0 + 136739 [124405][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 258, Cad 94, HR 147, Gear 8, Res 48, Current Pos 14234, Target Pos 14234 + 136740 [124926][E](FTMS_SERVER): 11 00 00 94 02 28 33 -> Sim Mode Incline 6.600000. Responding: 80 11 01 + 136741 [124930][E](DirConManager): Sending response message type 0x04 to client 0 + 136742 [126655][E](PTable): Averaged Entry: watts=257.399994, cad=94.500000, targetPosition=1423.000000, (7)(9) + 136743 [126656][E](PTData): Cleaned 287 readings + 136744 [126666][E](PTData): New entry recorded (7)(9)(1423) + 136745 [126667][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136746 [126679][E](PTData): Fit Valid: 1, N: 14, Quad: 1, Time: 1 ms + 136747 [126687][E](PTData): Fit Valid: 1, N: 14, Quad: 1, Time: 1 ms + 136748 [126689][E](PTable): New Entry Processed in 35 ms + 136749 [126689][E](PTable): Power Buffer Reset + 136750 [126703][E](FTMS_SERVER): 11 00 00 8f 02 28 33 -> Sim Mode Incline 6.550000. Responding: 80 11 01 + 136751 [126708][E](DirConManager): Sending response message type 0x04 to client 0 + 136752 [129121][E](FTMS_SERVER): 11 00 00 8c 02 28 33 -> Sim Mode Incline 6.520000. Responding: 80 11 01 + 136753 [129126][E](DirConManager): Sending response message type 0x04 to client 0 + 136754 [130416][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 245, Cad 89, HR 145, Gear 8, Res 48, Current Pos 14164, Target Pos 14164 + 136755 [131569][E](FTMS_SERVER): 11 00 00 8a 02 28 33 -> Sim Mode Incline 6.500000. Responding: 80 11 01 + 136756 [131576][E](DirConManager): Sending response message type 0x04 to client 0 + 136757 [132591][E](FTMS_SERVER): 11 00 00 88 02 28 33 -> Sim Mode Incline 6.480000. Responding: 80 11 01 + 136758 [132600][E](DirConManager): Sending response message type 0x04 to client 0 + 136759 [133008][E](PTable): Averaged Entry: watts=262.200012, cad=90.000000, targetPosition=1416.400024, (6)(9) + 136760 [133009][E](PTData): Cleaned 286 readings + 136761 [133020][E](PTData): New entry recorded (6)(9)(1416) + 136762 [133020][E](PTData): Greater Down Found 7, 9, tp1423 + 136763 [133032][E](PTData): Fit Valid: 1, N: 13, Quad: 1, Time: 2 ms + 136764 [133033][E](PTable): New Entry Processed in 25 ms + 136765 [133033][E](PTable): Power Buffer Reset + 136766 [133557][E](FTMS_SERVER): 11 00 00 87 02 28 33 -> Sim Mode Incline 6.470000. Responding: 80 11 01 + 136767 [133566][E](DirConManager): Sending response message type 0x04 to client 0 + 136768 [134554][E](FTMS_SERVER): 11 00 00 86 02 28 33 -> Sim Mode Incline 6.460000. Responding: 80 11 01 + 136769 [134561][E](DirConManager): Sending response message type 0x04 to client 0 + 136770 [135457][E](FTMS_SERVER): 11 00 00 87 02 28 33 -> Sim Mode Incline 6.470000. Responding: 80 11 01 + 136771 [135462][E](DirConManager): Sending response message type 0x04 to client 0 + 136772 [136431][E](FTMS_SERVER): 11 00 00 86 02 28 33 -> Sim Mode Incline 6.460000. Responding: 80 11 01 + 136773 [136436][E](DirConManager): Sending response message type 0x04 to client 0 + 136774 [136437][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 250, Cad 89, HR 144, Gear 8, Res 48, Current Pos 14129, Target Pos 14129 + 136775 [137514][E](FTMS_SERVER): 11 00 00 85 02 28 33 -> Sim Mode Incline 6.450000. Responding: 80 11 01 + 136776 [137520][E](DirConManager): Sending response message type 0x04 to client 0 + 136777 [138525][E](FTMS_SERVER): 11 00 00 82 02 28 33 -> Sim Mode Incline 6.420000. Responding: 80 11 01 + 136778 [138529][E](DirConManager): Sending response message type 0x04 to client 0 + 136779 [139350][E](PTable): Averaged Entry: watts=238.399994, cad=89.599998, targetPosition=1411.300049, (6)(8) + 136780 [139351][E](PTData): Cleaned 1 readings + 136781 [139361][E](PTData): New entry recorded (6)(8)(1411) + 136782 [139362][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136783 [139374][E](PTData): Fit Valid: 1, N: 14, Quad: 1, Time: 1 ms + 136784 [139382][E](PTData): Fit Valid: 1, N: 14, Quad: 1, Time: 1 ms + 136785 [139384][E](PTable): New Entry Processed in 34 ms + 136786 [139384][E](PTable): Power Buffer Reset + 136787 [139569][E](FTMS_SERVER): 11 00 00 86 02 28 33 -> Sim Mode Incline 6.460000. Responding: 80 11 01 + 136788 [139574][E](DirConManager): Sending response message type 0x04 to client 0 + 136789 [140490][E](FTMS_SERVER): 11 00 00 82 02 28 33 -> Sim Mode Incline 6.420000. Responding: 80 11 01 + 136790 [140500][E](DirConManager): Sending response message type 0x04 to client 0 + 136791 [141516][E](FTMS_SERVER): 11 00 00 80 02 28 33 -> Sim Mode Incline 6.400000. Responding: 80 11 01 + 136792 [141523][E](DirConManager): Sending response message type 0x04 to client 0 + 136793 [142458][E](FTMS_SERVER): 11 00 00 82 02 28 33 -> Sim Mode Incline 6.420000. Responding: 80 11 01 + 136794 [142466][E](DirConManager): Sending response message type 0x04 to client 0 + 136795 [142468][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 231, Cad 88, HR 145, Gear 8, Res 47, Current Pos 14080, Target Pos 14080 + 136796 [143464][E](FTMS_SERVER): 11 00 00 80 02 28 33 -> Sim Mode Incline 6.400000. Responding: 80 11 01 + 136797 [143471][E](DirConManager): Sending response message type 0x04 to client 0 + 136798 [144365][E](FTMS_SERVER): 11 00 00 7f 02 28 33 -> Sim Mode Incline 6.390000. Responding: 80 11 01 + 136799 [144370][E](DirConManager): Sending response message type 0x04 to client 0 + 136800 [145298][E](FTMS_SERVER): 11 00 00 80 02 28 33 -> Sim Mode Incline 6.400000. Responding: 80 11 01 + 136801 [145303][E](DirConManager): Sending response message type 0x04 to client 0 + 136802 [145706][E](PTable): Averaged Entry: watts=245.000000, cad=90.000000, targetPosition=1409.000000, (6)(8) + 136803 [145707][E](PTData): Cleaned 286 readings + 136804 [145717][E](PTData): Existing entry averaged (6)(8)(1410), readings(2) + 136805 [145718][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136806 [145730][E](PTData): Fit Valid: 1, N: 14, Quad: 1, Time: 1 ms + 136807 [145738][E](PTData): Fit Valid: 1, N: 14, Quad: 1, Time: 1 ms + 136808 [145740][E](PTable): New Entry Processed in 33 ms + 136809 [145740][E](PTable): Power Buffer Reset + 136810 [146325][E](FTMS_SERVER): 11 00 00 82 02 28 33 -> Sim Mode Incline 6.420000. Responding: 80 11 01 + 136811 [146332][E](DirConManager): Sending response message type 0x04 to client 0 + 136812 [147263][E](FTMS_SERVER): 11 00 00 7f 02 28 33 -> Sim Mode Incline 6.390000. Responding: 80 11 01 + 136813 [147270][E](DirConManager): Sending response message type 0x04 to client 0 + 136814 [148261][E](FTMS_SERVER): 11 00 00 7e 02 28 33 -> Sim Mode Incline 6.380000. Responding: 80 11 01 + 136815 [148268][E](DirConManager): Sending response message type 0x04 to client 0 + 136816 [148494][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 235, Cad 90, HR 147, Gear 8, Res 47, Current Pos 14066, Target Pos 14066 + 136817 [149176][E](FTMS_SERVER): 11 00 00 7c 02 28 33 -> Sim Mode Incline 6.360000. Responding: 80 11 01 + 136818 [149184][E](DirConManager): Sending response message type 0x04 to client 0 + 136819 [150923][E](FTMS_SERVER): 11 00 00 79 02 28 33 -> Sim Mode Incline 6.330000. Responding: 80 11 01 + 136820 [150930][E](DirConManager): Sending response message type 0x04 to client 0 + 136821 [151347][E](PTable): Using detected travel limits during homing + 136822 [151952][E](FTMS_SERVER): 11 00 00 80 02 28 33 -> Sim Mode Incline 6.400000. Responding: 80 11 01 + 136823 [151959][E](DirConManager): Sending response message type 0x04 to client 0 + 136824 [152052][E](PTable): Averaged Entry: watts=233.500000, cad=89.900002, targetPosition=1406.099976, (6)(8) + 136825 [152053][E](PTData): Cleaned 286 readings + 136826 [152063][E](PTData): Existing entry averaged (6)(8)(1409), readings(3) + 136827 [152064][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136828 [152076][E](PTData): Fit Valid: 1, N: 14, Quad: 1, Time: 1 ms + 136829 [152085][E](PTData): Fit Valid: 1, N: 14, Quad: 1, Time: 2 ms + 136830 [152086][E](PTable): New Entry Processed in 35 ms + 136831 [152086][E](PTable): Power Buffer Reset + 136832 [152877][E](FTMS_SERVER): 11 00 00 7e 02 28 33 -> Sim Mode Incline 6.380000. Responding: 80 11 01 + 136833 [152884][E](DirConManager): Sending response message type 0x04 to client 0 + 136834 [153783][E](FTMS_SERVER): 11 00 00 7f 02 28 33 -> Sim Mode Incline 6.390000. Responding: 80 11 01 + 136835 [153788][E](DirConManager): Sending response message type 0x04 to client 0 + 136836 [154511][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 224, Cad 86, HR 149, Gear 8, Res 47, Current Pos 14073, Target Pos 14073 + 136837 [155526][E](FTMS_SERVER): 11 00 00 7e 02 28 33 -> Sim Mode Incline 6.380000. Responding: 80 11 01 + 136838 [155533][E](DirConManager): Sending response message type 0x04 to client 0 + 136839 [156469][E](FTMS_SERVER): 11 00 00 7c 02 28 33 -> Sim Mode Incline 6.360000. Responding: 80 11 01 + 136840 [156477][E](DirConManager): Sending response message type 0x04 to client 0 + 136841 [157370][E](FTMS_SERVER): 11 00 00 7b 02 28 33 -> Sim Mode Incline 6.350000. Responding: 80 11 01 + 136842 [157375][E](DirConManager): Sending response message type 0x04 to client 0 + 136843 [158397][E](PTable): Averaged Entry: watts=224.800003, cad=86.599998, targetPosition=1406.099976, (5)(7) + 136844 [158398][E](PTData): Cleaned 286 readings + 136845 [158409][E](PTData): New entry recorded (5)(7)(1406) + 136846 [158410][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136847 [158422][E](PTData): Fit Valid: 1, N: 15, Quad: 1, Time: 2 ms + 136848 [158430][E](PTData): Fit Valid: 1, N: 15, Quad: 1, Time: 1 ms + 136849 [158431][E](PTable): New Entry Processed in 34 ms + 136850 [158431][E](PTable): Power Buffer Reset + 136851 [159107][E](FTMS_SERVER): 11 00 00 7d 02 28 33 -> Sim Mode Incline 6.370000. Responding: 80 11 01 + 136852 [159115][E](DirConManager): Sending response message type 0x04 to client 0 + 136853 [160071][E](FTMS_SERVER): 11 00 00 81 02 28 33 -> Sim Mode Incline 6.410000. Responding: 80 11 01 + 136854 [160076][E](DirConManager): Sending response message type 0x04 to client 0 + 136855 [160528][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 226, Cad 87, HR 149, Gear 8, Res 47, Current Pos 14087, Target Pos 14087 + 136856 [161076][E](FTMS_SERVER): 11 00 00 7b 02 28 33 -> Sim Mode Incline 6.350000. Responding: 80 11 01 + 136857 [161081][E](DirConManager): Sending response message type 0x04 to client 0 + 136858 [162089][E](FTMS_SERVER): 11 00 00 7c 02 28 33 -> Sim Mode Incline 6.360000. Responding: 80 11 01 + 136859 [162094][E](DirConManager): Sending response message type 0x04 to client 0 + 136860 [163013][E](FTMS_SERVER): 11 00 00 7f 02 28 33 -> Sim Mode Incline 6.390000. Responding: 80 11 01 + 136861 [163021][E](DirConManager): Sending response message type 0x04 to client 0 + 136862 [164742][E](PTable): Averaged Entry: watts=228.100006, cad=87.500000, targetPosition=1405.599976, (5)(8) + 136863 [164743][E](PTData): Cleaned 285 readings + 136864 [164753][E](PTData): Existing entry averaged (5)(8)(1448), readings(6) + 136865 [164754][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136866 [164766][E](PTData): Fit Valid: 1, N: 15, Quad: 1, Time: 1 ms + 136867 [164774][E](PTData): Fit Valid: 1, N: 15, Quad: 1, Time: 1 ms + 136868 [164779][E](PTable): New Entry Processed in 37 ms + 136869 [164779][E](PTable): Power Buffer Reset + 136870 [164794][E](FTMS_SERVER): 11 00 00 7b 02 28 33 -> Sim Mode Incline 6.350000. Responding: 80 11 01 + 136871 [164799][E](DirConManager): Sending response message type 0x04 to client 0 + 136872 [165780][E](FTMS_SERVER): 11 00 00 7d 02 28 33 -> Sim Mode Incline 6.370000. Responding: 80 11 01 + 136873 [165785][E](DirConManager): Sending response message type 0x04 to client 0 + 136874 [166538][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 227, Cad 88, HR 149, Gear 8, Res 47, Current Pos 14059, Target Pos 14059 + 136875 [166682][E](FTMS_SERVER): 11 00 00 7f 02 28 33 -> Sim Mode Incline 6.390000. Responding: 80 11 01 + 136876 [166690][E](DirConManager): Sending response message type 0x04 to client 0 + 136877 [167724][E](FTMS_SERVER): 11 00 00 80 02 28 33 -> Sim Mode Incline 6.400000. Responding: 80 11 01 + 136878 [167731][E](DirConManager): Sending response message type 0x04 to client 0 + 136879 [169454][E](FTMS_SERVER): 11 00 00 7f 02 28 33 -> Sim Mode Incline 6.390000. Responding: 80 11 01 + 136880 [169459][E](DirConManager): Sending response message type 0x04 to client 0 + 136881 [170484][E](FTMS_SERVER): 11 00 00 81 02 28 33 -> Sim Mode Incline 6.410000. Responding: 80 11 01 + 136882 [170490][E](DirConManager): Sending response message type 0x04 to client 0 + 136883 [171100][E](PTable): Averaged Entry: watts=224.600006, cad=87.199997, targetPosition=1406.500000, (5)(7) + 136884 [171101][E](PTData): Cleaned 285 readings + 136885 [171111][E](PTData): Existing entry averaged (5)(7)(1406), readings(2) + 136886 [171113][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136887 [171124][E](PTData): Fit Valid: 1, N: 15, Quad: 1, Time: 1 ms + 136888 [171133][E](PTData): Fit Valid: 1, N: 15, Quad: 1, Time: 1 ms + 136889 [171134][E](PTable): New Entry Processed in 34 ms + 136890 [171134][E](PTable): Power Buffer Reset + 136891 [171410][E](FTMS_SERVER): 11 00 00 83 02 28 33 -> Sim Mode Incline 6.430000. Responding: 80 11 01 + 136892 [171416][E](DirConManager): Sending response message type 0x04 to client 0 + 136893 [172424][E](FTMS_SERVER): 11 00 00 82 02 28 33 -> Sim Mode Incline 6.420000. Responding: 80 11 01 + 136894 [172431][E](DirConManager): Sending response message type 0x04 to client 0 + 136895 [172550][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 232, Cad 87, HR 149, Gear 8, Res 48, Current Pos 14094, Target Pos 14094 + 136896 [173381][E](FTMS_SERVER): 11 00 00 81 02 28 33 -> Sim Mode Incline 6.410000. Responding: 80 11 01 + 136897 [173389][E](DirConManager): Sending response message type 0x04 to client 0 + 136898 [174384][E](FTMS_SERVER): 11 00 00 80 02 28 33 -> Sim Mode Incline 6.400000. Responding: 80 11 01 + 136899 [174391][E](DirConManager): Sending response message type 0x04 to client 0 + 136900 [175286][E](FTMS_SERVER): 11 00 00 85 02 28 33 -> Sim Mode Incline 6.450000. Responding: 80 11 01 + 136901 [175291][E](DirConManager): Sending response message type 0x04 to client 0 + 136902 [176210][E](FTMS_SERVER): 11 00 00 84 02 28 33 -> Sim Mode Incline 6.440000. Responding: 80 11 01 + 136903 [176214][E](DirConManager): Sending response message type 0x04 to client 0 + 136904 [177251][E](FTMS_SERVER): 11 00 00 88 02 28 33 -> Sim Mode Incline 6.480000. Responding: 80 11 01 + 136905 [177256][E](DirConManager): Sending response message type 0x04 to client 0 + 136906 [177461][E](PTable): Averaged Entry: watts=229.800003, cad=86.900002, targetPosition=1409.599976, (5)(8) + 136907 [177462][E](PTData): Cleaned 285 readings + 136908 [177472][E](PTData): Existing entry averaged (5)(8)(1443), readings(7) + 136909 [177474][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136910 [177485][E](PTData): Fit Valid: 1, N: 15, Quad: 1, Time: 1 ms + 136911 [177494][E](PTData): Fit Valid: 1, N: 15, Quad: 1, Time: 1 ms + 136912 [177495][E](PTable): New Entry Processed in 34 ms + 136913 [177495][E](PTable): Power Buffer Reset + 136914 [178265][E](FTMS_SERVER): 11 00 00 87 02 28 33 -> Sim Mode Incline 6.470000. Responding: 80 11 01 + 136915 [178272][E](DirConManager): Sending response message type 0x04 to client 0 + 136916 [178567][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 232, Cad 88, HR 151, Gear 8, Res 48, Current Pos 14129, Target Pos 14129 + 136917 [179198][E](FTMS_SERVER): 11 00 00 89 02 28 33 -> Sim Mode Incline 6.490000. Responding: 80 11 01 + 136918 [179205][E](DirConManager): Sending response message type 0x04 to client 0 + 136919 [180100][E](FTMS_SERVER): 11 00 00 8a 02 28 33 -> Sim Mode Incline 6.500000. Responding: 80 11 01 + 136920 [180107][E](DirConManager): Sending response message type 0x04 to client 0 + 136921 [181022][E](FTMS_SERVER): 11 00 00 8c 02 28 33 -> Sim Mode Incline 6.520000. Responding: 80 11 01 + 136922 [181027][E](DirConManager): Sending response message type 0x04 to client 0 + 136923 [182045][E](FTMS_SERVER): 11 00 00 94 02 28 33 -> Sim Mode Incline 6.600000. Responding: 80 11 01 + 136924 [182050][E](DirConManager): Sending response message type 0x04 to client 0 + 136925 [183006][E](FTMS_SERVER): 11 00 00 93 02 28 33 -> Sim Mode Incline 6.590000. Responding: 80 11 01 + 136926 [183012][E](DirConManager): Sending response message type 0x04 to client 0 + 136927 [183814][E](PTable): Averaged Entry: watts=228.100006, cad=87.500000, targetPosition=1416.199951, (5)(8) + 136928 [183815][E](PTData): Cleaned 285 readings + 136929 [183825][E](PTData): Existing entry averaged (5)(8)(1440), readings(8) + 136930 [183827][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136931 [183838][E](PTData): Fit Valid: 1, N: 15, Quad: 1, Time: 1 ms + 136932 [183847][E](PTData): Fit Valid: 1, N: 15, Quad: 1, Time: 2 ms + 136933 [183848][E](PTable): New Entry Processed in 34 ms + 136934 [183848][E](PTable): Power Buffer Reset + 136935 [183903][E](FTMS_SERVER): 11 00 00 9c 02 28 33 -> Sim Mode Incline 6.680000. Responding: 80 11 01 + 136936 [183910][E](DirConManager): Sending response message type 0x04 to client 0 + 136937 [184579][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 225, Cad 87, HR 152, Gear 8, Res 48, Current Pos 14276, Target Pos 14276 + 136938 [184817][E](FTMS_SERVER): 11 00 00 a5 02 28 33 -> Sim Mode Incline 6.770000. Responding: 80 11 01 + 136939 [184824][E](DirConManager): Sending response message type 0x04 to client 0 + 136940 [185743][E](FTMS_SERVER): 11 00 00 91 02 28 33 -> Sim Mode Incline 6.570000. Responding: 80 11 01 + 136941 [185750][E](DirConManager): Sending response message type 0x04 to client 0 + 136942 [186706][E](FTMS_SERVER): 11 00 00 8a 02 28 33 -> Sim Mode Incline 6.500000. Responding: 80 11 01 + 136943 [186711][E](DirConManager): Sending response message type 0x04 to client 0 + 136944 [187351][E](PTable): Using detected travel limits during homing + 136945 [187701][E](FTMS_SERVER): 11 00 00 81 02 28 33 -> Sim Mode Incline 6.410000. Responding: 80 11 01 + 136946 [187707][E](DirConManager): Sending response message type 0x04 to client 0 + 136947 [188720][E](FTMS_SERVER): 11 00 00 7a 02 28 33 -> Sim Mode Incline 6.340000. Responding: 80 11 01 + 136948 [188727][E](DirConManager): Sending response message type 0x04 to client 0 + 136949 [189630][E](FTMS_SERVER): 11 00 00 6c 02 28 33 -> Sim Mode Incline 6.200000. Responding: 80 11 01 + 136950 [189637][E](DirConManager): Sending response message type 0x04 to client 0 + 136951 [190175][E](PTable): Averaged Entry: watts=238.100006, cad=87.300003, targetPosition=1416.199951, (5)(8) + 136952 [190176][E](PTData): Cleaned 285 readings + 136953 [190186][E](PTData): Existing entry averaged (5)(8)(1437), readings(9) + 136954 [190187][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136955 [190199][E](PTData): Fit Valid: 1, N: 15, Quad: 1, Time: 1 ms + 136956 [190207][E](PTData): Fit Valid: 1, N: 15, Quad: 1, Time: 1 ms + 136957 [190209][E](PTable): New Entry Processed in 34 ms + 136958 [190209][E](PTable): Power Buffer Reset + 136959 [190590][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 238, Cad 89, HR 152, Gear 8, Res 47, Current Pos 13940, Target Pos 13940 + 136960 [190654][E](FTMS_SERVER): 11 00 00 5a 02 28 33 -> Sim Mode Incline 6.020000. Responding: 80 11 01 + 136961 [190661][E](DirConManager): Sending response message type 0x04 to client 0 + 136962 [191617][E](FTMS_SERVER): 11 00 00 24 02 28 33 -> Sim Mode Incline 5.480000. Responding: 80 11 01 + 136963 [191624][E](DirConManager): Sending response message type 0x04 to client 0 + 136964 [192599][E](FTMS_SERVER): 11 00 00 6b 01 28 33 -> Sim Mode Incline 3.630000. Responding: 80 11 01 + 136965 [192607][E](DirConManager): Sending response message type 0x04 to client 0 + 136966 [193524][E](FTMS_SERVER): 11 00 00 4f 00 28 33 -> Sim Mode Incline 0.790000. Responding: 80 11 01 + 136967 [193529][E](DirConManager): Sending response message type 0x04 to client 0 + 136968 [194410][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 136969 [194410][E](PTable): Power Buffer Reset + 136970 [194558][E](FTMS_SERVER): 11 00 00 dc ff 28 33 -> Sim Mode Incline -0.360000. Responding: 80 11 01 + 136971 [194563][E](DirConManager): Sending response message type 0x04 to client 0 + 136972 [195567][E](FTMS_SERVER): 11 00 00 ca ff 28 33 -> Sim Mode Incline -0.540000. Responding: 80 11 01 + 136973 [195572][E](DirConManager): Sending response message type 0x04 to client 0 + 136974 [196518][E](FTMS_SERVER): 11 00 00 d6 ff 28 33 -> Sim Mode Incline -0.420000. Responding: 80 11 01 + 136975 [196525][E](DirConManager): Sending response message type 0x04 to client 0 + 136976 [196606][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 100, Cad 98, HR 152, Gear 8, Res 31, Current Pos 9233, Target Pos 9306 + 136977 [197650][E](FTMS_SERVER): 11 00 00 f6 ff 28 33 -> Sim Mode Incline -0.100000. Responding: 80 11 01 + 136978 [197655][E](DirConManager): Sending response message type 0x04 to client 0 + 136979 [198535][E](FTMS_SERVER): 11 00 00 31 00 28 33 -> Sim Mode Incline 0.490000. Responding: 80 11 01 + 136980 [198542][E](DirConManager): Sending response message type 0x04 to client 0 + 136981 [199559][E](FTMS_SERVER): 11 00 00 81 00 28 33 -> Sim Mode Incline 1.290000. Responding: 80 11 01 + 136982 [199566][E](DirConManager): Sending response message type 0x04 to client 0 + 136983 [200521][E](FTMS_SERVER): 11 00 00 de 00 28 33 -> Sim Mode Incline 2.220000. Responding: 80 11 01 + 136984 [200527][E](DirConManager): Sending response message type 0x04 to client 0 + 136985 [200785][E](PTable): Averaged Entry: watts=130.600006, cad=95.000000, targetPosition=967.599976, (7)(4) + 136986 [200787][E](PTData): Cleaned 285 readings + 136987 [200798][E](PTData): New entry recorded (7)(4)(967) + 136988 [200799][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 136989 [200811][E](PTData): Fit Valid: 1, N: 16, Quad: 1, Time: 2 ms + 136990 [200819][E](PTData): Fit Valid: 1, N: 16, Quad: 1, Time: 1 ms + 136991 [200821][E](PTable): New Entry Processed in 36 ms + 136992 [200821][E](PTable): Power Buffer Reset + 136993 [201016][E](FTMS_SERVER): 05 91 00 -> ERG Mode Target: 145 Current: 68 Incline: 2.220000. Responding: 80 05 01 + 136994 [201024][E](DirConManager): Sending response message type 0x04 to client 0 + 136995 [201491][E](ERG_Mode): Table Result Failed increasing Test: 9940 + 136996 [201492][E](ERG_Mode): Lookup Error. Using PID + 136997 [201492][E](ERG_Mode): Proportional: 231.000000 + 136998 [202619][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 108, Cad 96, HR 151, Gear 8, Res 38, Current Pos 11461, Target Pos 11461 + 136999 [203607][E](ERG_Mode): Watts previously processed. + 137000 [205732][E](ERG_Mode): Watts previously processed. + 137001 [207147][E](PTable): Averaged Entry: watts=109.900002, cad=95.500000, targetPosition=1146.800049, (7)(4) + 137002 [207148][E](PTData): Cleaned 284 readings + 137003 [207158][E](PTData): Existing entry averaged (7)(4)(1026), readings(2) + 137004 [207160][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137005 [207171][E](PTData): Fit Valid: 1, N: 16, Quad: 1, Time: 1 ms + 137006 [207180][E](PTData): Fit Valid: 1, N: 16, Quad: 1, Time: 2 ms + 137007 [207181][E](PTable): New Entry Processed in 34 ms + 137008 [207181][E](PTable): Power Buffer Reset + 137009 [207192][E](ERG_Mode): Proportional: 47.250000 + 137010 [208558][E](ERG_Mode): Watts previously processed. + 137011 [208632][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 122, Cad 93, HR 148, Gear 8, Res 39, Current Pos 11735, Target Pos 11735 + 137012 [210678][E](ERG_Mode): Watts previously processed. + 137013 [212787][E](ERG_Mode): Watts previously processed. + 137014 [213488][E](PTable): Averaged Entry: watts=121.800003, cad=91.599998, targetPosition=1180.099976, (6)(4) + 137015 [213489][E](PTData): Cleaned 284 readings + 137016 [213499][E](PTData): New entry recorded (6)(4)(1180) + 137017 [213500][E](PTData): Lower Up Found 4, 4, tp1140 + 137018 [213501][E](PTData): Fit Valid: 1, N: 15, Quad: 1, Time: 1 ms + 137019 [213513][E](PTable): New Entry Processed in 26 ms + 137020 [213513][E](PTable): Power Buffer Reset + 137021 [213513][E](ERG_Mode): Proportional: 45.000000 + 137022 [214641][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 119, Cad 87, HR 146, Gear 8, Res 41, Current Pos 12048, Target Pos 12048 + 137023 [215621][E](ERG_Mode): Watts previously processed. + 137024 [218444][E](ERG_Mode): Watts previously processed. + 137025 [219146][E](ERG_Mode): Proportional: -153.000000 + 137026 [219854][E](PTable): Averaged Entry: watts=135.000000, cad=86.800003, targetPosition=1208.699951, (5)(5) + 137027 [219855][E](PTData): Cleaned 1 readings + 137028 [219865][E](PTData): New entry recorded (5)(5)(1208) + 137029 [219867][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137030 [219878][E](PTData): Fit Valid: 1, N: 16, Quad: 1, Time: 1 ms + 137031 [219887][E](PTData): Fit Valid: 1, N: 16, Quad: 1, Time: 2 ms + 137032 [219888][E](PTable): New Entry Processed in 35 ms + 137033 [219888][E](PTable): Power Buffer Reset + 137034 [220561][E](ERG_Mode): Watts previously processed. + 137035 [220658][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 138, Cad 90, HR 145, Gear 8, Res 40, Current Pos 12023, Target Pos 12023 + 137036 [222674][E](ERG_Mode): Watts previously processed. + 137037 [223382][E](PTable): Using detected travel limits during homing + 137038 [224795][E](ERG_Mode): Watts previously processed. + 137039 [225500][E](ERG_Mode): Proportional: -69.750000 + 137040 [226210][E](PTable): Averaged Entry: watts=146.100006, cad=90.000000, targetPosition=1201.800049, (6)(5) + 137041 [226211][E](PTData): Cleaned 284 readings + 137042 [226221][E](PTData): New entry recorded (6)(5)(1201) + 137043 [226222][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137044 [226234][E](PTData): Fit Valid: 1, N: 17, Quad: 1, Time: 1 ms + 137045 [226243][E](PTData): Fit Valid: 1, N: 17, Quad: 1, Time: 2 ms + 137046 [226244][E](PTable): New Entry Processed in 34 ms + 137047 [226244][E](PTable): Power Buffer Reset + 137048 [226675][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 137, Cad 92, HR 142, Gear 8, Res 40, Current Pos 11976, Target Pos 11976 + 137049 [226917][E](ERG_Mode): Watts previously processed. + 137050 [229740][E](ERG_Mode): Watts previously processed. + 137051 [231155][E](ERG_Mode): Proportional: 42.750000 + 137052 [232569][E](PTable): Averaged Entry: watts=132.600006, cad=88.599998, targetPosition=1203.599976, (6)(4) + 137053 [232570][E](PTData): Cleaned 283 readings + 137054 [232580][E](PTData): New entry recorded (6)(4)(1203) + 137055 [232580][E](PTData): Lower Right Found 6, 5, tp1201 + 137056 [232582][E](PTData): Fit Valid: 1, N: 16, Quad: 1, Time: 1 ms + 137057 [232594][E](PTable): New Entry Processed in 26 ms + 137058 [232594][E](PTable): Power Buffer Reset + 137059 [232595][E](ERG_Mode): Watts previously processed. + 137060 [232705][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 129, Cad 86, HR 139, Gear 8, Res 41, Current Pos 12153, Target Pos 12153 + 137061 [234683][E](ERG_Mode): Watts previously processed. + 137062 [236801][E](ERG_Mode): Watts previously processed. + 137063 [237508][E](ERG_Mode): Proportional: 42.750000 + 137064 [238720][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 131, Cad 82, HR 137, Gear 8, Res 42, Current Pos 12394, Target Pos 12394 + 137065 [238911][E](PTable): Averaged Entry: watts=127.300003, cad=83.900002, targetPosition=1226.000000, (5)(4) + 137066 [238912][E](PTData): Cleaned 1 readings + 137067 [238922][E](PTData): New entry recorded (5)(4)(1226) + 137068 [238922][E](PTData): Lower Right Found 5, 5, tp1208 + 137069 [238924][E](PTData): Fit Valid: 1, N: 15, Quad: 1, Time: 1 ms + 137070 [238935][E](PTable): New Entry Processed in 24 ms + 137071 [238936][E](PTable): Power Buffer Reset + 137072 [238936][E](ERG_Mode): Watts previously processed. + 137073 [241020][E](ERG_Mode): Watts previously processed. + 137074 [243137][E](ERG_Mode): Proportional: 6.000000 + 137075 [244553][E](ERG_Mode): Watts previously processed. + 137076 [244729][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 136, Cad 83, HR 135, Gear 8, Res 42, Current Pos 12462, Target Pos 12462 + 137077 [245256][E](PTable): Averaged Entry: watts=137.699997, cad=82.599998, targetPosition=1243.800049, (4)(5) + 137078 [245258][E](PTData): Cleaned 1 readings + 137079 [245268][E](PTData): New entry recorded (4)(5)(1243) + 137080 [245270][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137081 [245281][E](PTData): Fit Valid: 1, N: 16, Quad: 1, Time: 1 ms + 137082 [245290][E](PTData): Fit Valid: 1, N: 16, Quad: 1, Time: 2 ms + 137083 [245291][E](PTable): New Entry Processed in 35 ms + 137084 [245380][E](PTable): Writing File: /PowerTable.txt + 137085 [245622][E](PTable): Power table saved successfully with 331 readings + 137086 [245623][E](PTable): Power Buffer Reset + 137087 [246670][E](ERG_Mode): Watts previously processed. + 137088 [248788][E](ERG_Mode): Watts previously processed. + 137089 [249498][E](ERG_Mode): Proportional: 4.500000 + 137090 [250743][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 141, Cad 83, HR 134, Gear 8, Res 42, Current Pos 12482, Target Pos 12482 + 137091 [250905][E](ERG_Mode): Watts previously processed. + 137092 [251613][E](PTable): Averaged Entry: watts=140.500000, cad=83.000000, targetPosition=1247.000000, (5)(5) + 137093 [251614][E](PTData): Cleaned 284 readings + 137094 [251625][E](PTData): New entry recorded (5)(5)(1247) + 137095 [251625][E](PTData): Lower Up Found 4, 5, tp1243 + 137096 [251626][E](PTData): Fit Valid: 1, N: 15, Quad: 1, Time: 1 ms + 137097 [251638][E](PTable): New Entry Processed in 25 ms + 137098 [251638][E](PTable): Power Buffer Reset + 137099 [254433][E](ERG_Mode): Watts previously processed. + 137100 [255141][E](ERG_Mode): Proportional: 6.000000 + 137101 [256547][E](ERG_Mode): Watts previously processed. + 137102 [256762][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 150, Cad 83, HR 132, Gear 8, Res 42, Current Pos 12548, Target Pos 12548 + 137103 [257956][E](PTable): Averaged Entry: watts=139.300003, cad=82.699997, targetPosition=1252.800049, (4)(5) + 137104 [257957][E](PTData): Cleaned 1 readings + 137105 [257967][E](PTData): New entry recorded (4)(5)(1252) + 137106 [257968][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137107 [257980][E](PTData): Fit Valid: 1, N: 16, Quad: 1, Time: 1 ms + 137108 [257989][E](PTData): Fit Valid: 1, N: 16, Quad: 1, Time: 2 ms + 137109 [257990][E](PTable): New Entry Processed in 34 ms + 137110 [257990][E](PTable): Power Buffer Reset + 137111 [258664][E](ERG_Mode): Watts previously processed. + 137112 [258978][E](FTMS_SERVER): 05 f5 00 -> ERG Mode Target: 245 Current: 144 Incline: 125.459999. Responding: 80 05 01 + 137113 [258985][E](DirConManager): Sending response message type 0x04 to client 0 + 137114 [259374][E](ERG_Mode): SetPoint changed:215w Waiting:1115ms PowerTable Result: 14000 + 137115 [259374][E](PTable): Using detected travel limits during homing + 137116 [261892][E](ERG_Mode): ERG wait expired, pos: 14000, tgt: 0 + 137117 [261893][E](ERG_Mode): Proportional: 382.500000 + 137118 [262775][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 150, Cad 83, HR 129, Gear 8, Res 48, Current Pos 14429, Target Pos 14667 + 137119 [264008][E](ERG_Mode): Watts previously processed. + 137120 [266126][E](PTable): Averaged Entry: watts=201.399994, cad=86.300003, targetPosition=1392.099976, (5)(7) + 137121 [266127][E](PTData): Cleaned 284 readings + 137122 [266137][E](PTData): Existing entry averaged (5)(7)(1402), readings(3) + 137123 [266138][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137124 [266150][E](PTData): Fit Valid: 1, N: 16, Quad: 1, Time: 1 ms + 137125 [266158][E](PTData): Fit Valid: 1, N: 16, Quad: 1, Time: 1 ms + 137126 [266160][E](PTable): New Entry Processed in 35 ms + 137127 [266160][E](PTable): Power Buffer Reset + 137128 [267541][E](ERG_Mode): Watts previously processed. + 137129 [268248][E](ERG_Mode): Proportional: -81.000000 + 137130 [268785][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 281, Cad 92, HR 129, Gear 8, Res 49, Current Pos 14332, Target Pos 14332 + 137131 [269657][E](ERG_Mode): Watts previously processed. + 137132 [271775][E](ERG_Mode): Watts previously processed. + 137133 [272475][E](PTable): Averaged Entry: watts=277.299988, cad=93.500000, targetPosition=1429.599976, (7)(9) + 137134 [272477][E](PTData): Cleaned 284 readings + 137135 [272487][E](PTData): New entry recorded (7)(9)(1429) + 137136 [272488][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137137 [272500][E](PTData): Fit Valid: 1, N: 17, Quad: 1, Time: 2 ms + 137138 [272508][E](PTData): Fit Valid: 1, N: 17, Quad: 1, Time: 1 ms + 137139 [272510][E](PTable): New Entry Processed in 35 ms + 137140 [272510][E](PTable): Power Buffer Reset + 137141 [273889][E](ERG_Mode): Watts previously processed. + 137142 [274599][E](ERG_Mode): Proportional: -54.000000 + 137143 [274803][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 269, Cad 95, HR 132, Gear 8, Res 47, Current Pos 13955, Target Pos 13950 + 137144 [276715][E](ERG_Mode): Watts previously processed. + 137145 [278835][E](PTable): Averaged Entry: watts=262.200012, cad=94.800003, targetPosition=1392.900024, (7)(9) + 137146 [278836][E](PTData): Cleaned 283 readings + 137147 [278846][E](PTData): Existing entry averaged (7)(9)(1416), readings(2) + 137148 [278847][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137149 [278859][E](PTData): Fit Valid: 1, N: 17, Quad: 1, Time: 1 ms + 137150 [278868][E](PTData): Fit Valid: 1, N: 17, Quad: 1, Time: 2 ms + 137151 [278869][E](PTable): New Entry Processed in 34 ms + 137152 [278869][E](PTable): Power Buffer Reset + 137153 [279540][E](ERG_Mode): Watts previously processed. + 137154 [280248][E](ERG_Mode): Proportional: -24.750000 + 137155 [280815][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 256, Cad 95, HR 134, Gear 8, Res 47, Current Pos 13792, Target Pos 13792 + 137156 [281655][E](ERG_Mode): Watts previously processed. + 137157 [283773][E](ERG_Mode): Watts previously processed. + 137158 [285184][E](PTable): Averaged Entry: watts=252.399994, cad=94.900002, targetPosition=1376.599976, (7)(8) + 137159 [285185][E](PTData): Cleaned 283 readings + 137160 [285195][E](PTData): New entry recorded (7)(8)(1376) + 137161 [285196][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137162 [285208][E](PTData): Fit Valid: 1, N: 18, Quad: 1, Time: 1 ms + 137163 [285217][E](PTData): Fit Valid: 1, N: 18, Quad: 1, Time: 2 ms + 137164 [285218][E](PTable): New Entry Processed in 34 ms + 137165 [285218][E](PTable): Power Buffer Reset + 137166 [285889][E](ERG_Mode): Watts previously processed. + 137167 [286599][E](ERG_Mode): Proportional: 0.750000 + 137168 [286824][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 244, Cad 95, HR 138, Gear 8, Res 46, Current Pos 13728, Target Pos 13728 + 137169 [289415][E](ERG_Mode): Watts previously processed. + 137170 [291533][E](PTable): Averaged Entry: watts=244.000000, cad=94.500000, targetPosition=1372.599976, (7)(8) + 137171 [291534][E](PTData): Cleaned 282 readings + 137172 [291544][E](PTData): Existing entry averaged (7)(8)(1374), readings(2) + 137173 [291545][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137174 [291558][E](PTData): Fit Valid: 1, N: 18, Quad: 1, Time: 2 ms + 137175 [291566][E](PTData): Fit Valid: 1, N: 18, Quad: 1, Time: 1 ms + 137176 [291567][E](PTable): New Entry Processed in 35 ms + 137177 [291568][E](PTable): Power Buffer Reset + 137178 [291578][E](ERG_Mode): Watts previously processed. + 137179 [292242][E](ERG_Mode): Proportional: -3.750000 + 137180 [292840][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 250, Cad 95, HR 140, Gear 8, Res 46, Current Pos 13730, Target Pos 13730 + 137181 [293652][E](ERG_Mode): Watts previously processed. + 137182 [295768][E](ERG_Mode): Watts previously processed. + 137183 [297177][E](PTable): Using detected travel limits during homing + 137184 [297883][E](PTable): Averaged Entry: watts=252.000000, cad=95.699997, targetPosition=1371.400024, (7)(8) + 137185 [297884][E](PTData): Cleaned 282 readings + 137186 [297894][E](PTData): Existing entry averaged (7)(8)(1373), readings(3) + 137187 [297896][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137188 [297908][E](PTData): Fit Valid: 1, N: 18, Quad: 1, Time: 2 ms + 137189 [297916][E](PTData): Fit Valid: 1, N: 18, Quad: 1, Time: 1 ms + 137190 [297917][E](PTable): New Entry Processed in 35 ms + 137191 [297918][E](PTable): Power Buffer Reset + 137192 [297928][E](ERG_Mode): Watts previously processed. + 137193 [298591][E](ERG_Mode): Proportional: -6.750000 + 137194 [298858][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 254, Cad 98, HR 142, Gear 8, Res 46, Current Pos 13646, Target Pos 13646 + 137195 [299997][E](ERG_Mode): Watts previously processed. + 137196 [301421][E](ERG_Mode): Watts previously processed. + 137197 [303545][E](ERG_Mode): Watts previously processed. + 137198 [304253][E](PTable): Averaged Entry: watts=242.800003, cad=95.900002, targetPosition=1364.900024, (7)(8) + 137199 [304254][E](PTData): Cleaned 282 readings + 137200 [304264][E](PTData): Existing entry averaged (7)(8)(1371), readings(4) + 137201 [304266][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137202 [304277][E](PTData): Fit Valid: 1, N: 18, Quad: 1, Time: 1 ms + 137203 [304286][E](PTData): Fit Valid: 1, N: 18, Quad: 1, Time: 2 ms + 137204 [304287][E](PTable): New Entry Processed in 34 ms + 137205 [304287][E](PTable): Power Buffer Reset + 137206 [304298][E](ERG_Mode): Proportional: 4.500000 + 137207 [304870][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 239, Cad 94, HR 145, Gear 8, Res 46, Current Pos 13679, Target Pos 13679 + 137208 [305659][E](ERG_Mode): Watts previously processed. + 137209 [307784][E](ERG_Mode): Watts previously processed. + 137210 [309894][E](ERG_Mode): Watts previously processed. + 137211 [310601][E](PTable): Averaged Entry: watts=243.899994, cad=94.099998, targetPosition=1368.599976, (7)(8) + 137212 [310602][E](PTData): Cleaned 282 readings + 137213 [310612][E](PTData): Existing entry averaged (7)(8)(1370), readings(5) + 137214 [310613][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137215 [310625][E](PTData): Fit Valid: 1, N: 18, Quad: 1, Time: 1 ms + 137216 [310634][E](PTData): Fit Valid: 1, N: 18, Quad: 1, Time: 1 ms + 137217 [310635][E](PTable): New Entry Processed in 34 ms + 137218 [310635][E](PTable): Power Buffer Reset + 137219 [310646][E](ERG_Mode): Proportional: -4.500000 + 137220 [310881][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 244, Cad 95, HR 146, Gear 8, Res 46, Current Pos 13702, Target Pos 13702 + 137221 [312718][E](ERG_Mode): Watts previously processed. + 137222 [314831][E](ERG_Mode): Watts previously processed. + 137223 [316236][E](ERG_Mode): Proportional: -6.000000 + 137224 [316892][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 253, Cad 96, HR 148, Gear 8, Res 46, Current Pos 13729, Target Pos 13729 + 137225 [316957][E](PTable): Averaged Entry: watts=240.699997, cad=94.599998, targetPosition=1371.800049, (7)(8) + 137226 [316959][E](PTData): Cleaned 282 readings + 137227 [316969][E](PTData): Existing entry averaged (7)(8)(1370), readings(6) + 137228 [316970][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137229 [316982][E](PTData): Fit Valid: 1, N: 18, Quad: 1, Time: 1 ms + 137230 [316991][E](PTData): Fit Valid: 1, N: 18, Quad: 1, Time: 1 ms + 137231 [316992][E](PTable): New Entry Processed in 35 ms + 137232 [316992][E](PTable): Power Buffer Reset + 137233 [317663][E](ERG_Mode): Watts previously processed. + 137234 [318975][E](FTMS_SERVER): 05 91 00 -> ERG Mode Target: 145 Current: 226 Incline: 137.740005. Responding: 80 05 01 + 137235 [318983][E](DirConManager): Sending response message type 0x04 to client 0 + 137236 [319074][E](ERG_Mode): SetPoint changed:175w Waiting:1133ms PowerTable Result: 12260 + 137237 [321612][E](ERG_Mode): ERG wait expired, pos: 12260, tgt: 0 + 137238 [321613][E](ERG_Mode): Proportional: -285.000000 + 137239 [322908][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 179, Cad 97, HR 150, Gear 8, Res 40, Current Pos 11765, Target Pos 11765 + 137240 [324450][E](ERG_Mode): Watts previously processed. + 137241 [325158][E](PTable): Averaged Entry: watts=209.100006, cad=95.699997, targetPosition=1258.500000, (7)(7) + 137242 [325159][E](PTData): Cleaned 282 readings + 137243 [325169][E](PTData): New entry recorded (7)(7)(1258) + 137244 [325171][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137245 [325183][E](PTData): Fit Valid: 1, N: 19, Quad: 1, Time: 2 ms + 137246 [325191][E](PTData): Fit Valid: 1, N: 19, Quad: 1, Time: 2 ms + 137247 [325192][E](PTable): New Entry Processed in 35 ms + 137248 [325192][E](PTable): Power Buffer Reset + 137249 [326562][E](ERG_Mode): Watts previously processed. + 137250 [327269][E](ERG_Mode): Proportional: 0.000000 + 137251 [328683][E](ERG_Mode): Watts previously processed. + 137252 [328925][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 145, Cad 97, HR 150, Gear 8, Res 39, Current Pos 11563, Target Pos 11563 + 137253 [330802][E](ERG_Mode): Watts previously processed. + 137254 [331508][E](PTable): Averaged Entry: watts=143.699997, cad=97.300003, targetPosition=1156.000000, (7)(5) + 137255 [331509][E](PTData): Cleaned 281 readings + 137256 [331519][E](PTData): New entry recorded (7)(5)(1156) + 137257 [331521][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137258 [331533][E](PTData): Fit Valid: 1, N: 20, Quad: 1, Time: 2 ms + 137259 [331541][E](PTData): Fit Valid: 1, N: 20, Quad: 1, Time: 1 ms + 137260 [331542][E](PTable): New Entry Processed in 35 ms + 137261 [331543][E](PTable): Power Buffer Reset + 137262 [332920][E](ERG_Mode): Watts previously processed. + 137263 [333627][E](ERG_Mode): Proportional: 42.750000 + 137264 [334937][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 130, Cad 94, HR 151, Gear 8, Res 39, Current Pos 11687, Target Pos 11687 + 137265 [335039][E](PTable): Using detected travel limits during homing + 137266 [335749][E](ERG_Mode): Watts previously processed. + 137267 [337870][E](PTable): Averaged Entry: watts=130.600006, cad=94.300003, targetPosition=1167.000000, (7)(4) + 137268 [337872][E](PTData): Cleaned 280 readings + 137269 [337882][E](PTData): Existing entry averaged (7)(4)(1061), readings(3) + 137270 [337884][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137271 [337896][E](PTData): Fit Valid: 1, N: 20, Quad: 1, Time: 2 ms + 137272 [337904][E](PTData): Fit Valid: 1, N: 20, Quad: 1, Time: 1 ms + 137273 [337905][E](PTable): New Entry Processed in 35 ms + 137274 [337906][E](PTable): Power Buffer Reset + 137275 [338577][E](ERG_Mode): Watts previously processed. + 137276 [339278][E](ERG_Mode): Proportional: 22.500000 + 137277 [340681][E](ERG_Mode): Watts previously processed. + 137278 [340952][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 145, Cad 94, HR 151, Gear 8, Res 40, Current Pos 11773, Target Pos 11773 + 137279 [342797][E](ERG_Mode): Watts previously processed. + 137280 [344214][E](PTable): Averaged Entry: watts=138.300003, cad=93.800003, targetPosition=1176.699951, (7)(5) + 137281 [344215][E](PTData): Cleaned 280 readings + 137282 [344225][E](PTData): Existing entry averaged (7)(5)(1162), readings(2) + 137283 [344226][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137284 [344239][E](PTData): Fit Valid: 1, N: 20, Quad: 1, Time: 2 ms + 137285 [344249][E](PTData): Fit Valid: 1, N: 20, Quad: 1, Time: 1 ms + 137286 [344251][E](PTable): New Entry Processed in 38 ms + 137287 [344251][E](PTable): Power Buffer Reset + 137288 [344916][E](ERG_Mode): Proportional: 1.500000 + 137289 [345622][E](ERG_Mode): Watts previously processed. + 137290 [346969][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 141, Cad 93, HR 149, Gear 8, Res 40, Current Pos 11815, Target Pos 11815 + 137291 [347736][E](ERG_Mode): Watts previously processed. + 137292 [349858][E](ERG_Mode): Watts previously processed. + 137293 [350560][E](PTable): Averaged Entry: watts=142.600006, cad=92.800003, targetPosition=1181.199951, (6)(5) + 137294 [350561][E](PTData): Cleaned 280 readings + 137295 [350572][E](PTData): New entry recorded (6)(5)(1181) + 137296 [350573][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137297 [350585][E](PTData): Fit Valid: 1, N: 21, Quad: 1, Time: 2 ms + 137298 [350595][E](PTData): Fit Valid: 1, N: 21, Quad: 1, Time: 2 ms + 137299 [350596][E](PTable): New Entry Processed in 36 ms + 137300 [350597][E](PTable): Power Buffer Reset + 137301 [350607][E](ERG_Mode): Proportional: 2.250000 + 137302 [351962][E](ERG_Mode): Watts previously processed. + 137303 [352981][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 137, Cad 94, HR 146, Gear 8, Res 40, Current Pos 11828, Target Pos 11828 + 137304 [354787][E](ERG_Mode): Watts previously processed. + 137305 [356204][E](ERG_Mode): Proportional: 0.000000 + 137306 [356912][E](PTable): Averaged Entry: watts=141.899994, cad=93.099998, targetPosition=1182.699951, (7)(5) + 137307 [356913][E](PTData): Cleaned 279 readings + 137308 [356923][E](PTData): Existing entry averaged (7)(5)(1167), readings(3) + 137309 [356925][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137310 [356938][E](PTData): Fit Valid: 1, N: 21, Quad: 1, Time: 3 ms + 137311 [356947][E](PTData): Fit Valid: 1, N: 21, Quad: 1, Time: 2 ms + 137312 [356948][E](PTable): New Entry Processed in 36 ms + 137313 [356948][E](PTable): Power Buffer Reset + 137314 [357620][E](ERG_Mode): Watts previously processed. + 137315 [358990][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 148, Cad 94, HR 143, Gear 8, Res 40, Current Pos 11838, Target Pos 11838 + 137316 [359737][E](ERG_Mode): Watts previously processed. + 137317 [361856][E](ERG_Mode): Watts previously processed. + 137318 [362565][E](ERG_Mode): Proportional: -3.750000 + 137319 [363275][E](PTable): Averaged Entry: watts=144.399994, cad=92.900002, targetPosition=1184.800049, (6)(5) + 137320 [363276][E](PTData): Cleaned 279 readings + 137321 [363286][E](PTData): Existing entry averaged (6)(5)(1182), readings(2) + 137322 [363288][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137323 [363300][E](PTData): Fit Valid: 1, N: 21, Quad: 1, Time: 2 ms + 137324 [363308][E](PTData): Fit Valid: 1, N: 21, Quad: 1, Time: 1 ms + 137325 [363309][E](PTable): New Entry Processed in 34 ms + 137326 [363310][E](PTable): Power Buffer Reset + 137327 [363978][E](ERG_Mode): Watts previously processed. + 137328 [365001][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 143, Cad 93, HR 141, Gear 8, Res 40, Current Pos 11877, Target Pos 11877 + 137329 [366806][E](ERG_Mode): Watts previously processed. + 137330 [368218][E](ERG_Mode): Proportional: 6.000000 + 137331 [369623][E](PTable): Averaged Entry: watts=150.500000, cad=92.400002, targetPosition=1188.800049, (6)(5) + 137332 [369624][E](PTData): Cleaned 279 readings + 137333 [369634][E](PTData): Existing entry averaged (6)(5)(1183), readings(3) + 137334 [369636][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137335 [369648][E](PTData): Fit Valid: 1, N: 21, Quad: 1, Time: 2 ms + 137336 [369656][E](PTData): Fit Valid: 1, N: 21, Quad: 1, Time: 1 ms + 137337 [369657][E](PTable): New Entry Processed in 35 ms + 137338 [369658][E](PTable): Power Buffer Reset + 137339 [369668][E](ERG_Mode): Watts previously processed. + 137340 [371010][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 111, Cad 91, HR 139, Gear 8, Res 40, Current Pos 11830, Target Pos 11830 + 137341 [371031][E](PTable): Using detected travel limits during homing + 137342 [371738][E](ERG_Mode): Watts previously processed. + 137343 [373855][E](ERG_Mode): Watts previously processed. + 137344 [374563][E](ERG_Mode): Proportional: 5.250000 + 137345 [375969][E](PTable): Averaged Entry: watts=129.899994, cad=90.800003, targetPosition=1192.400024, (6)(4) + 137346 [375970][E](PTData): Cleaned 279 readings + 137347 [375980][E](PTData): New entry recorded (6)(4)(1192) + 137348 [375980][E](PTData): Lower Right Found 6, 5, tp1183 + 137349 [375982][E](PTData): Fit Valid: 1, N: 21, Quad: 1, Time: 1 ms + 137350 [375994][E](PTable): New Entry Processed in 26 ms + 137351 [375994][E](PTable): Power Buffer Reset + 137352 [375994][E](ERG_Mode): Watts previously processed. + 137353 [377018][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 133, Cad 89, HR 138, Gear 8, Res 40, Current Pos 12047, Target Pos 12047 + 137354 [378090][E](ERG_Mode): Watts previously processed. + 137355 [379005][E](FTMS_SERVER): 05 f5 00 -> ERG Mode Target: 245 Current: 134 Incline: 120.980003. Responding: 80 05 01 + 137356 [379012][E](DirConManager): Sending response message type 0x04 to client 0 + 137357 [379494][E](ERG_Mode): SetPoint changed:215w Waiting:1123ms PowerTable Result: 13580 + 137358 [382025][E](ERG_Mode): ERG wait expired, pos: 13580, tgt: 0 + 137359 [382026][E](ERG_Mode): Proportional: 65.250000 + 137360 [382735][E](ERG_Mode): Watts previously processed. + 137361 [383035][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 250, Cad 97, HR 139, Gear 8, Res 46, Current Pos 13645, Target Pos 13645 + 137362 [384149][E](PTable): Averaged Entry: watts=175.500000, cad=91.800003, targetPosition=1268.099976, (6)(6) + 137363 [384150][E](PTData): New entry recorded (6)(6)(1268) + 137364 [384161][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137365 [384163][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137366 [384182][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137367 [384183][E](PTable): New Entry Processed in 35 ms + 137368 [384183][E](PTable): Power Buffer Reset + 137369 [384852][E](ERG_Mode): Watts previously processed. + 137370 [386967][E](ERG_Mode): Watts previously processed. + 137371 [387677][E](ERG_Mode): Proportional: 1.500000 + 137372 [389045][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 251, Cad 97, HR 136, Gear 8, Res 46, Current Pos 13577, Target Pos 13577 + 137373 [389087][E](ERG_Mode): Watts previously processed. + 137374 [390495][E](PTable): Averaged Entry: watts=250.399994, cad=97.400002, targetPosition=1358.300049, (7)(8) + 137375 [390496][E](PTData): Cleaned 278 readings + 137376 [390506][E](PTData): Existing entry averaged (7)(8)(1368), readings(7) + 137377 [390507][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137378 [390520][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137379 [390528][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137380 [390529][E](PTable): New Entry Processed in 35 ms + 137381 [390530][E](PTable): Power Buffer Reset + 137382 [391913][E](ERG_Mode): Watts previously processed. + 137383 [393322][E](ERG_Mode): Proportional: 1.500000 + 137384 [394735][E](ERG_Mode): Watts previously processed. + 137385 [395061][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 232, Cad 95, HR 135, Gear 8, Res 46, Current Pos 13582, Target Pos 13582 + 137386 [396854][E](PTable): Averaged Entry: watts=240.000000, cad=95.699997, targetPosition=1358.300049, (7)(8) + 137387 [396855][E](PTData): Cleaned 278 readings + 137388 [396865][E](PTData): Existing entry averaged (7)(8)(1366), readings(8) + 137389 [396867][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137390 [396879][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137391 [396887][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137392 [396888][E](PTable): New Entry Processed in 35 ms + 137393 [396889][E](PTable): Power Buffer Reset + 137394 [396899][E](ERG_Mode): Watts previously processed. + 137395 [398968][E](ERG_Mode): Watts previously processed. + 137396 [399677][E](ERG_Mode): Proportional: 24.750000 + 137397 [401078][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 231, Cad 93, HR 135, Gear 8, Res 46, Current Pos 13743, Target Pos 13743 + 137398 [401089][E](ERG_Mode): Watts previously processed. + 137399 [403208][E](PTable): Averaged Entry: watts=232.800003, cad=93.500000, targetPosition=1370.400024, (7)(8) + 137400 [403209][E](PTData): Cleaned 278 readings + 137401 [403219][E](PTData): Existing entry averaged (7)(8)(1366), readings(9) + 137402 [403220][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137403 [403233][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137404 [403241][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137405 [403242][E](PTable): New Entry Processed in 34 ms + 137406 [403243][E](PTable): Power Buffer Reset + 137407 [404620][E](ERG_Mode): Watts previously processed. + 137408 [405326][E](ERG_Mode): Proportional: 0.750000 + 137409 [406733][E](ERG_Mode): Watts previously processed. + 137410 [407090][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 241, Cad 93, HR 137, Gear 8, Res 47, Current Pos 13840, Target Pos 13840 + 137411 [408850][E](ERG_Mode): Watts previously processed. + 137412 [408850][E](PTable): Using detected travel limits during homing + 137413 [409568][E](PTable): Averaged Entry: watts=239.199997, cad=92.599998, targetPosition=1383.500000, (6)(8) + 137414 [409570][E](PTData): Cleaned 278 readings + 137415 [409580][E](PTData): Existing entry averaged (6)(8)(1403), readings(4) + 137416 [409581][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137417 [409594][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137418 [409602][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137419 [409603][E](PTable): New Entry Processed in 35 ms + 137420 [409603][E](PTable): Power Buffer Reset + 137421 [410976][E](ERG_Mode): Watts previously processed. + 137422 [411685][E](ERG_Mode): Proportional: 6.750000 + 137423 [413096][E](ERG_Mode): Watts previously processed. + 137424 [413107][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 245, Cad 92, HR 138, Gear 8, Res 47, Current Pos 13859, Target Pos 13859 + 137425 [414510][E](ERG_Mode): Watts previously processed. + 137426 [415926][E](PTable): Averaged Entry: watts=242.500000, cad=92.400002, targetPosition=1385.000000, (6)(8) + 137427 [415927][E](PTData): Cleaned 278 readings + 137428 [415937][E](PTData): Existing entry averaged (6)(8)(1400), readings(5) + 137429 [415939][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137430 [415951][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137431 [415959][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137432 [415960][E](PTable): New Entry Processed in 34 ms + 137433 [415961][E](PTable): Power Buffer Reset + 137434 [416632][E](ERG_Mode): Watts previously processed. + 137435 [417339][E](ERG_Mode): Proportional: 6.000000 + 137436 [418748][E](ERG_Mode): Watts previously processed. + 137437 [419124][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 241, Cad 92, HR 139, Gear 8, Res 47, Current Pos 13870, Target Pos 13870 + 137438 [420869][E](ERG_Mode): Watts previously processed. + 137439 [422284][E](PTable): Averaged Entry: watts=241.800003, cad=92.300003, targetPosition=1386.599976, (6)(8) + 137440 [422285][E](PTData): Cleaned 278 readings + 137441 [422295][E](PTData): Existing entry averaged (6)(8)(1398), readings(6) + 137442 [422297][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137443 [422309][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137444 [422317][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137445 [422318][E](PTable): New Entry Processed in 34 ms + 137446 [422319][E](PTable): Power Buffer Reset + 137447 [422989][E](ERG_Mode): Watts previously processed. + 137448 [423707][E](ERG_Mode): Proportional: 4.500000 + 137449 [425114][E](ERG_Mode): Watts previously processed. + 137450 [425135][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 248, Cad 93, HR 141, Gear 8, Res 47, Current Pos 13875, Target Pos 13875 + 137451 [426522][E](ERG_Mode): Watts previously processed. + 137452 [427227][E](ERG_Mode): Watts previously processed. + 137453 [428640][E](PTable): Averaged Entry: watts=243.399994, cad=92.800003, targetPosition=1387.099976, (6)(8) + 137454 [428641][E](PTData): Cleaned 278 readings + 137455 [428651][E](PTData): Existing entry averaged (6)(8)(1396), readings(7) + 137456 [428653][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137457 [428665][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137458 [428673][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137459 [428674][E](PTable): New Entry Processed in 34 ms + 137460 [428675][E](PTable): Power Buffer Reset + 137461 [428685][E](ERG_Mode): Watts previously processed. + 137462 [429349][E](ERG_Mode): Proportional: -40.500000 + 137463 [430754][E](ERG_Mode): Watts previously processed. + 137464 [431150][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 237, Cad 95, HR 144, Gear 8, Res 47, Current Pos 13800, Target Pos 13800 + 137465 [432871][E](ERG_Mode): Watts previously processed. + 137466 [434987][E](PTable): Averaged Entry: watts=251.399994, cad=93.599998, targetPosition=1382.300049, (7)(8) + 137467 [434988][E](PTData): Cleaned 278 readings + 137468 [434998][E](PTData): Existing entry averaged (7)(8)(1367), readings(10) + 137469 [434999][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137470 [435012][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137471 [435020][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137472 [435021][E](PTable): New Entry Processed in 35 ms + 137473 [435022][E](PTable): Power Buffer Reset + 137474 [435032][E](ERG_Mode): Watts previously processed. + 137475 [435695][E](ERG_Mode): Proportional: -36.000000 + 137476 [437108][E](ERG_Mode): Watts previously processed. + 137477 [437160][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 255, Cad 95, HR 146, Gear 8, Res 46, Current Pos 13748, Target Pos 13748 + 137478 [438522][E](ERG_Mode): Watts previously processed. + 137479 [438971][E](FTMS_SERVER): 05 91 00 -> ERG Mode Target: 145 Current: 252 Incline: 137.419998. Responding: 80 05 01 + 137480 [438976][E](DirConManager): Sending response message type 0x04 to client 0 + 137481 [439223][E](ERG_Mode): SetPoint changed:175w Waiting:1181ms PowerTable Result: 12060 + 137482 [441804][E](ERG_Mode): ERG wait expired, pos: 12060, tgt: 0 + 137483 [441805][E](ERG_Mode): Proportional: -291.000000 + 137484 [443170][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 175, Cad 99, HR 148, Gear 8, Res 39, Current Pos 11667, Target Pos 11667 + 137485 [443221][E](PTable): Averaged Entry: watts=239.500000, cad=96.000000, targetPosition=1318.099976, (7)(8) + 137486 [443222][E](PTData): Cleaned 278 readings + 137487 [443232][E](PTData): Existing entry averaged (7)(8)(1362), readings(11) + 137488 [443233][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137489 [443245][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137490 [443254][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137491 [443255][E](PTable): New Entry Processed in 34 ms + 137492 [443255][E](PTable): Power Buffer Reset + 137493 [443927][E](ERG_Mode): Watts previously processed. + 137494 [446042][E](ERG_Mode): Watts previously processed. + 137495 [446750][E](PTable): Using detected travel limits during homing + 137496 [447458][E](ERG_Mode): Proportional: 1.500000 + 137497 [448163][E](ERG_Mode): Watts previously processed. + 137498 [449186][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 138, Cad 97, HR 149, Gear 8, Res 39, Current Pos 11555, Target Pos 11555 + 137499 [449573][E](PTable): Averaged Entry: watts=151.399994, cad=97.900002, targetPosition=1155.800049, (7)(5) + 137500 [449574][E](PTData): Cleaned 278 readings + 137501 [449584][E](PTData): Existing entry averaged (7)(5)(1164), readings(4) + 137502 [449586][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137503 [449598][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137504 [449606][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137505 [449608][E](PTable): New Entry Processed in 35 ms + 137506 [449608][E](PTable): Power Buffer Reset + 137507 [451689][E](ERG_Mode): Watts previously processed. + 137508 [453101][E](ERG_Mode): Proportional: 27.000000 + 137509 [453810][E](ERG_Mode): Watts previously processed. + 137510 [455199][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 121, Cad 95, HR 150, Gear 8, Res 39, Current Pos 11648, Target Pos 11648 + 137511 [455924][E](PTable): Averaged Entry: watts=132.600006, cad=95.800003, targetPosition=1160.500000, (7)(4) + 137512 [455925][E](PTData): Cleaned 278 readings + 137513 [455935][E](PTData): Existing entry averaged (7)(4)(1080), readings(4) + 137514 [455936][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137515 [455949][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137516 [455957][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137517 [455958][E](PTable): New Entry Processed in 34 ms + 137518 [455959][E](PTable): Power Buffer Reset + 137519 [455969][E](ERG_Mode): Watts previously processed. + 137520 [458051][E](ERG_Mode): Watts previously processed. + 137521 [458754][E](ERG_Mode): Proportional: 6.000000 + 137522 [460159][E](ERG_Mode): Watts previously processed. + 137523 [461211][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 126, Cad 93, HR 150, Gear 8, Res 40, Current Pos 11787, Target Pos 11787 + 137524 [461567][E](ERG_Mode): Watts previously processed. + 137525 [462274][E](PTable): Averaged Entry: watts=134.300003, cad=93.599998, targetPosition=1173.500000, (7)(4) + 137526 [462275][E](PTData): Cleaned 278 readings + 137527 [462285][E](PTData): Existing entry averaged (7)(4)(1095), readings(5) + 137528 [462287][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137529 [462299][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137530 [462307][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137531 [462308][E](PTable): New Entry Processed in 34 ms + 137532 [462309][E](PTable): Power Buffer Reset + 137533 [463683][E](ERG_Mode): Watts previously processed. + 137534 [464393][E](ERG_Mode): Proportional: 0.750000 + 137535 [465801][E](ERG_Mode): Watts previously processed. + 137536 [467229][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 138, Cad 94, HR 148, Gear 8, Res 40, Current Pos 11801, Target Pos 11806 + 137537 [467927][E](ERG_Mode): Watts previously processed. + 137538 [468636][E](PTable): Averaged Entry: watts=139.899994, cad=92.800003, targetPosition=1179.500000, (6)(5) + 137539 [468637][E](PTData): Cleaned 278 readings + 137540 [468647][E](PTData): Existing entry averaged (6)(5)(1182), readings(3) + 137541 [468649][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137542 [468661][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137543 [468669][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137544 [468671][E](PTable): New Entry Processed in 36 ms + 137545 [468671][E](PTable): Power Buffer Reset + 137546 [470048][E](ERG_Mode): Watts previously processed. + 137547 [470755][E](ERG_Mode): Proportional: 4.500000 + 137548 [472865][E](ERG_Mode): Watts previously processed. + 137549 [473242][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 139, Cad 93, HR 145, Gear 8, Res 40, Current Pos 11818, Target Pos 11818 + 137550 [474985][E](PTable): Averaged Entry: watts=140.100006, cad=92.900002, targetPosition=1180.800049, (6)(5) + 137551 [474987][E](PTData): Cleaned 278 readings + 137552 [474997][E](PTData): Existing entry averaged (6)(5)(1181), readings(4) + 137553 [474999][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137554 [475012][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 3 ms + 137555 [475020][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137556 [475021][E](PTable): New Entry Processed in 36 ms + 137557 [475022][E](PTable): Power Buffer Reset + 137558 [475692][E](ERG_Mode): Watts previously processed. + 137559 [476401][E](ERG_Mode): Proportional: 36.000000 + 137560 [477811][E](ERG_Mode): Watts previously processed. + 137561 [479252][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 145, Cad 91, HR 143, Gear 8, Res 40, Current Pos 11922, Target Pos 11922 + 137562 [479926][E](ERG_Mode): Watts previously processed. + 137563 [481342][E](PTable): Averaged Entry: watts=136.000000, cad=91.099998, targetPosition=1189.500000, (6)(5) + 137564 [481343][E](PTData): Cleaned 278 readings + 137565 [481355][E](PTData): Existing entry averaged (6)(5)(1182), readings(5) + 137566 [481356][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137567 [481369][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137568 [481377][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137569 [481378][E](PTable): New Entry Processed in 37 ms + 137570 [481379][E](PTable): Power Buffer Reset + 137571 [482052][E](ERG_Mode): Watts previously processed. + 137572 [482759][E](ERG_Mode): Proportional: 33.750000 + 137573 [482760][E](PTable): Using detected travel limits during homing + 137574 [484870][E](ERG_Mode): Watts previously processed. + 137575 [485267][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 132, Cad 91, HR 141, Gear 8, Res 40, Current Pos 12021, Target Pos 12021 + 137576 [486984][E](ERG_Mode): Watts previously processed. + 137577 [487694][E](PTable): Averaged Entry: watts=136.699997, cad=90.199997, targetPosition=1200.800049, (6)(5) + 137578 [487695][E](PTData): Cleaned 278 readings + 137579 [487705][E](PTData): Existing entry averaged (6)(5)(1184), readings(6) + 137580 [487707][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137581 [487719][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137582 [487728][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137583 [487729][E](PTable): New Entry Processed in 35 ms + 137584 [487832][E](PTable): Writing File: /PowerTable.txt + 137585 [488069][E](PTable): Power table saved successfully with 364 readings + 137586 [488069][E](PTable): Power Buffer Reset + 137587 [488069][E](ERG_Mode): Proportional: 1.500000 + 137588 [489100][E](ERG_Mode): Watts previously processed. + 137589 [491214][E](ERG_Mode): Watts previously processed. + 137590 [491280][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 141, Cad 90, HR 139, Gear 8, Res 41, Current Pos 12066, Target Pos 12066 + 137591 [493333][E](ERG_Mode): Proportional: 4.500000 + 137592 [494044][E](PTable): Averaged Entry: watts=143.899994, cad=90.099998, targetPosition=1206.699951, (6)(5) + 137593 [494045][E](PTData): Cleaned 278 readings + 137594 [494055][E](PTData): Existing entry averaged (6)(5)(1186), readings(7) + 137595 [494057][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137596 [494069][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137597 [494077][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137598 [494079][E](PTable): New Entry Processed in 36 ms + 137599 [494079][E](PTable): Power Buffer Reset + 137600 [494750][E](ERG_Mode): Watts previously processed. + 137601 [496867][E](ERG_Mode): Watts previously processed. + 137602 [497295][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 124, Cad 89, HR 136, Gear 8, Res 40, Current Pos 12011, Target Pos 12011 + 137603 [498982][E](ERG_Mode): Watts previously processed. + 137604 [498996][E](FTMS_SERVER): 05 f5 00 -> ERG Mode Target: 245 Current: 129 Incline: 120.940002. Responding: 80 05 01 + 137605 [499003][E](DirConManager): Sending response message type 0x04 to client 0 + 137606 [499687][E](ERG_Mode): SetPoint changed:215w Waiting:1142ms PowerTable Result: 13640 + 137607 [502239][E](ERG_Mode): ERG wait expired, pos: 13640, tgt: 0 + 137608 [502240][E](PTable): Averaged Entry: watts=139.600006, cad=89.400002, targetPosition=1220.800049, (6)(5) + 137609 [502251][E](PTData): Cleaned 278 readings + 137610 [502251][E](PTData): Existing entry averaged (6)(5)(1189), readings(8) + 137611 [502263][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137612 [502265][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137613 [502283][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137614 [502284][E](PTable): New Entry Processed in 44 ms + 137615 [502285][E](PTable): Power Buffer Reset + 137616 [502295][E](ERG_Mode): Proportional: 378.750000 + 137617 [502947][E](ERG_Mode): Watts previously processed. + 137618 [503307][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 199, Cad 89, HR 135, Gear 8, Res 47, Current Pos 14018, Target Pos 14018 + 137619 [505762][E](ERG_Mode): Watts previously processed. + 137620 [507877][E](ERG_Mode): Watts previously processed. + 137621 [508585][E](PTable): Averaged Entry: watts=216.699997, cad=90.400002, targetPosition=1410.400024, (6)(7) + 137622 [508586][E](PTData): Cleaned 278 readings + 137623 [508596][E](PTData): New entry recorded (6)(7)(1410) + 137624 [508597][E](PTData): Lower Right Found 6, 8, tp1396 + 137625 [508597][E](PTData): Lower Up Found 5, 7, tp1402 + 137626 [508609][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137627 [508611][E](PTable): New Entry Processed in 26 ms + 137628 [508611][E](PTable): Power Buffer Reset + 137629 [508621][E](ERG_Mode): Proportional: 1.500000 + 137630 [509319][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 247, Cad 92, HR 135, Gear 8, Res 48, Current Pos 14152, Target Pos 14152 + 137631 [509996][E](ERG_Mode): Watts previously processed. + 137632 [512110][E](ERG_Mode): Watts previously processed. + 137633 [514236][E](ERG_Mode): Proportional: -4.500000 + 137634 [514946][E](PTable): Averaged Entry: watts=248.899994, cad=92.000000, targetPosition=1414.300049, (6)(8) + 137635 [514947][E](PTData): Existing entry averaged (6)(8)(1398), readings(7) + 137636 [514958][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137637 [514960][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137638 [514979][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137639 [514980][E](PTable): New Entry Processed in 34 ms + 137640 [514981][E](PTable): Power Buffer Reset + 137641 [514991][E](ERG_Mode): Watts previously processed. + 137642 [515334][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 253, Cad 92, HR 136, Gear 8, Res 48, Current Pos 14134, Target Pos 14134 + 137643 [517777][E](ERG_Mode): Watts previously processed. + 137644 [519896][E](ERG_Mode): Watts previously processed. + 137645 [520597][E](ERG_Mode): Proportional: -29.250000 + 137646 [520598][E](PTable): Using detected travel limits during homing + 137647 [521299][E](PTable): Averaged Entry: watts=252.300003, cad=91.699997, targetPosition=1411.500000, (6)(8) + 137648 [521300][E](PTData): Cleaned 278 readings + 137649 [521310][E](PTData): Existing entry averaged (6)(8)(1399), readings(8) + 137650 [521312][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137651 [521324][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137652 [521332][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137653 [521334][E](PTable): New Entry Processed in 36 ms + 137654 [521334][E](PTable): Power Buffer Reset + 137655 [521345][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 258, Cad 92, HR 137, Gear 8, Res 47, Current Pos 14082, Target Pos 14082 + 137656 [522006][E](ERG_Mode): Watts previously processed. + 137657 [524126][E](ERG_Mode): Watts previously processed. + 137658 [526238][E](ERG_Mode): Watts previously processed. + 137659 [526947][E](ERG_Mode): Proportional: 33.750000 + 137660 [527354][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 228, Cad 89, HR 140, Gear 8, Res 48, Current Pos 14160, Target Pos 14160 + 137661 [527657][E](PTable): Averaged Entry: watts=239.000000, cad=90.900002, targetPosition=1408.199951, (6)(8) + 137662 [527658][E](PTData): Cleaned 278 readings + 137663 [527668][E](PTData): Existing entry averaged (6)(8)(1399), readings(9) + 137664 [527669][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137665 [527682][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137666 [527690][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137667 [527692][E](PTable): New Entry Processed in 35 ms + 137668 [527692][E](PTable): Power Buffer Reset + 137669 [529771][E](ERG_Mode): Watts previously processed. + 137670 [531890][E](ERG_Mode): Watts previously processed. + 137671 [532598][E](ERG_Mode): Proportional: -22.500000 + 137672 [533368][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 246, Cad 91, HR 144, Gear 8, Res 48, Current Pos 14196, Target Pos 14196 + 137673 [534014][E](PTable): Averaged Entry: watts=243.500000, cad=89.599998, targetPosition=1420.800049, (6)(8) + 137674 [534015][E](PTData): Cleaned 278 readings + 137675 [534026][E](PTData): Existing entry averaged (6)(8)(1400), readings(10) + 137676 [534027][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137677 [534039][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137678 [534047][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137679 [534049][E](PTable): New Entry Processed in 35 ms + 137680 [534049][E](PTable): Power Buffer Reset + 137681 [534059][E](ERG_Mode): Watts previously processed. + 137682 [536124][E](ERG_Mode): Watts previously processed. + 137683 [538244][E](ERG_Mode): Watts previously processed. + 137684 [538955][E](ERG_Mode): Proportional: -6.000000 + 137685 [539383][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 252, Cad 92, HR 145, Gear 8, Res 48, Current Pos 14139, Target Pos 14139 + 137686 [540382][E](PTable): Averaged Entry: watts=253.600006, cad=91.900002, targetPosition=1415.599976, (6)(8) + 137687 [540383][E](PTData): Cleaned 278 readings + 137688 [540394][E](PTData): Existing entry averaged (6)(8)(1401), readings(11) + 137689 [540395][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137690 [540407][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137691 [540416][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137692 [540417][E](PTable): New Entry Processed in 35 ms + 137693 [540417][E](PTable): Power Buffer Reset + 137694 [541792][E](ERG_Mode): Watts previously processed. + 137695 [543903][E](ERG_Mode): Watts previously processed. + 137696 [544613][E](ERG_Mode): Proportional: 2.250000 + 137697 [545393][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 254, Cad 90, HR 145, Gear 8, Res 48, Current Pos 14151, Target Pos 14150 + 137698 [546030][E](ERG_Mode): Watts previously processed. + 137699 [546738][E](PTable): Averaged Entry: watts=244.000000, cad=90.699997, targetPosition=1413.500000, (6)(8) + 137700 [546740][E](PTData): Cleaned 278 readings + 137701 [546750][E](PTData): Existing entry averaged (6)(8)(1401), readings(12) + 137702 [546751][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137703 [546763][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137704 [546772][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137705 [546773][E](PTable): New Entry Processed in 35 ms + 137706 [546773][E](PTable): Power Buffer Reset + 137707 [548151][E](ERG_Mode): Watts previously processed. + 137708 [550263][E](ERG_Mode): Watts previously processed. + 137709 [550971][E](ERG_Mode): Proportional: 0.750000 + 137710 [551409][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 244, Cad 90, HR 148, Gear 8, Res 48, Current Pos 14151, Target Pos 14151 + 137711 [553081][E](PTable): Averaged Entry: watts=244.000000, cad=90.599998, targetPosition=1415.000000, (6)(8) + 137712 [553082][E](PTData): Cleaned 278 readings + 137713 [553092][E](PTData): Existing entry averaged (6)(8)(1402), readings(13) + 137714 [553094][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137715 [553106][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137716 [553114][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137717 [553115][E](PTable): New Entry Processed in 34 ms + 137718 [553116][E](PTable): Power Buffer Reset + 137719 [553787][E](ERG_Mode): Watts previously processed. + 137720 [555906][E](ERG_Mode): Watts previously processed. + 137721 [556612][E](ERG_Mode): Proportional: 3.000000 + 137722 [556613][E](PTable): Using detected travel limits during homing + 137723 [557425][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 232, Cad 90, HR 150, Gear 8, Res 48, Current Pos 14176, Target Pos 14185 + 137724 [558023][E](ERG_Mode): Watts previously processed. + 137725 [559006][E](FTMS_SERVER): 05 91 00 -> ERG Mode Target: 145 Current: 237 Incline: 141.910004. Responding: 80 05 01 + 137726 [559013][E](DirConManager): Sending response message type 0x04 to client 0 + 137727 [559437][E](PTable): Averaged Entry: watts=239.500000, cad=89.800003, targetPosition=1416.000000, (6)(8) + 137728 [559438][E](PTData): Cleaned 278 readings + 137729 [559448][E](PTData): Existing entry averaged (6)(8)(1402), readings(14) + 137730 [559450][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137731 [559462][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137732 [559470][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137733 [559471][E](PTable): New Entry Processed in 34 ms + 137734 [559472][E](PTable): Power Buffer Reset + 137735 [559482][E](ERG_Mode): SetPoint changed:175w Waiting:1140ms PowerTable Result: 12650 + 137736 [561979][E](ERG_Mode): ERG wait expired, pos: 12650, tgt: 0 + 137737 [561980][E](ERG_Mode): Proportional: -270.000000 + 137738 [563442][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 170, Cad 91, HR 150, Gear 8, Res 41, Current Pos 12281, Target Pos 12228 + 137739 [564101][E](ERG_Mode): Watts previously processed. + 137740 [566921][E](ERG_Mode): Watts previously processed. + 137741 [567624][E](PTable): Averaged Entry: watts=176.500000, cad=90.199997, targetPosition=1230.099976, (6)(6) + 137742 [567625][E](PTData): Cleaned 278 readings + 137743 [567635][E](PTData): Existing entry averaged (6)(6)(1255), readings(2) + 137744 [567637][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137745 [567649][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137746 [567657][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137747 [567659][E](PTable): New Entry Processed in 36 ms + 137748 [567659][E](PTable): Power Buffer Reset + 137749 [567669][E](ERG_Mode): Proportional: 1.500000 + 137750 [569027][E](ERG_Mode): Watts previously processed. + 137751 [569454][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 151, Cad 90, HR 151, Gear 8, Res 41, Current Pos 12148, Target Pos 12148 + 137752 [571135][E](ERG_Mode): Watts previously processed. + 137753 [573252][E](ERG_Mode): Watts previously processed. + 137754 [573960][E](PTable): Averaged Entry: watts=152.600006, cad=90.099998, targetPosition=1213.699951, (6)(5) + 137755 [573961][E](PTData): Cleaned 278 readings + 137756 [573971][E](PTData): Existing entry averaged (6)(5)(1191), readings(9) + 137757 [573972][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137758 [573985][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137759 [573993][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137760 [573994][E](PTable): New Entry Processed in 35 ms + 137761 [573995][E](PTable): Power Buffer Reset + 137762 [574005][E](ERG_Mode): Proportional: -72.000000 + 137763 [575465][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 148, Cad 92, HR 150, Gear 8, Res 40, Current Pos 12020, Target Pos 12020 + 137764 [576780][E](ERG_Mode): Watts previously processed. + 137765 [578899][E](ERG_Mode): Watts previously processed. + 137766 [579616][E](ERG_Mode): Proportional: -0.750000 + 137767 [580324][E](PTable): Averaged Entry: watts=149.899994, cad=91.300003, targetPosition=1202.199951, (6)(5) + 137768 [580325][E](PTData): Cleaned 278 readings + 137769 [580335][E](PTData): Existing entry averaged (6)(5)(1192), readings(10) + 137770 [580337][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137771 [580349][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137772 [580357][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137773 [580358][E](PTable): New Entry Processed in 35 ms + 137774 [580359][E](PTable): Power Buffer Reset + 137775 [581030][E](ERG_Mode): Watts previously processed. + 137776 [581478][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 143, Cad 90, HR 150, Gear 8, Res 40, Current Pos 12011, Target Pos 12011 + 137777 [583141][E](ERG_Mode): Watts previously processed. + 137778 [585261][E](ERG_Mode): Watts previously processed. + 137779 [585969][E](ERG_Mode): Proportional: -6.750000 + 137780 [586670][E](PTable): Averaged Entry: watts=157.199997, cad=91.900002, targetPosition=1194.900024, (6)(5) + 137781 [586671][E](PTData): Cleaned 278 readings + 137782 [586681][E](PTData): Existing entry averaged (6)(5)(1192), readings(11) + 137783 [586683][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137784 [586695][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137785 [586703][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137786 [586705][E](PTable): New Entry Processed in 35 ms + 137787 [586705][E](PTable): Power Buffer Reset + 137788 [587493][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 150, Cad 95, HR 149, Gear 8, Res 40, Current Pos 11808, Target Pos 11808 + 137789 [588783][E](ERG_Mode): Watts previously processed. + 137790 [590901][E](ERG_Mode): Watts previously processed. + 137791 [591610][E](ERG_Mode): Proportional: 5.250000 + 137792 [593029][E](PTable): Averaged Entry: watts=141.199997, cad=93.400002, targetPosition=1181.099976, (7)(5) + 137793 [593030][E](PTData): Cleaned 278 readings + 137794 [593040][E](PTData): Existing entry averaged (7)(5)(1166), readings(5) + 137795 [593041][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137796 [593054][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137797 [593062][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137798 [593063][E](PTable): New Entry Processed in 35 ms + 137799 [593064][E](PTable): Power Buffer Reset + 137800 [593074][E](ERG_Mode): Watts previously processed. + 137801 [593506][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 142, Cad 92, HR 149, Gear 8, Res 40, Current Pos 11829, Target Pos 11829 + 137802 [594444][E](PTable): Using detected travel limits during homing + 137803 [595149][E](ERG_Mode): Watts previously processed. + 137804 [597271][E](ERG_Mode): Watts previously processed. + 137805 [597975][E](ERG_Mode): Proportional: 0.750000 + 137806 [598682][E](ERG_Mode): Watts previously processed. + 137807 [599390][E](PTable): Averaged Entry: watts=144.100006, cad=92.300003, targetPosition=1182.800049, (6)(5) + 137808 [599391][E](PTData): Cleaned 278 readings + 137809 [599401][E](PTData): Existing entry averaged (6)(5)(1191), readings(12) + 137810 [599403][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137811 [599415][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137812 [599423][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137813 [599425][E](PTable): New Entry Processed in 35 ms + 137814 [599425][E](PTable): Power Buffer Reset + 137815 [599436][E](ERG_Mode): Watts previously processed. + 137816 [599526][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 140, Cad 92, HR 146, Gear 8, Res 40, Current Pos 11831, Target Pos 11831 + 137817 [600806][E](ERG_Mode): Watts previously processed. + 137818 [602928][E](ERG_Mode): Watts previously processed. + 137819 [603635][E](ERG_Mode): Proportional: 6.750000 + 137820 [605050][E](ERG_Mode): Watts previously processed. + 137821 [605538][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 133, Cad 90, HR 142, Gear 8, Res 40, Current Pos 11902, Target Pos 11902 + 137822 [605760][E](PTable): Averaged Entry: watts=135.399994, cad=91.099998, targetPosition=1185.699951, (6)(5) + 137823 [605761][E](PTData): Cleaned 278 readings + 137824 [605771][E](PTData): Existing entry averaged (6)(5)(1190), readings(13) + 137825 [605772][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137826 [605785][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137827 [605793][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137828 [605794][E](PTable): New Entry Processed in 34 ms + 137829 [605795][E](PTable): Power Buffer Reset + 137830 [607175][E](ERG_Mode): Watts previously processed. + 137831 [609300][E](ERG_Mode): Proportional: 22.500000 + 137832 [610721][E](ERG_Mode): Watts previously processed. + 137833 [611551][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 130, Cad 90, HR 139, Gear 8, Res 40, Current Pos 12046, Target Pos 12056 + 137834 [612139][E](PTable): Averaged Entry: watts=135.600006, cad=89.900002, targetPosition=1198.099976, (6)(5) + 137835 [612140][E](PTData): Cleaned 278 readings + 137836 [612150][E](PTData): Existing entry averaged (6)(5)(1190), readings(14) + 137837 [612151][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137838 [612164][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137839 [612172][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137840 [612174][E](PTable): New Entry Processed in 35 ms + 137841 [612174][E](PTable): Power Buffer Reset + 137842 [612847][E](ERG_Mode): Watts previously processed. + 137843 [614963][E](ERG_Mode): Watts previously processed. + 137844 [615670][E](ERG_Mode): Proportional: -4.500000 + 137845 [617086][E](ERG_Mode): Watts previously processed. + 137846 [617565][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 146, Cad 92, HR 137, Gear 8, Res 41, Current Pos 12043, Target Pos 12043 + 137847 [618496][E](PTable): Averaged Entry: watts=147.600006, cad=91.099998, targetPosition=1204.599976, (6)(5) + 137848 [618497][E](PTData): Cleaned 278 readings + 137849 [618507][E](PTData): Existing entry averaged (6)(5)(1190), readings(15) + 137850 [618508][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137851 [618521][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137852 [618529][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137853 [618530][E](PTable): New Entry Processed in 35 ms + 137854 [618531][E](PTable): Power Buffer Reset + 137855 [618987][E](FTMS_SERVER): 05 f5 00 -> ERG Mode Target: 245 Current: 138 Incline: 120.470001. Responding: 80 05 01 + 137856 [618993][E](DirConManager): Sending response message type 0x04 to client 0 + 137857 [619199][E](ERG_Mode): SetPoint changed:215w Waiting:1069ms PowerTable Result: 13340 + 137858 [621668][E](ERG_Mode): ERG wait expired, pos: 13340, tgt: 0 + 137859 [621669][E](ERG_Mode): Proportional: 276.000000 + 137860 [623075][E](ERG_Mode): Watts previously processed. + 137861 [623582][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 243, Cad 96, HR 134, Gear 8, Res 46, Current Pos 13706, Target Pos 13706 + 137862 [625897][E](ERG_Mode): Watts previously processed. + 137863 [626604][E](PTable): Averaged Entry: watts=203.300003, cad=94.300003, targetPosition=1332.599976, (7)(7) + 137864 [626605][E](PTData): Cleaned 278 readings + 137865 [626615][E](PTData): Existing entry averaged (7)(7)(1282), readings(2) + 137866 [626617][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137867 [626629][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137868 [626637][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137869 [626639][E](PTable): New Entry Processed in 36 ms + 137870 [626639][E](PTable): Power Buffer Reset + 137871 [627306][E](ERG_Mode): Proportional: -3.000000 + 137872 [628014][E](ERG_Mode): Watts previously processed. + 137873 [629599][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 246, Cad 96, HR 133, Gear 8, Res 46, Current Pos 13716, Target Pos 13716 + 137874 [630135][E](ERG_Mode): Watts previously processed. + 137875 [632256][E](PTable): Using detected travel limits during homing + 137876 [632962][E](PTable): Averaged Entry: watts=246.500000, cad=95.599998, targetPosition=1371.199951, (7)(8) + 137877 [632964][E](PTData): Cleaned 278 readings + 137878 [632974][E](PTData): Existing entry averaged (7)(8)(1362), readings(12) + 137879 [632975][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137880 [632987][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137881 [632996][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137882 [632997][E](PTable): New Entry Processed in 35 ms + 137883 [632998][E](PTable): Power Buffer Reset + 137884 [633008][E](ERG_Mode): Watts previously processed. + 137885 [633666][E](ERG_Mode): Proportional: -3.000000 + 137886 [635073][E](ERG_Mode): Watts previously processed. + 137887 [635614][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 251, Cad 96, HR 134, Gear 8, Res 46, Current Pos 13706, Target Pos 13706 + 137888 [637191][E](ERG_Mode): Watts previously processed. + 137889 [639306][E](PTable): Averaged Entry: watts=246.699997, cad=95.500000, targetPosition=1370.199951, (7)(8) + 137890 [639307][E](PTData): Cleaned 278 readings + 137891 [639317][E](PTData): Existing entry averaged (7)(8)(1362), readings(13) + 137892 [639319][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137893 [639331][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137894 [639339][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137895 [639340][E](PTable): New Entry Processed in 35 ms + 137896 [639341][E](PTable): Power Buffer Reset + 137897 [639351][E](ERG_Mode): Watts previously processed. + 137898 [640008][E](ERG_Mode): Proportional: 5.250000 + 137899 [641623][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 247, Cad 96, HR 135, Gear 8, Res 46, Current Pos 13700, Target Pos 13700 + 137900 [642833][E](ERG_Mode): Watts previously processed. + 137901 [644951][E](ERG_Mode): Watts previously processed. + 137902 [645659][E](PTable): Averaged Entry: watts=245.199997, cad=95.199997, targetPosition=1370.400024, (7)(8) + 137903 [645660][E](PTData): Cleaned 278 readings + 137904 [645670][E](PTData): Existing entry averaged (7)(8)(1362), readings(14) + 137905 [645672][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137906 [645684][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137907 [645692][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 1 ms + 137908 [645693][E](PTable): New Entry Processed in 34 ms + 137909 [645694][E](PTable): Power Buffer Reset + 137910 [645704][E](ERG_Mode): Proportional: -31.500000 + 137911 [647063][E](ERG_Mode): Watts previously processed. + 137912 [647639][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 254, Cad 97, HR 138, Gear 8, Res 46, Current Pos 13681, Target Pos 13681 + 137913 [649175][E](ERG_Mode): Watts previously processed. + 137914 [651290][E](ERG_Mode): Proportional: -33.750000 + 137915 [651997][E](PTable): Averaged Entry: watts=254.000000, cad=96.800003, targetPosition=1366.199951, (7)(8) + 137916 [651998][E](PTData): Cleaned 278 readings + 137917 [652008][E](PTData): Existing entry averaged (7)(8)(1362), readings(15) + 137918 [652009][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137919 [652022][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137920 [652030][E](PTData): Fit Valid: 1, N: 22, Quad: 1, Time: 2 ms + 137921 [652031][E](PTable): New Entry Processed in 34 ms + 137922 [652032][E](PTable): Power Buffer Reset + 137923 [652042][E](ERG_Mode): Watts previously processed. + 137924 [653405][E](ERG_Mode): Watts previously processed. + 137925 [653651][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 252, Cad 98, HR 140, Gear 8, Res 46, Current Pos 13566, Target Pos 13566 + 137926 [656945][E](ERG_Mode): Watts previously processed. + 137927 [657653][E](ERG_Mode): Proportional: -47.250000 + 137928 [658355][E](PTable): Averaged Entry: watts=264.100006, cad=99.500000, targetPosition=1351.300049, (8)(9) + 137929 [658356][E](PTData): Cleaned 278 readings + 137930 [658366][E](PTData): New entry recorded (8)(9)(1351) + 137931 [658367][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137932 [658380][E](PTData): Fit Valid: 1, N: 23, Quad: 1, Time: 1 ms + 137933 [658388][E](PTData): Fit Valid: 1, N: 23, Quad: 1, Time: 2 ms + 137934 [658389][E](PTable): New Entry Processed in 35 ms + 137935 [658389][E](PTable): Power Buffer Reset + 137936 [659062][E](ERG_Mode): Watts previously processed. + 137937 [659662][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 249, Cad 102, HR 143, Gear 8, Res 45, Current Pos 13338, Target Pos 13338 + 137938 [661172][E](ERG_Mode): Watts previously processed. + 137939 [663286][E](ERG_Mode): Proportional: -36.000000 + 137940 [663992][E](ERG_Mode): Watts previously processed. + 137941 [664701][E](PTable): Averaged Entry: watts=258.100006, cad=102.199997, targetPosition=1329.699951, (8)(9) + 137942 [664702][E](PTData): Cleaned 277 readings + 137943 [664713][E](PTData): Existing entry averaged (8)(9)(1343), readings(2) + 137944 [664714][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137945 [664726][E](PTData): Fit Valid: 1, N: 23, Quad: 1, Time: 2 ms + 137946 [664734][E](PTData): Fit Valid: 1, N: 23, Quad: 1, Time: 1 ms + 137947 [664736][E](PTable): New Entry Processed in 35 ms + 137948 [664736][E](PTable): Power Buffer Reset + 137949 [665680][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 258, Cad 103, HR 145, Gear 8, Res 44, Current Pos 13163, Target Pos 13163 + 137950 [666113][E](ERG_Mode): Watts previously processed. + 137951 [668231][E](ERG_Mode): Watts previously processed. + 137952 [668231][E](PTable): Using detected travel limits during homing + 137953 [668932][E](ERG_Mode): Proportional: -81.000000 + 137954 [671062][E](ERG_Mode): Watts previously processed. + 137955 [671697][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 232, Cad 105, HR 148, Gear 8, Res 44, Current Pos 12925, Target Pos 12925 + 137956 [673183][E](ERG_Mode): Watts previously processed. + 137957 [673889][E](PTable): Averaged Entry: watts=249.600006, cad=103.699997, targetPosition=1307.099976, (9)(8) + 137958 [673890][E](PTData): Cleaned 277 readings + 137959 [673900][E](PTData): New entry recorded (9)(8)(1307) + 137960 [673901][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137961 [673914][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 137962 [673922][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 1 ms + 137963 [673924][E](PTable): New Entry Processed in 35 ms + 137964 [673924][E](PTable): Power Buffer Reset + 137965 [673934][E](ERG_Mode): Proportional: 24.750000 + 137966 [676013][E](ERG_Mode): Watts previously processed. + 137967 [677713][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 248, Cad 105, HR 151, Gear 8, Res 44, Current Pos 13003, Target Pos 13003 + 137968 [678125][E](ERG_Mode): Watts previously processed. + 137969 [678933][E](FTMS_SERVER): 05 91 00 -> ERG Mode Target: 145 Current: 248 Incline: 130.000000. Responding: 80 05 01 + 137970 [678940][E](DirConManager): Sending response message type 0x04 to client 0 + 137971 [679532][E](ERG_Mode): SetPoint changed:175w Waiting:1131ms PowerTable Result: 11490 + 137972 [682064][E](ERG_Mode): ERG wait expired, pos: 11490, tgt: 0 + 137973 [682065][E](PTable): Averaged Entry: watts=240.100006, cad=103.900002, targetPosition=1284.900024, (9)(8) + 137974 [682076][E](PTData): Cleaned 276 readings + 137975 [682077][E](PTData): Existing entry averaged (9)(8)(1299), readings(2) + 137976 [682088][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 137977 [682090][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 137978 [682109][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 137979 [682110][E](PTable): New Entry Processed in 45 ms + 137980 [682110][E](PTable): Power Buffer Reset + 137981 [682121][E](ERG_Mode): Proportional: -231.000000 + 137982 [683724][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 165, Cad 102, HR 153, Gear 8, Res 38, Current Pos 11169, Target Pos 11169 + 137983 [684191][E](ERG_Mode): Watts previously processed. + 137984 [686311][E](ERG_Mode): Watts previously processed. + 137985 [687718][E](ERG_Mode): Proportional: 6.000000 + 137986 [688425][E](PTable): Averaged Entry: watts=150.300003, cad=102.400002, targetPosition=1119.300049, (8)(5) + 137987 [688426][E](PTData): Cleaned 276 readings + 137988 [688436][E](PTData): New entry recorded (8)(5)(1119) + 137989 [688437][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 137990 [688448][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 137991 [688450][E](PTData): Fit Valid: 1, N: 25, Quad: 1, Time: 2 ms + 137992 [688469][E](PTData): Fit Valid: 1, N: 25, Quad: 1, Time: 2 ms + 137993 [688470][E](PTable): New Entry Processed in 45 ms + 137994 [688470][E](PTable): Power Buffer Reset + 137995 [689126][E](ERG_Mode): Watts previously processed. + 137996 [689736][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 139, Cad 103, HR 154, Gear 8, Res 38, Current Pos 11210, Target Pos 11210 + 137997 [691954][E](ERG_Mode): Watts previously processed. + 137998 [693366][E](ERG_Mode): Proportional: 33.750000 + 137999 [694075][E](ERG_Mode): Watts previously processed. + 138000 [694784][E](PTable): Averaged Entry: watts=132.100006, cad=101.400002, targetPosition=1127.300049, (8)(4) + 138001 [694785][E](PTData): Cleaned 275 readings + 138002 [694795][E](PTData): New entry recorded (8)(4)(1127) + 138003 [694795][E](PTData): Lower Right Found 8, 5, tp1119 + 138004 [694806][E](PTData): Lower Up Found 7, 4, tp1095 + 138005 [694808][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138006 [694809][E](PTable): New Entry Processed in 26 ms + 138007 [694820][E](PTable): Power Buffer Reset + 138008 [695754][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 134, Cad 99, HR 154, Gear 8, Res 38, Current Pos 11396, Target Pos 11396 + 138009 [696200][E](ERG_Mode): Watts previously processed. + 138010 [698321][E](ERG_Mode): Watts previously processed. + 138011 [699029][E](ERG_Mode): Proportional: 24.750000 + 138012 [701144][E](PTable): Averaged Entry: watts=133.199997, cad=98.699997, targetPosition=1141.800049, (8)(4) + 138013 [701145][E](PTData): Cleaned 1 readings + 138014 [701155][E](PTData): New entry recorded (8)(4)(1141) + 138015 [701155][E](PTData): Lower Up Found 7, 4, tp1095 + 138016 [701158][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138017 [701169][E](PTable): New Entry Processed in 26 ms + 138018 [701169][E](PTable): Power Buffer Reset + 138019 [701169][E](ERG_Mode): Watts previously processed. + 138020 [701766][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 136, Cad 97, HR 154, Gear 8, Res 39, Current Pos 11512, Target Pos 11512 + 138021 [703252][E](ERG_Mode): Watts previously processed. + 138022 [704658][E](ERG_Mode): Proportional: 3.000000 + 138023 [705364][E](ERG_Mode): Watts previously processed. + 138024 [706074][E](PTable): Using detected travel limits during homing + 138025 [707490][E](PTable): Averaged Entry: watts=138.600006, cad=97.500000, targetPosition=1151.900024, (7)(5) + 138026 [707491][E](PTData): Existing entry averaged (7)(5)(1163), readings(6) + 138027 [707503][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138028 [707505][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138029 [707524][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138030 [707525][E](PTable): New Entry Processed in 35 ms + 138031 [707525][E](PTable): Power Buffer Reset + 138032 [707780][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 137, Cad 98, HR 151, Gear 8, Res 39, Current Pos 11541, Target Pos 11541 + 138033 [708194][E](ERG_Mode): Watts previously processed. + 138034 [710312][E](ERG_Mode): Proportional: 2.250000 + 138035 [711019][E](ERG_Mode): Watts previously processed. + 138036 [713136][E](ERG_Mode): Watts previously processed. + 138037 [713794][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 138, Cad 97, HR 147, Gear 8, Res 39, Current Pos 11559, Target Pos 11559 + 138038 [713845][E](PTable): Averaged Entry: watts=138.800003, cad=97.900002, targetPosition=1154.599976, (7)(5) + 138039 [713846][E](PTData): Cleaned 276 readings + 138040 [713857][E](PTData): Existing entry averaged (7)(5)(1161), readings(7) + 138041 [713858][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138042 [713870][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138043 [713879][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138044 [713880][E](PTable): New Entry Processed in 35 ms + 138045 [713880][E](PTable): Power Buffer Reset + 138046 [715252][E](ERG_Mode): Watts previously processed. + 138047 [715961][E](ERG_Mode): Proportional: 6.000000 + 138048 [717376][E](ERG_Mode): Watts previously processed. + 138049 [719494][E](ERG_Mode): Watts previously processed. + 138050 [719812][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 137, Cad 96, HR 144, Gear 8, Res 39, Current Pos 11629, Target Pos 11629 + 138051 [720199][E](PTable): Averaged Entry: watts=136.000000, cad=96.400002, targetPosition=1159.500000, (7)(5) + 138052 [720200][E](PTData): Cleaned 276 readings + 138053 [720210][E](PTData): Existing entry averaged (7)(5)(1160), readings(8) + 138054 [720212][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138055 [720224][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138056 [720232][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 1 ms + 138057 [720234][E](PTable): New Entry Processed in 36 ms + 138058 [720234][E](PTable): Power Buffer Reset + 138059 [720906][E](ERG_Mode): Watts previously processed. + 138060 [721612][E](ERG_Mode): Proportional: 3.000000 + 138061 [723023][E](ERG_Mode): Watts previously processed. + 138062 [725144][E](ERG_Mode): Watts previously processed. + 138063 [725822][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 150, Cad 95, HR 143, Gear 8, Res 39, Current Pos 11692, Target Pos 11692 + 138064 [726550][E](PTable): Averaged Entry: watts=139.399994, cad=95.300003, targetPosition=1165.800049, (7)(5) + 138065 [726552][E](PTData): Cleaned 276 readings + 138066 [726562][E](PTData): Existing entry averaged (7)(5)(1160), readings(9) + 138067 [726563][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138068 [726575][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 1 ms + 138069 [726584][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138070 [726586][E](PTable): New Entry Processed in 35 ms + 138071 [726586][E](PTable): Power Buffer Reset + 138072 [727258][E](ERG_Mode): Watts previously processed. + 138073 [727960][E](ERG_Mode): Proportional: 2.250000 + 138074 [729375][E](ERG_Mode): Watts previously processed. + 138075 [731830][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 154, Cad 95, HR 141, Gear 8, Res 39, Current Pos 11716, Target Pos 11716 + 138076 [732912][E](PTable): Averaged Entry: watts=143.199997, cad=95.300003, targetPosition=1169.900024, (7)(5) + 138077 [732913][E](PTData): Cleaned 276 readings + 138078 [732924][E](PTData): Existing entry averaged (7)(5)(1160), readings(10) + 138079 [732925][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138080 [732937][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138081 [732946][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138082 [732947][E](PTable): New Entry Processed in 35 ms + 138083 [733075][E](PTable): Writing File: /PowerTable.txt + 138084 [733310][E](PTable): Power table saved successfully with 393 readings + 138085 [733311][E](PTable): Power Buffer Reset + 138086 [733311][E](ERG_Mode): Watts previously processed. + 138087 [733614][E](ERG_Mode): Proportional: -1.500000 + 138088 [734324][E](ERG_Mode): Watts previously processed. + 138089 [736435][E](ERG_Mode): Watts previously processed. + 138090 [737841][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 144, Cad 95, HR 138, Gear 8, Res 39, Current Pos 11721, Target Pos 11721 + 138091 [739126][E](FTMS_SERVER): 05 aa 00 -> ERG Mode Target: 170 Current: 140 Incline: 117.150002. Responding: 80 05 01 + 138092 [739131][E](DirConManager): Sending response message type 0x04 to client 0 + 138093 [739256][E](PTable): Averaged Entry: watts=144.199997, cad=96.199997, targetPosition=1171.199951, (7)(5) + 138094 [739257][E](PTData): Cleaned 276 readings + 138095 [739267][E](PTData): Existing entry averaged (7)(5)(1160), readings(11) + 138096 [739268][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138097 [739281][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138098 [739289][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 1 ms + 138099 [739290][E](PTable): New Entry Processed in 34 ms + 138100 [739291][E](PTable): Power Buffer Reset + 138101 [739301][E](ERG_Mode): SetPoint changed:140w Waiting:876ms PowerTable Result: 11100 + 138102 [741534][E](ERG_Mode): ERG wait expired, pos: 11100, tgt: 0 + 138103 [741535][E](ERG_Mode): Proportional: 63.000000 + 138104 [742950][E](ERG_Mode): Watts previously processed. + 138105 [743657][E](PTable): Using detected travel limits during homing + 138106 [743854][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 129, Cad 98, HR 137, Gear 8, Res 38, Current Pos 11297, Target Pos 11329 + 138107 [745066][E](ERG_Mode): Watts previously processed. + 138108 [747181][E](PTable): Averaged Entry: watts=134.500000, cad=97.400002, targetPosition=1130.300049, (7)(4) + 138109 [747183][E](PTData): Cleaned 276 readings + 138110 [747193][E](PTData): Existing entry averaged (7)(4)(1102), readings(4) + 138111 [747194][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138112 [747207][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138113 [747215][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138114 [747216][E](PTable): New Entry Processed in 35 ms + 138115 [747217][E](PTable): Power Buffer Reset + 138116 [747227][E](ERG_Mode): Watts previously processed. + 138117 [747888][E](ERG_Mode): Proportional: 69.750000 + 138118 [749869][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 132, Cad 97, HR 136, Gear 8, Res 40, Current Pos 11820, Target Pos 11820 + 138119 [750000][E](ERG_Mode): Watts previously processed. + 138120 [752115][E](ERG_Mode): Watts previously processed. + 138121 [753532][E](PTable): Averaged Entry: watts=137.300003, cad=96.199997, targetPosition=1180.900024, (7)(5) + 138122 [753533][E](PTData): Cleaned 276 readings + 138123 [753544][E](PTData): Existing entry averaged (7)(5)(1161), readings(12) + 138124 [753545][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138125 [753557][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138126 [753566][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138127 [753567][E](PTable): New Entry Processed in 35 ms + 138128 [753567][E](PTable): Power Buffer Reset + 138129 [753578][E](ERG_Mode): Proportional: 42.750000 + 138130 [754240][E](ERG_Mode): Watts previously processed. + 138131 [755879][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 154, Cad 94, HR 134, Gear 8, Res 41, Current Pos 12177, Target Pos 12177 + 138132 [757078][E](ERG_Mode): Watts previously processed. + 138133 [759201][E](ERG_Mode): Watts previously processed. + 138134 [759908][E](PTable): Averaged Entry: watts=155.600006, cad=94.900002, targetPosition=1215.599976, (7)(5) + 138135 [759909][E](PTData): Cleaned 276 readings + 138136 [759919][E](PTData): Existing entry averaged (7)(5)(1164), readings(13) + 138137 [759920][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138138 [759933][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138139 [759941][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 1 ms + 138140 [759943][E](PTable): New Entry Processed in 36 ms + 138141 [759943][E](PTable): Power Buffer Reset + 138142 [759953][E](ERG_Mode): Proportional: 27.000000 + 138143 [761313][E](ERG_Mode): Watts previously processed. + 138144 [761890][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 134, Cad 95, HR 132, Gear 8, Res 41, Current Pos 12250, Target Pos 12250 + 138145 [764132][E](ERG_Mode): Watts previously processed. + 138146 [765543][E](ERG_Mode): Proportional: 36.000000 + 138147 [766248][E](PTable): Averaged Entry: watts=152.600006, cad=92.699997, targetPosition=1235.599976, (6)(5) + 138148 [766249][E](PTData): Cleaned 276 readings + 138149 [766259][E](PTData): Existing entry averaged (6)(5)(1192), readings(16) + 138150 [766260][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138151 [766273][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138152 [766281][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 1 ms + 138153 [766283][E](PTable): New Entry Processed in 36 ms + 138154 [766283][E](PTable): Power Buffer Reset + 138155 [766293][E](ERG_Mode): Watts previously processed. + 138156 [767910][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 163, Cad 90, HR 131, Gear 8, Res 42, Current Pos 12555, Target Pos 12555 + 138157 [768362][E](ERG_Mode): Watts previously processed. + 138158 [770476][E](ERG_Mode): Watts previously processed. + 138159 [771178][E](ERG_Mode): Proportional: 0.000000 + 138160 [772588][E](PTable): Averaged Entry: watts=162.300003, cad=89.900002, targetPosition=1255.199951, (6)(5) + 138161 [772589][E](PTData): Cleaned 276 readings + 138162 [772600][E](PTData): Existing entry averaged (6)(5)(1195), readings(17) + 138163 [772601][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138164 [772613][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138165 [772622][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138166 [772623][E](PTable): New Entry Processed in 35 ms + 138167 [772623][E](PTable): Power Buffer Reset + 138168 [773925][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 161, Cad 89, HR 131, Gear 8, Res 42, Current Pos 12606, Target Pos 12606 + 138169 [774007][E](ERG_Mode): Watts previously processed. + 138170 [776126][E](ERG_Mode): Watts previously processed. + 138171 [776833][E](ERG_Mode): Proportional: -33.750000 + 138172 [777133][E](BLE_Server): MTU updated: 515 for connection ID: 0 + 138173 [778241][E](ERG_Mode): Watts previously processed. + 138174 [778955][E](PTable): Averaged Entry: watts=174.100006, cad=90.800003, targetPosition=1259.099976, (6)(6) + 138175 [778956][E](PTData): Cleaned 276 readings + 138176 [778967][E](PTData): Existing entry averaged (6)(6)(1256), readings(3) + 138177 [778968][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138178 [778980][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138179 [778989][E](PTData): Fit Valid: 1, N: 24, Quad: 1, Time: 2 ms + 138180 [778991][E](PTable): New Entry Processed in 36 ms + 138181 [778991][E](PTable): Power Buffer Reset + 138182 [779663][E](PTable): Using detected travel limits during homing + 138183 [779934][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 170, Cad 94, HR 132, Gear 8, Res 42, Current Pos 12509, Target Pos 12509 + 138184 [780371][E](ERG_Mode): Watts previously processed. + 138185 [782492][E](ERG_Mode): Proportional: -22.500000 + 138186 [783899][E](ERG_Mode): Watts previously processed. + 138187 [785310][E](PTable): Averaged Entry: watts=174.100006, cad=93.699997, targetPosition=1246.400024, (7)(6) + 138188 [785311][E](PTData): Cleaned 276 readings + 138189 [785321][E](PTData): New entry recorded (7)(6)(1246) + 138190 [785322][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138191 [785335][E](PTData): Fit Valid: 1, N: 25, Quad: 1, Time: 2 ms + 138192 [785343][E](PTData): Fit Valid: 1, N: 25, Quad: 1, Time: 1 ms + 138193 [785345][E](PTable): New Entry Processed in 36 ms + 138194 [785345][E](PTable): Power Buffer Reset + 138195 [785946][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 166, Cad 91, HR 133, Gear 8, Res 42, Current Pos 12434, Target Pos 12434 + 138196 [786018][E](ERG_Mode): Watts previously processed. + 138197 [788138][E](ERG_Mode): Watts previously processed. + 138198 [788845][E](ERG_Mode): Proportional: 0.750000 + 138199 [790254][E](ERG_Mode): Watts previously processed. + 138200 [791677][E](PTable): Averaged Entry: watts=168.899994, cad=91.500000, targetPosition=1242.900024, (6)(6) + 138201 [791678][E](PTData): Cleaned 275 readings + 138202 [791688][E](PTData): Existing entry averaged (6)(6)(1253), readings(4) + 138203 [791689][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138204 [791702][E](PTData): Fit Valid: 1, N: 25, Quad: 1, Time: 2 ms + 138205 [791710][E](PTData): Fit Valid: 1, N: 25, Quad: 1, Time: 1 ms + 138206 [791712][E](PTable): New Entry Processed in 36 ms + 138207 [791712][E](PTable): Power Buffer Reset + 138208 [791964][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 165, Cad 92, HR 133, Gear 8, Res 42, Current Pos 12432, Target Pos 12432 + 138209 [792385][E](ERG_Mode): Watts previously processed. + 138210 [793186][E](BLE_Server): MTU updated: 515 for connection ID: 0 + 138211 [794504][E](ERG_Mode): Proportional: -45.000000 + 138212 [795212][E](ERG_Mode): Watts previously processed. + 138213 [797978][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 170, Cad 91, HR 133, Gear 8, Res 42, Current Pos 12399, Target Pos 12399 + 138214 [798040][E](PTable): Averaged Entry: watts=172.800003, cad=92.000000, targetPosition=1239.000000, (6)(6) + 138215 [798041][E](PTData): Cleaned 275 readings + 138216 [798051][E](PTData): Existing entry averaged (6)(6)(1250), readings(5) + 138217 [798052][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138218 [798065][E](PTData): Fit Valid: 1, N: 25, Quad: 1, Time: 2 ms + 138219 [798073][E](PTData): Fit Valid: 1, N: 25, Quad: 1, Time: 2 ms + 138220 [798075][E](PTable): New Entry Processed in 35 ms + 138221 [798075][E](PTable): Power Buffer Reset + 138222 [798086][E](ERG_Mode): Watts previously processed. + 138223 [799007][E](FTMS_SERVER): 05 b9 00 -> ERG Mode Target: 185 Current: 166 Incline: 124.019997. Responding: 80 05 01 + 138224 [799012][E](DirConManager): Sending response message type 0x04 to client 0 + 138225 [800157][E](ERG_Mode): Watts previously processed. + 138226 [800867][E](ERG_Mode): Proportional: 33.750000 + 138227 [802279][E](ERG_Mode): Watts previously processed. + 138228 [803988][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 168, Cad 91, HR 134, Gear 8, Res 42, Current Pos 12597, Target Pos 12597 + 138229 [804403][E](PTable): Averaged Entry: watts=167.000000, cad=91.400002, targetPosition=1246.900024, (6)(6) + 138230 [804404][E](PTData): Cleaned 275 readings + 138231 [804414][E](PTData): Existing entry averaged (6)(6)(1249), readings(6) + 138232 [804415][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138233 [804428][E](PTData): Fit Valid: 1, N: 25, Quad: 1, Time: 2 ms + 138234 [804437][E](PTData): Fit Valid: 1, N: 25, Quad: 1, Time: 2 ms + 138235 [804438][E](PTable): New Entry Processed in 35 ms + 138236 [804438][E](PTable): Power Buffer Reset + 138237 [804449][E](ERG_Mode): Watts previously processed. + 138238 [806533][E](ERG_Mode): Proportional: 31.500000 + 138239 [807939][E](ERG_Mode): Watts previously processed. + 138240 [810005][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 169, Cad 90, HR 135, Gear 8, Res 43, Current Pos 12798, Target Pos 12798 + 138241 [810056][E](ERG_Mode): Watts previously processed. + 138242 [810763][E](PTable): Averaged Entry: watts=171.000000, cad=91.099998, targetPosition=1269.099976, (6)(6) + 138243 [810764][E](PTData): Cleaned 275 readings + 138244 [810774][E](PTData): Existing entry averaged (6)(6)(1251), readings(7) + 138245 [810775][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138246 [810788][E](PTData): Fit Valid: 1, N: 25, Quad: 1, Time: 2 ms + 138247 [810796][E](PTData): Fit Valid: 1, N: 25, Quad: 1, Time: 1 ms + 138248 [810798][E](PTable): New Entry Processed in 36 ms + 138249 [810798][E](PTable): Power Buffer Reset + 138250 [812171][E](ERG_Mode): Watts previously processed. + 138251 [812879][E](ERG_Mode): Proportional: 5.250000 + 138252 [814286][E](ERG_Mode): Watts previously processed. + 138253 [815701][E](PTable): Using detected travel limits during homing + 138254 [816022][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 175, Cad 90, HR 135, Gear 8, Res 43, Current Pos 12845, Target Pos 12845 + 138255 [816407][E](ERG_Mode): Watts previously processed. + 138256 [817115][E](PTable): Averaged Entry: watts=176.300003, cad=90.400002, targetPosition=1281.300049, (6)(6) + 138257 [817116][E](PTData): Cleaned 275 readings + 138258 [817126][E](PTData): Existing entry averaged (6)(6)(1254), readings(8) + 138259 [817128][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138260 [817140][E](PTData): Fit Valid: 1, N: 25, Quad: 1, Time: 2 ms + 138261 [817149][E](PTData): Fit Valid: 1, N: 25, Quad: 1, Time: 2 ms + 138262 [817150][E](PTable): New Entry Processed in 35 ms + 138263 [817150][E](PTable): Power Buffer Reset + 138264 [818529][E](ERG_Mode): Proportional: 24.750000 + 138265 [819234][E](ERG_Mode): Watts previously processed. + 138266 [821342][E](ERG_Mode): Watts previously processed. + 138267 [822041][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 183, Cad 89, HR 135, Gear 8, Res 44, Current Pos 12984, Target Pos 12984 + 138268 [823468][E](PTable): Averaged Entry: watts=175.500000, cad=88.900002, targetPosition=1294.900024, (6)(6) + 138269 [823469][E](PTData): Cleaned 275 readings + 138270 [823480][E](PTData): Existing entry averaged (6)(6)(1258), readings(9) + 138271 [823481][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138272 [823493][E](PTData): Fit Valid: 1, N: 25, Quad: 1, Time: 2 ms + 138273 [823502][E](PTData): Fit Valid: 1, N: 25, Quad: 1, Time: 2 ms + 138274 [823503][E](PTable): New Entry Processed in 35 ms + 138275 [823503][E](PTable): Power Buffer Reset + 138276 [824173][E](ERG_Mode): Watts previously processed. + 138277 [824881][E](ERG_Mode): Proportional: 6.000000 + 138278 [826295][E](ERG_Mode): Watts previously processed. + 138279 [828058][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 177, Cad 87, HR 136, Gear 8, Res 44, Current Pos 13056, Target Pos 13056 + 138280 [829116][E](ERG_Mode): Watts previously processed. + 138281 [829824][E](PTable): Averaged Entry: watts=177.199997, cad=87.900002, targetPosition=1302.199951, (5)(6) + 138282 [829826][E](PTData): Cleaned 275 readings + 138283 [829836][E](PTData): New entry recorded (5)(6)(1302) + 138284 [829837][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138285 [829849][E](PTData): Fit Valid: 1, N: 26, Quad: 1, Time: 2 ms + 138286 [829858][E](PTData): Fit Valid: 1, N: 26, Quad: 1, Time: 2 ms + 138287 [829860][E](PTable): New Entry Processed in 37 ms + 138288 [829860][E](PTable): Power Buffer Reset + 138289 [830527][E](ERG_Mode): Proportional: -3.000000 + 138290 [831235][E](ERG_Mode): Watts previously processed. + 138291 [833350][E](ERG_Mode): Watts previously processed. + 138292 [834068][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 187, Cad 89, HR 139, Gear 8, Res 44, Current Pos 13053, Target Pos 13051 + 138293 [836171][E](PTable): Averaged Entry: watts=186.600006, cad=89.000000, targetPosition=1304.800049, (6)(6) + 138294 [836172][E](PTData): Cleaned 274 readings + 138295 [836183][E](PTData): Existing entry averaged (6)(6)(1262), readings(10) + 138296 [836184][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138297 [836196][E](PTData): Fit Valid: 1, N: 26, Quad: 1, Time: 2 ms + 138298 [836205][E](PTData): Fit Valid: 1, N: 26, Quad: 1, Time: 2 ms + 138299 [836206][E](PTable): New Entry Processed in 35 ms + 138300 [836207][E](PTable): Power Buffer Reset + 138301 [836217][E](ERG_Mode): Watts previously processed. + 138302 [836880][E](ERG_Mode): Proportional: 3.000000 + 138303 [838285][E](ERG_Mode): Watts previously processed. + 138304 [840079][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 190, Cad 89, HR 139, Gear 8, Res 44, Current Pos 13072, Target Pos 13072 + 138305 [841113][E](ERG_Mode): Watts previously processed. + 138306 [842528][E](PTable): Averaged Entry: watts=181.699997, cad=88.800003, targetPosition=1306.199951, (6)(6) + 138307 [842529][E](PTData): Cleaned 274 readings + 138308 [842539][E](PTData): Existing entry averaged (6)(6)(1265), readings(11) + 138309 [842540][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138310 [842553][E](PTData): Fit Valid: 1, N: 26, Quad: 1, Time: 2 ms + 138311 [842561][E](PTData): Fit Valid: 1, N: 26, Quad: 1, Time: 1 ms + 138312 [842563][E](PTable): New Entry Processed in 36 ms + 138313 [842563][E](PTable): Power Buffer Reset + 138314 [842574][E](ERG_Mode): Proportional: 4.500000 + 138315 [843235][E](ERG_Mode): Watts previously processed. + 138316 [845345][E](ERG_Mode): Watts previously processed. + 138317 [846090][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 180, Cad 87, HR 140, Gear 8, Res 44, Current Pos 13110, Target Pos 13110 + 138318 [847463][E](ERG_Mode): Watts previously processed. + 138319 [848170][E](ERG_Mode): Proportional: -0.750000 + 138320 [848878][E](PTable): Averaged Entry: watts=182.500000, cad=87.699997, targetPosition=1310.099976, (5)(6) + 138321 [848879][E](PTData): Cleaned 274 readings + 138322 [848889][E](PTData): Existing entry averaged (5)(6)(1304), readings(2) + 138323 [848890][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138324 [848903][E](PTData): Fit Valid: 1, N: 26, Quad: 1, Time: 2 ms + 138325 [848912][E](PTData): Fit Valid: 1, N: 26, Quad: 1, Time: 2 ms + 138326 [848913][E](PTable): New Entry Processed in 36 ms + 138327 [848913][E](PTable): Power Buffer Reset + 138328 [850292][E](ERG_Mode): Watts previously processed. + 138329 [851710][E](PTable): Using detected travel limits during homing + 138330 [852102][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 186, Cad 90, HR 141, Gear 8, Res 44, Current Pos 13024, Target Pos 13024 + 138331 [853126][E](ERG_Mode): Watts previously processed. + 138332 [853835][E](ERG_Mode): Proportional: 3.750000 + 138333 [855248][E](PTable): Averaged Entry: watts=183.399994, cad=89.400002, targetPosition=1303.400024, (6)(6) + 138334 [855249][E](PTData): Cleaned 274 readings + 138335 [855259][E](PTData): Existing entry averaged (6)(6)(1267), readings(12) + 138336 [855260][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138337 [855273][E](PTData): Fit Valid: 1, N: 26, Quad: 1, Time: 2 ms + 138338 [855281][E](PTData): Fit Valid: 1, N: 26, Quad: 1, Time: 1 ms + 138339 [855283][E](PTable): New Entry Processed in 36 ms + 138340 [855283][E](PTable): Power Buffer Reset + 138341 [855293][E](ERG_Mode): Watts previously processed. + 138342 [857366][E](ERG_Mode): Watts previously processed. + 138343 [858116][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 180, Cad 88, HR 140, Gear 8, Res 44, Current Pos 13081, Target Pos 13081 + 138344 [859020][E](FTMS_SERVER): 05 c8 00 -> ERG Mode Target: 200 Current: 180 Incline: 130.839996. Responding: 80 05 01 + 138345 [859024][E](DirConManager): Sending response message type 0x04 to client 0 + 138346 [859492][E](ERG_Mode): Proportional: 45.000000 + 138347 [861621][E](PTable): Averaged Entry: watts=183.600006, cad=88.099998, targetPosition=1309.599976, (6)(6) + 138348 [861623][E](PTData): Cleaned 274 readings + 138349 [861633][E](PTData): Existing entry averaged (6)(6)(1270), readings(13) + 138350 [861634][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138351 [861647][E](PTData): Fit Valid: 1, N: 26, Quad: 1, Time: 2 ms + 138352 [861656][E](PTData): Fit Valid: 1, N: 26, Quad: 1, Time: 2 ms + 138353 [861657][E](PTable): New Entry Processed in 36 ms + 138354 [861657][E](PTable): Power Buffer Reset + 138355 [862328][E](ERG_Mode): Watts previously processed. + 138356 [864125][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 199, Cad 90, HR 140, Gear 8, Res 44, Current Pos 13186, Target Pos 13186 + 138357 [865159][E](ERG_Mode): Watts previously processed. + 138358 [865869][E](ERG_Mode): Proportional: 0.000000 + 138359 [867276][E](ERG_Mode): Watts previously processed. + 138360 [867987][E](PTable): Averaged Entry: watts=200.399994, cad=91.300003, targetPosition=1317.699951, (6)(7) + 138361 [867988][E](PTData): Cleaned 274 readings + 138362 [867998][E](PTData): New entry recorded (6)(7)(1317) + 138363 [867999][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138364 [868012][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138365 [868021][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138366 [868022][E](PTable): New Entry Processed in 35 ms + 138367 [868022][E](PTable): Power Buffer Reset + 138368 [869395][E](ERG_Mode): Watts previously processed. + 138369 [870135][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 200, Cad 91, HR 139, Gear 8, Res 44, Current Pos 13182, Target Pos 13182 + 138370 [871515][E](ERG_Mode): Watts previously processed. + 138371 [872224][E](ERG_Mode): Proportional: -0.750000 + 138372 [874343][E](PTable): Averaged Entry: watts=198.000000, cad=91.000000, targetPosition=1317.699951, (6)(7) + 138373 [874344][E](PTData): Cleaned 273 readings + 138374 [874354][E](PTData): Existing entry averaged (6)(7)(1317), readings(2) + 138375 [874355][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138376 [874368][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138377 [874377][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138378 [874378][E](PTable): New Entry Processed in 36 ms + 138379 [874378][E](PTable): Power Buffer Reset + 138380 [874389][E](ERG_Mode): Watts previously processed. + 138381 [876144][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 198, Cad 90, HR 140, Gear 8, Res 44, Current Pos 13189, Target Pos 13189 + 138382 [876470][E](ERG_Mode): Watts previously processed. + 138383 [877882][E](ERG_Mode): Proportional: -3.000000 + 138384 [879298][E](ERG_Mode): Watts previously processed. + 138385 [880712][E](PTable): Averaged Entry: watts=196.600006, cad=90.500000, targetPosition=1318.500000, (6)(7) + 138386 [880714][E](PTData): Cleaned 273 readings + 138387 [880724][E](PTData): Existing entry averaged (6)(7)(1317), readings(3) + 138388 [880725][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138389 [880738][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138390 [880747][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138391 [880748][E](PTable): New Entry Processed in 36 ms + 138392 [880748][E](PTable): Power Buffer Reset + 138393 [881419][E](ERG_Mode): Watts previously processed. + 138394 [882161][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 199, Cad 91, HR 141, Gear 8, Res 44, Current Pos 13198, Target Pos 13198 + 138395 [883541][E](ERG_Mode): Watts previously processed. + 138396 [884243][E](ERG_Mode): Proportional: -1.500000 + 138397 [885656][E](ERG_Mode): Watts previously processed. + 138398 [887060][E](PTable): Averaged Entry: watts=201.699997, cad=91.400002, targetPosition=1318.900024, (6)(7) + 138399 [887062][E](PTData): Cleaned 273 readings + 138400 [887072][E](PTData): Existing entry averaged (6)(7)(1317), readings(4) + 138401 [887073][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138402 [887086][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 3 ms + 138403 [887094][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138404 [887095][E](PTable): New Entry Processed in 35 ms + 138405 [887096][E](PTable): Power Buffer Reset + 138406 [887106][E](ERG_Mode): Watts previously processed. + 138407 [887778][E](PTable): Using detected travel limits during homing + 138408 [888171][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 200, Cad 92, HR 141, Gear 8, Res 44, Current Pos 13187, Target Pos 13187 + 138409 [889183][E](ERG_Mode): Watts previously processed. + 138410 [889893][E](ERG_Mode): Proportional: 4.500000 + 138411 [891305][E](ERG_Mode): Watts previously processed. + 138412 [893422][E](PTable): Averaged Entry: watts=200.199997, cad=91.900002, targetPosition=1317.900024, (6)(7) + 138413 [893423][E](PTData): Cleaned 273 readings + 138414 [893433][E](PTData): Existing entry averaged (6)(7)(1317), readings(5) + 138415 [893435][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138416 [893447][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138417 [893456][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138418 [893457][E](PTable): New Entry Processed in 35 ms + 138419 [893457][E](PTable): Power Buffer Reset + 138420 [893468][E](ERG_Mode): Watts previously processed. + 138421 [894184][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 200, Cad 91, HR 142, Gear 8, Res 44, Current Pos 13184, Target Pos 13184 + 138422 [895537][E](ERG_Mode): Watts previously processed. + 138423 [896247][E](ERG_Mode): Proportional: -31.500000 + 138424 [897034][E](BLE_Server): MTU updated: 515 for connection ID: 0 + 138425 [897664][E](ERG_Mode): Watts previously processed. + 138426 [899079][E](ERG_Mode): Watts previously processed. + 138427 [899788][E](PTable): Averaged Entry: watts=210.399994, cad=93.300003, targetPosition=1312.900024, (7)(7) + 138428 [899789][E](PTData): Cleaned 273 readings + 138429 [899799][E](PTData): Existing entry averaged (7)(7)(1289), readings(3) + 138430 [899800][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138431 [899813][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138432 [899822][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138433 [899823][E](PTable): New Entry Processed in 35 ms + 138434 [899823][E](PTable): Power Buffer Reset + 138435 [900200][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 216, Cad 95, HR 143, Gear 8, Res 44, Current Pos 13030, Target Pos 13030 + 138436 [900863][E](Config): Writing File: /config.txt + 138437 [901197][E](ERG_Mode): Watts previously processed. + 138438 [901905][E](ERG_Mode): Proportional: -36.000000 + 138439 [903316][E](ERG_Mode): Watts previously processed. + 138440 [905144][E](BLE_Server): MTU updated: 515 for connection ID: 0 + 138441 [905434][E](ERG_Mode): Watts previously processed. + 138442 [906135][E](PTable): Averaged Entry: watts=211.699997, cad=95.599998, targetPosition=1293.599976, (7)(7) + 138443 [906136][E](PTData): Cleaned 273 readings + 138444 [906146][E](PTData): Existing entry averaged (7)(7)(1289), readings(4) + 138445 [906147][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138446 [906160][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138447 [906169][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138448 [906170][E](PTable): New Entry Processed in 36 ms + 138449 [906170][E](PTable): Power Buffer Reset + 138450 [906210][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 200, Cad 97, HR 145, Gear 8, Res 43, Current Pos 12800, Target Pos 12800 + 138451 [907546][E](ERG_Mode): Proportional: -9.000000 + 138452 [908253][E](ERG_Mode): Watts previously processed. + 138453 [910369][E](ERG_Mode): Watts previously processed. + 138454 [912223][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 183, Cad 94, HR 144, Gear 8, Res 43, Current Pos 12890, Target Pos 12890 + 138455 [912491][E](PTable): Averaged Entry: watts=197.000000, cad=95.900002, targetPosition=1280.500000, (7)(7) + 138456 [912492][E](PTData): Cleaned 273 readings + 138457 [912503][E](PTData): Existing entry averaged (7)(7)(1287), readings(5) + 138458 [912504][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138459 [912516][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138460 [912525][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138461 [912527][E](PTable): New Entry Processed in 35 ms + 138462 [912527][E](PTable): Power Buffer Reset + 138463 [913200][E](ERG_Mode): Watts previously processed. + 138464 [913906][E](ERG_Mode): Proportional: 33.000000 + 138465 [915320][E](ERG_Mode): Watts previously processed. + 138466 [918150][E](ERG_Mode): Watts previously processed. + 138467 [918255][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 188, Cad 93, HR 144, Gear 8, Res 44, Current Pos 12983, Target Pos 12983 + 138468 [918860][E](PTable): Averaged Entry: watts=193.800003, cad=93.300003, targetPosition=1297.000000, (7)(6) + 138469 [918861][E](PTData): Cleaned 273 readings + 138470 [918871][E](PTData): Existing entry averaged (7)(6)(1263), readings(2) + 138471 [918872][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138472 [918885][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138473 [918894][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138474 [918895][E](PTable): New Entry Processed in 36 ms + 138475 [918895][E](PTable): Power Buffer Reset + 138476 [919030][E](FTMS_SERVER): 05 d7 00 -> ERG Mode Target: 215 Current: 188 Incline: 130.190002. Responding: 80 05 01 + 138477 [919037][E](DirConManager): Sending response message type 0x04 to client 0 + 138478 [919563][E](ERG_Mode): Proportional: 87.000000 + 138479 [920271][E](ERG_Mode): Watts previously processed. + 138480 [922391][E](ERG_Mode): Watts previously processed. + 138481 [923805][E](PTable): Using detected travel limits during homing + 138482 [924271][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 208, Cad 93, HR 146, Gear 8, Res 45, Current Pos 13272, Target Pos 13272 + 138483 [924513][E](ERG_Mode): Watts previously processed. + 138484 [925215][E](PTable): Averaged Entry: watts=197.300003, cad=92.800003, targetPosition=1317.199951, (6)(7) + 138485 [925216][E](PTData): Cleaned 273 readings + 138486 [925226][E](PTData): Existing entry averaged (6)(7)(1317), readings(6) + 138487 [925228][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138488 [925240][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138489 [925249][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138490 [925250][E](PTable): New Entry Processed in 35 ms + 138491 [925250][E](PTable): Power Buffer Reset + 138492 [925261][E](ERG_Mode): Proportional: -5.000000 + 138493 [926620][E](ERG_Mode): Watts previously processed. + 138494 [930155][E](ERG_Mode): Watts previously processed. + 138495 [930286][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 204, Cad 93, HR 145, Gear 8, Res 45, Current Pos 13305, Target Pos 13305 + 138496 [930865][E](ERG_Mode): Proportional: 33.000000 + 138497 [931573][E](PTable): Averaged Entry: watts=211.199997, cad=93.699997, targetPosition=1327.599976, (7)(7) + 138498 [931574][E](PTData): Cleaned 273 readings + 138499 [931585][E](PTData): Existing entry averaged (7)(7)(1292), readings(6) + 138500 [931586][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138501 [931598][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138502 [931608][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 3 ms + 138503 [931609][E](PTable): New Entry Processed in 37 ms + 138504 [931609][E](PTable): Power Buffer Reset + 138505 [932281][E](ERG_Mode): Watts previously processed. + 138506 [934393][E](ERG_Mode): Watts previously processed. + 138507 [936300][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 211, Cad 93, HR 145, Gear 8, Res 45, Current Pos 13362, Target Pos 13362 + 138508 [936512][E](ERG_Mode): Watts previously processed. + 138509 [937221][E](ERG_Mode): Proportional: 3.000000 + 138510 [937923][E](PTable): Averaged Entry: watts=210.300003, cad=92.800003, targetPosition=1337.000000, (6)(7) + 138511 [937924][E](PTData): Cleaned 273 readings + 138512 [937934][E](PTData): Existing entry averaged (6)(7)(1319), readings(7) + 138513 [937936][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138514 [937948][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138515 [937957][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138516 [937958][E](PTable): New Entry Processed in 36 ms + 138517 [937959][E](PTable): Power Buffer Reset + 138518 [938631][E](ERG_Mode): Watts previously processed. + 138519 [942155][E](ERG_Mode): Watts previously processed. + 138520 [942317][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 219, Cad 93, HR 146, Gear 8, Res 45, Current Pos 13359, Target Pos 13359 + 138521 [942865][E](ERG_Mode): Proportional: -5.000000 + 138522 [944271][E](PTable): Averaged Entry: watts=216.100006, cad=93.500000, targetPosition=1335.599976, (7)(7) + 138523 [944272][E](PTData): Cleaned 273 readings + 138524 [944282][E](PTData): Existing entry averaged (7)(7)(1297), readings(7) + 138525 [944283][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138526 [944296][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138527 [944305][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138528 [944306][E](PTable): New Entry Processed in 36 ms + 138529 [944306][E](PTable): Power Buffer Reset + 138530 [944317][E](ERG_Mode): Watts previously processed. + 138531 [946397][E](ERG_Mode): Watts previously processed. + 138532 [948330][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 130, Cad 84, HR 146, Gear 8, Res 46, Current Pos 13777, Target Pos 13807 + 138533 [948511][E](ERG_Mode): Watts previously processed. + 138534 [949220][E](ERG_Mode): Proportional: 292.000000 + 138535 [950633][E](PTable): Averaged Entry: watts=171.100006, cad=85.599998, targetPosition=1363.199951, (5)(6) + 138536 [950634][E](PTData): Cleaned 273 readings + 138537 [950644][E](PTData): Existing entry averaged (5)(6)(1318), readings(3) + 138538 [950645][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138539 [950658][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138540 [950667][E](PTData): Fit Valid: 1, N: 27, Quad: 1, Time: 2 ms + 138541 [950668][E](PTable): New Entry Processed in 36 ms + 138542 [950668][E](PTable): Power Buffer Reset + 138543 [950679][E](ERG_Mode): Watts previously processed. + 138544 [952039][E](ERG_Mode): Watts previously processed. + 138545 [954159][E](ERG_Mode): Watts previously processed. + 138546 [954341][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 193, Cad 74, HR 145, Gear 8, Res 50, Current Pos 14709, Target Pos 14709 + 138547 [954869][E](ERG_Mode): Proportional: 66.000000 + 138548 [956273][E](ERG_Mode): Watts previously processed. + 138549 [956975][E](PTable): Averaged Entry: watts=184.300003, cad=74.599998, targetPosition=1462.900024, (3)(6) + 138550 [956976][E](PTData): Cleaned 273 readings + 138551 [956986][E](PTData): New entry recorded (3)(6)(1462) + 138552 [956987][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138553 [957000][E](PTData): Fit Valid: 1, N: 28, Quad: 1, Time: 2 ms + 138554 [957009][E](PTData): Fit Valid: 1, N: 28, Quad: 1, Time: 2 ms + 138555 [957011][E](PTable): New Entry Processed in 36 ms + 138556 [957011][E](PTable): Power Buffer Reset + 138557 [958379][E](ERG_Mode): Watts previously processed. + 138558 [959793][E](PTable): Using detected travel limits during homing + 138559 [960352][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 186, Cad 73, HR 143, Gear 8, Res 51, Current Pos 15195, Target Pos 15195 + 138560 [960503][E](ERG_Mode): Watts previously processed. + 138561 [961204][E](ERG_Mode): Proportional: 57.000000 + 138562 [963323][E](PTable): Averaged Entry: watts=186.899994, cad=72.199997, targetPosition=1515.599976, (2)(6) + 138563 [963325][E](PTData): Cleaned 272 readings + 138564 [963335][E](PTData): New entry recorded (2)(6)(1515) + 138565 [963336][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138566 [963349][E](PTData): Fit Valid: 1, N: 29, Quad: 1, Time: 2 ms + 138567 [963358][E](PTData): Fit Valid: 1, N: 29, Quad: 1, Time: 2 ms + 138568 [963359][E](PTable): New Entry Processed in 36 ms + 138569 [963359][E](PTable): Power Buffer Reset + 138570 [963370][E](ERG_Mode): Watts previously processed. + 138571 [966157][E](ERG_Mode): Watts previously processed. + 138572 [966368][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 207, Cad 70, HR 141, Gear 8, Res 53, Current Pos 15564, Target Pos 15564 + 138573 [966866][E](ERG_Mode): Proportional: 7.000000 + 138574 [968270][E](ERG_Mode): Watts previously processed. + 138575 [969686][E](PTable): Averaged Entry: watts=203.899994, cad=69.900002, targetPosition=1556.099976, (2)(7) + 138576 [969687][E](PTData): Cleaned 271 readings + 138577 [969697][E](PTData): New entry recorded (2)(7)(1556) + 138578 [969698][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138579 [969711][E](PTData): Fit Valid: 1, N: 30, Quad: 1, Time: 2 ms + 138580 [969720][E](PTData): Fit Valid: 1, N: 30, Quad: 1, Time: 2 ms + 138581 [969721][E](PTable): New Entry Processed in 36 ms + 138582 [969722][E](PTable): Power Buffer Reset + 138583 [970396][E](ERG_Mode): Watts previously processed. + 138584 [972381][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 196, Cad 68, HR 138, Gear 8, Res 53, Current Pos 15784, Target Pos 15784 + 138585 [972512][E](ERG_Mode): Watts previously processed. + 138586 [973219][E](ERG_Mode): Proportional: 48.000000 + 138587 [976062][E](PTable): Averaged Entry: watts=199.000000, cad=67.800003, targetPosition=1579.099976, (1)(7) + 138588 [976064][E](PTData): Cleaned 270 readings + 138589 [976074][E](PTData): New entry recorded (1)(7)(1579) + 138590 [976075][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 138591 [976085][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 138592 [976088][E](PTData): Fit Valid: 1, N: 31, Quad: 1, Time: 2 ms + 138593 [976107][E](PTData): Fit Valid: 1, N: 31, Quad: 1, Time: 2 ms + 138594 [976108][E](PTable): New Entry Processed in 46 ms + 138595 [976284][E](PTable): Writing File: /PowerTable.txt + 138596 [976908][E](PTable): Power table saved successfully with 431 readings + 138597 [976908][E](PTable): Power Buffer Reset + 138598 [976908][E](ERG_Mode): Watts previously processed. + 138599 [978361][E](ERG_Mode): Watts previously processed. + 138600 [978392][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 201, Cad 66, HR 138, Gear 8, Res 54, Current Pos 16042, Target Pos 16042 + 138601 [979045][E](FTMS_SERVER): 05 e6 00 -> ERG Mode Target: 230 Current: 201 Incline: 160.419998. Responding: 80 05 01 + 138602 [979050][E](DirConManager): Sending response message type 0x04 to client 0 + 138603 [979073][E](ERG_Mode): Proportional: 87.000000 + 138604 [980478][E](ERG_Mode): Watts previously processed. + 138605 [982591][E](PTable): Averaged Entry: watts=200.600006, cad=65.699997, targetPosition=1612.500000, (1)(7) + 138606 [982592][E](PTData): Cleaned 269 readings + 138607 [982602][E](PTData): Existing entry averaged (1)(7)(1590), readings(2) + 138608 [982603][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 138609 [982614][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 138610 [982616][E](PTData): Fit Valid: 1, N: 31, Quad: 1, Time: 2 ms + 138611 [982635][E](PTData): Fit Valid: 1, N: 31, Quad: 1, Time: 2 ms + 138612 [982637][E](PTable): New Entry Processed in 47 ms + 138613 [982637][E](PTable): Power Buffer Reset + 138614 [982647][E](ERG_Mode): Watts previously processed. + 138615 [984402][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 193, Cad 63, HR 139, Gear 8, Res 56, Current Pos 16588, Target Pos 16588 + 138616 [984703][E](ERG_Mode): Watts previously processed. + 138617 [985404][E](ERG_Mode): Proportional: 114.000000 + 138618 [986111][E](ERG_Mode): Watts previously processed. + 138619 [988229][E](ERG_Mode): Watts previously processed. + 138620 [988936][E](PTable): Averaged Entry: watts=196.399994, cad=61.900002, targetPosition=1664.800049, (0)(7) + 138621 [988937][E](PTData): Cleaned 269 readings + 138622 [988947][E](PTData): New entry recorded (0)(7)(1664) + 138623 [988949][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 138624 [988959][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 138625 [988962][E](PTData): Fit Valid: 1, N: 32, Quad: 1, Time: 3 ms + 138626 [988981][E](PTData): Fit Valid: 1, N: 32, Quad: 1, Time: 2 ms + 138627 [988982][E](PTable): New Entry Processed in 47 ms + 138628 [988982][E](PTable): Power Buffer Reset + 138629 [990340][E](ERG_Mode): Watts previously processed. + 138630 [990411][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 204, Cad 61, HR 137, Gear 8, Res 58, Current Pos 17089, Target Pos 17089 + 138631 [991050][E](ERG_Mode): Proportional: 93.000000 + 138632 [992457][E](ERG_Mode): Watts previously processed. + 138633 [994576][E](ERG_Mode): Watts previously processed. + 138634 [995283][E](PTable): Averaged Entry: watts=201.000000, cad=59.900002, targetPosition=1721.099976, (0)(7) + 138635 [995285][E](PTData): Cleaned 268 readings + 138636 [995295][E](PTData): Existing entry averaged (0)(7)(1683), readings(2) + 138637 [995297][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 138638 [995307][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 138639 [995310][E](PTData): Fit Valid: 1, N: 32, Quad: 1, Time: 3 ms + 138640 [995329][E](PTData): Fit Valid: 1, N: 32, Quad: 1, Time: 3 ms + 138641 [995330][E](PTable): New Entry Processed in 47 ms + 138642 [995330][E](PTable): Power Buffer Reset + 138643 [995993][E](PTable): Using detected travel limits during homing + 138644 [996419][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 199, Cad 58, HR 137, Gear 8, Res 60, Current Pos 17641, Target Pos 17641 + 138645 [996701][E](ERG_Mode): Watts previously processed. + 138646 [997408][E](ERG_Mode): Proportional: 111.000000 + 138647 [998109][E](ERG_Mode): Watts previously processed. + 138648 [1000229][E](ERG_Mode): Watts previously processed. + 138649 [1002351][E](ERG_Mode): Watts previously processed. + 138650 [1002432][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 269, Cad 64, HR 137, Gear 8, Res 59, Current Pos 17557, Target Pos 17557 + 138651 [1003060][E](ERG_Mode): Proportional: -57.000000 + 138652 [1003761][E](PTable): Averaged Entry: watts=240.300003, cad=61.200001, targetPosition=1764.300049, (0)(8) + 138653 [1003762][E](PTData): Cleaned 268 readings + 138654 [1003772][E](PTData): New entry recorded (0)(8)(1764) + 138655 [1003773][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 138656 [1003784][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 138657 [1003786][E](PTData): Fit Valid: 1, N: 33, Quad: 1, Time: 2 ms + 138658 [1003806][E](PTData): Fit Valid: 1, N: 33, Quad: 1, Time: 2 ms + 138659 [1003808][E](PTable): New Entry Processed in 48 ms + 138660 [1003808][E](PTable): Power Buffer Reset + 138661 [1004468][E](ERG_Mode): Watts previously processed. + 138662 [1006584][E](ERG_Mode): Watts previously processed. + 138663 [1008444][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 223, Cad 60, HR 137, Gear 8, Res 59, Current Pos 17539, Target Pos 17539 + 138664 [1008705][E](ERG_Mode): Proportional: 7.000000 + 138665 [1009411][E](ERG_Mode): Watts previously processed. + 138666 [1010112][E](PTable): Averaged Entry: watts=226.399994, cad=60.900002, targetPosition=1749.599976, (0)(8) + 138667 [1010113][E](PTData): Cleaned 267 readings + 138668 [1010123][E](PTData): Existing entry averaged (0)(8)(1759), readings(2) + 138669 [1010124][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 138670 [1010135][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 138671 [1010148][E](PTData): Fit Valid: 1, N: 33, Quad: 1, Time: 3 ms + 138672 [1010158][E](PTData): Fit Valid: 1, N: 33, Quad: 1, Time: 2 ms + 138673 [1010159][E](PTable): New Entry Processed in 47 ms + 138674 [1010160][E](PTable): Power Buffer Reset + 138675 [1011520][E](ERG_Mode): Watts previously processed. + 138676 [1014350][E](ERG_Mode): Watts previously processed. + 138677 [1014452][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 222, Cad 60, HR 136, Gear 8, Res 59, Current Pos 17576, Target Pos 17576 + 138678 [1015061][E](ERG_Mode): Proportional: 3.000000 + 138679 [1016472][E](PTable): Averaged Entry: watts=224.600006, cad=60.299999, targetPosition=1756.099976, (0)(7) + 138680 [1016473][E](PTData): Cleaned 267 readings + 138681 [1016483][E](PTData): Existing entry averaged (0)(7)(1701), readings(3) + 138682 [1016484][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 138683 [1016495][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 138684 [1016508][E](PTData): Fit Valid: 1, N: 33, Quad: 1, Time: 3 ms + 138685 [1016516][E](PTData): Fit Valid: 1, N: 33, Quad: 1, Time: 2 ms + 138686 [1016518][E](PTable): New Entry Processed in 47 ms + 138687 [1016518][E](PTable): Power Buffer Reset + 138688 [1016528][E](ERG_Mode): Watts previously processed. + 138689 [1019307][E](ERG_Mode): Watts previously processed. + 138690 [1020460][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 365, Cad 77, HR 137, Gear 8, Res 57, Current Pos 16949, Target Pos 16704 + 138691 [1020722][E](ERG_Mode): Proportional: -675.000000 + 138692 [1021429][E](ERG_Mode): Watts previously processed. + 138693 [1022840][E](PTable): Averaged Entry: watts=305.299988, cad=70.099998, targetPosition=1691.599976, (2)(10) + 138694 [1022841][E](PTData): Cleaned 267 readings + 138695 [1022851][E](PTData): New entry recorded (2)(10)(1691) + 138696 [1022852][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 138697 [1022863][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 138698 [1022865][E](PTData): Fit Valid: 1, N: 34, Quad: 1, Time: 2 ms + 138699 [1022884][E](PTData): Fit Valid: 1, N: 34, Quad: 1, Time: 2 ms + 138700 [1022886][E](PTable): New Entry Processed in 47 ms + 138701 [1022886][E](PTable): Power Buffer Reset + 138702 [1023549][E](ERG_Mode): Watts previously processed. + 138703 [1025669][E](ERG_Mode): Watts previously processed. + 138704 [1026372][E](ERG_Mode): Proportional: -111.000000 + 138705 [1026475][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 267, Cad 84, HR 138, Gear 8, Res 49, Current Pos 14368, Target Pos 14275 + 138706 [1027779][E](ERG_Mode): Watts previously processed. + 138707 [1029188][E](PTable): Averaged Entry: watts=282.600006, cad=83.099998, targetPosition=1452.300049, (5)(9) + 138708 [1029189][E](PTData): Cleaned 266 readings + 138709 [1029199][E](PTData): Existing entry averaged (5)(9)(1463), readings(2) + 138710 [1029200][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138711 [1029213][E](PTData): Fit Valid: 1, N: 34, Quad: 1, Time: 2 ms + 138712 [1029222][E](PTData): Fit Valid: 1, N: 34, Quad: 1, Time: 2 ms + 138713 [1029223][E](PTable): New Entry Processed in 36 ms + 138714 [1029224][E](PTable): Power Buffer Reset + 138715 [1031306][E](ERG_Mode): Watts previously processed. + 138716 [1032008][E](ERG_Mode): Proportional: 45.000000 + 138717 [1032009][E](PTable): Using detected travel limits during homing + 138718 [1032491][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 215, Cad 85, HR 140, Gear 8, Res 48, Current Pos 14309, Target Pos 14309 + 138719 [1033412][E](ERG_Mode): Watts previously processed. + 138720 [1035527][E](PTable): Averaged Entry: watts=224.100006, cad=86.599998, targetPosition=1425.500000, (5)(7) + 138721 [1035528][E](PTData): Cleaned 266 readings + 138722 [1035538][E](PTData): Existing entry averaged (5)(7)(1407), readings(3) + 138723 [1035539][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138724 [1035552][E](PTData): Fit Valid: 1, N: 34, Quad: 1, Time: 2 ms + 138725 [1035561][E](PTData): Fit Valid: 1, N: 34, Quad: 1, Time: 2 ms + 138726 [1035563][E](PTable): New Entry Processed in 37 ms + 138727 [1035563][E](PTable): Power Buffer Reset + 138728 [1035573][E](ERG_Mode): Watts previously processed. + 138729 [1037639][E](ERG_Mode): Watts previously processed. + 138730 [1038347][E](ERG_Mode): Proportional: -7.000000 + 138731 [1038509][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 237, Cad 88, HR 142, Gear 8, Res 48, Current Pos 14277, Target Pos 14277 + 138732 [1038939][E](FTMS_SERVER): 05 3b 01 -> ERG Mode Target: 315 Current: 240 Incline: 142.770004. Responding: 80 05 01 + 138733 [1038944][E](DirConManager): Sending response message type 0x04 to client 0 + 138734 [1039050][E](ERG_Mode): SetPoint changed:285w Waiting:849ms PowerTable Result: 14800 + 138735 [1041302][E](ERG_Mode): ERG wait expired, pos: 14800, tgt: 0 + 138736 [1043421][E](PTable): Averaged Entry: watts=246.000000, cad=88.400002, targetPosition=1462.000000, (6)(8) + 138737 [1043422][E](PTData): Cleaned 266 readings + 138738 [1043433][E](PTData): Existing entry averaged (6)(8)(1405), readings(15) + 138739 [1043434][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138740 [1043447][E](PTData): Fit Valid: 1, N: 34, Quad: 1, Time: 2 ms + 138741 [1043456][E](PTData): Fit Valid: 1, N: 34, Quad: 1, Time: 2 ms + 138742 [1043458][E](PTable): New Entry Processed in 38 ms + 138743 [1043458][E](PTable): Power Buffer Reset + 138744 [1043468][E](ERG_Mode): Watts previously processed. + 138745 [1044125][E](ERG_Mode): Proportional: 132.000000 + 138746 [1044527][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 271, Cad 88, HR 144, Gear 8, Res 52, Current Pos 15512, Target Pos 15512 + 138747 [1045529][E](ERG_Mode): Watts previously processed. + 138748 [1047647][E](ERG_Mode): Watts previously processed. + 138749 [1049759][E](PTable): Averaged Entry: watts=288.100006, cad=86.699997, targetPosition=1562.099976, (5)(10) + 138750 [1049760][E](PTData): Cleaned 266 readings + 138751 [1049770][E](PTData): New entry recorded (5)(10)(1562) + 138752 [1049771][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138753 [1049784][E](PTData): Fit Valid: 1, N: 35, Quad: 1, Time: 2 ms + 138754 [1049793][E](PTData): Fit Valid: 1, N: 35, Quad: 1, Time: 2 ms + 138755 [1049795][E](PTable): New Entry Processed in 37 ms + 138756 [1049795][E](PTable): Power Buffer Reset + 138757 [1049805][E](ERG_Mode): Watts previously processed. + 138758 [1050465][E](ERG_Mode): Proportional: 39.000000 + 138759 [1050537][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 302, Cad 85, HR 146, Gear 8, Res 53, Current Pos 15821, Target Pos 15851 + 138760 [1051171][E](ERG_Mode): Watts previously processed. + 138761 [1053295][E](ERG_Mode): Watts previously processed. + 138762 [1055413][E](ERG_Mode): Watts previously processed. + 138763 [1056121][E](PTable): Averaged Entry: watts=306.600006, cad=84.500000, targetPosition=1587.099976, (5)(10) + 138764 [1056122][E](PTData): Cleaned 265 readings + 138765 [1056133][E](PTData): Existing entry averaged (5)(10)(1570), readings(2) + 138766 [1056134][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138767 [1056147][E](PTData): Fit Valid: 1, N: 35, Quad: 1, Time: 3 ms + 138768 [1056156][E](PTData): Fit Valid: 1, N: 35, Quad: 1, Time: 3 ms + 138769 [1056157][E](PTable): New Entry Processed in 36 ms + 138770 [1056157][E](PTable): Power Buffer Reset + 138771 [1056168][E](ERG_Mode): Proportional: -7.000000 + 138772 [1056552][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 322, Cad 85, HR 148, Gear 8, Res 54, Current Pos 15906, Target Pos 15906 + 138773 [1057530][E](ERG_Mode): Watts previously processed. + 138774 [1059010][E](FTMS_SERVER): 05 e6 00 -> ERG Mode Target: 230 Current: 326 Incline: 158.580002. Responding: 80 05 01 + 138775 [1059017][E](DirConManager): Sending response message type 0x04 to client 0 + 138776 [1059645][E](ERG_Mode): SetPoint changed:260w Waiting:1008ms PowerTable Result: 14780 + 138777 [1062061][E](ERG_Mode): ERG wait expired, pos: 14780, tgt: 0 + 138778 [1062062][E](ERG_Mode): Proportional: -256.000000 + 138779 [1062569][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 294, Cad 85, HR 149, Gear 8, Res 49, Current Pos 14532, Target Pos 14524 + 138780 [1062771][E](ERG_Mode): Watts previously processed. + 138781 [1064178][E](PTable): Averaged Entry: watts=302.299988, cad=85.500000, targetPosition=1536.099976, (5)(10) + 138782 [1064179][E](PTData): Cleaned 265 readings + 138783 [1064189][E](PTData): Existing entry averaged (5)(10)(1561), readings(3) + 138784 [1064190][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138785 [1064203][E](PTData): Fit Valid: 1, N: 35, Quad: 1, Time: 2 ms + 138786 [1064212][E](PTData): Fit Valid: 1, N: 35, Quad: 1, Time: 2 ms + 138787 [1064214][E](PTable): New Entry Processed in 37 ms + 138788 [1064214][E](PTable): Power Buffer Reset + 138789 [1064225][E](ERG_Mode): Watts previously processed. + 138790 [1066298][E](ERG_Mode): Watts previously processed. + 138791 [1067716][E](ERG_Mode): Proportional: -4.000000 + 138792 [1068424][E](ERG_Mode): Watts previously processed. + 138793 [1068585][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 234, Cad 85, HR 151, Gear 8, Res 49, Current Pos 14466, Target Pos 14466 + 138794 [1070546][E](PTable): Averaged Entry: watts=234.399994, cad=86.199997, targetPosition=1445.400024, (5)(8) + 138795 [1070547][E](PTData): Cleaned 265 readings + 138796 [1070557][E](PTData): Existing entry averaged (5)(8)(1437), readings(10) + 138797 [1070558][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138798 [1070571][E](PTData): Fit Valid: 1, N: 35, Quad: 1, Time: 2 ms + 138799 [1070580][E](PTData): Fit Valid: 1, N: 35, Quad: 1, Time: 2 ms + 138800 [1070581][E](PTable): New Entry Processed in 36 ms + 138801 [1070582][E](PTable): Power Buffer Reset + 138802 [1070592][E](ERG_Mode): Watts previously processed. + 138803 [1071247][E](PTable): Using detected travel limits during homing + 138804 [1072657][E](ERG_Mode): Watts previously processed. + 138805 [1073364][E](ERG_Mode): Proportional: 4.000000 + 138806 [1074600][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 219, Cad 85, HR 153, Gear 8, Res 49, Current Pos 14427, Target Pos 14427 + 138807 [1076196][E](ERG_Mode): Watts previously processed. + 138808 [1076904][E](PTable): Averaged Entry: watts=225.399994, cad=85.300003, targetPosition=1443.300049, (5)(8) + 138809 [1076905][E](PTData): Cleaned 265 readings + 138810 [1076915][E](PTData): Existing entry averaged (5)(8)(1437), readings(11) + 138811 [1076917][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138812 [1076930][E](PTData): Fit Valid: 1, N: 35, Quad: 1, Time: 3 ms + 138813 [1076939][E](PTData): Fit Valid: 1, N: 35, Quad: 1, Time: 3 ms + 138814 [1076940][E](PTable): New Entry Processed in 37 ms + 138815 [1076940][E](PTable): Power Buffer Reset + 138816 [1078309][E](ERG_Mode): Watts previously processed. + 138817 [1079017][E](ERG_Mode): Proportional: -5.000000 + 138818 [1080422][E](ERG_Mode): Watts previously processed. + 138819 [1080613][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 230, Cad 86, HR 154, Gear 8, Res 49, Current Pos 14486, Target Pos 14486 + 138820 [1082537][E](ERG_Mode): Watts previously processed. + 138821 [1083244][E](PTable): Averaged Entry: watts=232.800003, cad=85.500000, targetPosition=1448.400024, (5)(8) + 138822 [1083245][E](PTData): Cleaned 265 readings + 138823 [1083255][E](PTData): Existing entry averaged (5)(8)(1437), readings(12) + 138824 [1083256][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138825 [1083269][E](PTData): Fit Valid: 1, N: 35, Quad: 1, Time: 2 ms + 138826 [1083278][E](PTData): Fit Valid: 1, N: 35, Quad: 1, Time: 2 ms + 138827 [1083280][E](PTable): New Entry Processed in 36 ms + 138828 [1083280][E](PTable): Power Buffer Reset + 138829 [1084657][E](ERG_Mode): Proportional: 45.000000 + 138830 [1085366][E](ERG_Mode): Watts previously processed. + 138831 [1086629][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 223, Cad 83, HR 154, Gear 8, Res 49, Current Pos 14582, Target Pos 14582 + 138832 [1087491][E](ERG_Mode): Watts previously processed. + 138833 [1089620][E](PTable): Averaged Entry: watts=221.000000, cad=83.699997, targetPosition=1454.400024, (5)(7) + 138834 [1089622][E](PTData): Cleaned 265 readings + 138835 [1089632][E](PTData): Existing entry averaged (5)(7)(1416), readings(4) + 138836 [1089633][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138837 [1089646][E](PTData): Fit Valid: 1, N: 35, Quad: 1, Time: 3 ms + 138838 [1089655][E](PTData): Fit Valid: 1, N: 35, Quad: 1, Time: 2 ms + 138839 [1089656][E](PTable): New Entry Processed in 36 ms + 138840 [1089656][E](PTable): Power Buffer Reset + 138841 [1089667][E](ERG_Mode): Proportional: 7.000000 + 138842 [1090331][E](ERG_Mode): Watts previously processed. + 138843 [1092454][E](ERG_Mode): Watts previously processed. + 138844 [1092645][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 231, Cad 83, HR 155, Gear 8, Res 49, Current Pos 14616, Target Pos 14616 + 138845 [1094572][E](ERG_Mode): Watts previously processed. + 138846 [1095280][E](ERG_Mode): Proportional: 33.000000 + 138847 [1095985][E](PTable): Averaged Entry: watts=222.500000, cad=83.000000, targetPosition=1463.699951, (5)(7) + 138848 [1095986][E](PTData): Cleaned 265 readings + 138849 [1095996][E](PTData): Existing entry averaged (5)(7)(1423), readings(5) + 138850 [1095997][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138851 [1096010][E](PTData): Fit Valid: 1, N: 35, Quad: 1, Time: 2 ms + 138852 [1096019][E](PTData): Fit Valid: 1, N: 35, Quad: 1, Time: 2 ms + 138853 [1096020][E](PTable): New Entry Processed in 36 ms + 138854 [1096021][E](PTable): Power Buffer Reset + 138855 [1096692][E](ERG_Mode): Watts previously processed. + 138856 [1098661][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 228, Cad 82, HR 155, Gear 8, Res 50, Current Pos 14812, Target Pos 14812 + 138857 [1100235][E](ERG_Mode): Watts previously processed. + 138858 [1100942][E](ERG_Mode): Proportional: -30.000000 + 138859 [1102345][E](PTable): Averaged Entry: watts=226.899994, cad=82.300003, targetPosition=1478.400024, (4)(8) + 138860 [1102346][E](PTData): Cleaned 265 readings + 138861 [1102356][E](PTData): New entry recorded (4)(8)(1478) + 138862 [1102357][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 138863 [1102368][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 138864 [1102371][E](PTData): Fit Valid: 1, N: 36, Quad: 1, Time: 3 ms + 138865 [1102390][E](PTData): Fit Valid: 1, N: 36, Quad: 1, Time: 3 ms + 138866 [1102391][E](PTable): New Entry Processed in 47 ms + 138867 [1102391][E](PTable): Power Buffer Reset + 138868 [1102401][E](ERG_Mode): Watts previously processed. + 138869 [1104464][E](ERG_Mode): Watts previously processed. + 138870 [1104676][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 230, Cad 83, HR 154, Gear 8, Res 50, Current Pos 14778, Target Pos 14778 + 138871 [1106580][E](ERG_Mode): Watts previously processed. + 138872 [1107288][E](ERG_Mode): Proportional: -87.000000 + 138873 [1107289][E](PTable): Using detected travel limits during homing + 138874 [1108693][E](PTable): Averaged Entry: watts=231.500000, cad=83.000000, targetPosition=1475.599976, (5)(8) + 138875 [1108694][E](PTData): Cleaned 264 readings + 138876 [1108704][E](PTData): Existing entry averaged (5)(8)(1439), readings(13) + 138877 [1108705][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 138878 [1108716][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 138879 [1108729][E](PTData): Fit Valid: 1, N: 36, Quad: 1, Time: 3 ms + 138880 [1108738][E](PTData): Fit Valid: 1, N: 36, Quad: 1, Time: 3 ms + 138881 [1108739][E](PTable): New Entry Processed in 47 ms + 138882 [1108739][E](PTable): Power Buffer Reset + 138883 [1108750][E](ERG_Mode): Watts previously processed. + 138884 [1110691][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 210, Cad 80, HR 154, Gear 8, Res 50, Current Pos 14789, Target Pos 14789 + 138885 [1111518][E](ERG_Mode): Watts previously processed. + 138886 [1112931][E](ERG_Mode): Proportional: 54.000000 + 138887 [1113637][E](ERG_Mode): Watts previously processed. + 138888 [1115055][E](PTable): Averaged Entry: watts=213.100006, cad=79.699997, targetPosition=1484.000000, (4)(7) + 138889 [1115056][E](PTData): Cleaned 264 readings + 138890 [1115066][E](PTData): New entry recorded (4)(7)(1484) + 138891 [1115067][E](PTData): Lower Right Found 4, 8, tp1478 + 138892 [1115079][E](PTData): Fit Valid: 1, N: 35, Quad: 1, Time: 2 ms + 138893 [1115081][E](PTable): New Entry Processed in 27 ms + 138894 [1115081][E](PTable): Power Buffer Reset + 138895 [1116472][E](ERG_Mode): Watts previously processed. + 138896 [1116704][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 223, Cad 79, HR 154, Gear 8, Res 51, Current Pos 15060, Target Pos 15060 + 138897 [1118587][E](ERG_Mode): Watts previously processed. + 138898 [1119010][E](FTMS_SERVER): 05 d7 00 -> ERG Mode Target: 215 Current: 250 Incline: 150.500000. Responding: 80 05 01 + 138899 [1119015][E](DirConManager): Sending response message type 0x04 to client 0 + 138900 [1119291][E](ERG_Mode): Proportional: -105.000000 + 138901 [1121403][E](PTable): Averaged Entry: watts=237.000000, cad=80.500000, targetPosition=1498.900024, (4)(8) + 138902 [1121404][E](PTData): Cleaned 1 readings + 138903 [1121414][E](PTData): New entry recorded (4)(8)(1498) + 138904 [1121415][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 138905 [1121426][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 138906 [1121428][E](PTData): Fit Valid: 1, N: 36, Quad: 1, Time: 2 ms + 138907 [1121448][E](PTData): Fit Valid: 1, N: 36, Quad: 1, Time: 3 ms + 138908 [1121449][E](PTable): New Entry Processed in 47 ms + 138909 [1121449][E](PTable): Power Buffer Reset + 138910 [1121460][E](ERG_Mode): Watts previously processed. + 138911 [1122718][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 235, Cad 83, HR 154, Gear 8, Res 49, Current Pos 14645, Target Pos 14645 + 138912 [1123515][E](ERG_Mode): Watts previously processed. + 138913 [1124921][E](ERG_Mode): Proportional: -39.000000 + 138914 [1125628][E](ERG_Mode): Watts previously processed. + 138915 [1127745][E](PTable): Averaged Entry: watts=230.800003, cad=82.300003, targetPosition=1457.400024, (4)(8) + 138916 [1127746][E](PTData): Cleaned 264 readings + 138917 [1127756][E](PTData): Existing entry averaged (4)(8)(1484), readings(2) + 138918 [1127757][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 138919 [1127768][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 138920 [1127781][E](PTData): Fit Valid: 1, N: 36, Quad: 1, Time: 3 ms + 138921 [1127790][E](PTData): Fit Valid: 1, N: 36, Quad: 1, Time: 3 ms + 138922 [1127791][E](PTable): New Entry Processed in 47 ms + 138923 [1127791][E](PTable): Power Buffer Reset + 138924 [1127802][E](ERG_Mode): Watts previously processed. + 138925 [1128726][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 221, Cad 82, HR 154, Gear 8, Res 49, Current Pos 14462, Target Pos 14462 + 138926 [1129856][E](ERG_Mode): Watts previously processed. + 138927 [1130564][E](ERG_Mode): Proportional: 2.000000 + 138928 [1133391][E](ERG_Mode): Watts previously processed. + 138929 [1134098][E](PTable): Averaged Entry: watts=212.399994, cad=81.900002, targetPosition=1446.599976, (4)(7) + 138930 [1134099][E](PTData): Cleaned 264 readings + 138931 [1134109][E](PTData): New entry recorded (4)(7)(1446) + 138932 [1134110][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138933 [1134123][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 2 ms + 138934 [1134132][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 2 ms + 138935 [1134134][E](PTable): New Entry Processed in 37 ms + 138936 [1134134][E](PTable): Power Buffer Reset + 138937 [1134740][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 214, Cad 81, HR 154, Gear 8, Res 49, Current Pos 14490, Target Pos 14490 + 138938 [1135508][E](ERG_Mode): Watts previously processed. + 138939 [1136215][E](ERG_Mode): Proportional: -63.000000 + 138940 [1137630][E](ERG_Mode): Watts previously processed. + 138941 [1139748][E](ERG_Mode): Watts previously processed. + 138942 [1140457][E](PTable): Averaged Entry: watts=221.800003, cad=83.599998, targetPosition=1440.900024, (5)(7) + 138943 [1140458][E](PTData): Cleaned 263 readings + 138944 [1140468][E](PTData): Existing entry averaged (5)(7)(1417), readings(6) + 138945 [1140469][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138946 [1140482][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 2 ms + 138947 [1140491][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 2 ms + 138948 [1140493][E](PTable): New Entry Processed in 36 ms + 138949 [1140493][E](PTable): Power Buffer Reset + 138950 [1140755][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 210, Cad 84, HR 154, Gear 8, Res 48, Current Pos 14334, Target Pos 14334 + 138951 [1141872][E](ERG_Mode): Proportional: 3.000000 + 138952 [1143282][E](ERG_Mode): Watts previously processed. + 138953 [1143282][E](PTable): Using detected travel limits during homing + 138954 [1145397][E](ERG_Mode): Watts previously processed. + 138955 [1146770][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 203, Cad 80, HR 154, Gear 8, Res 49, Current Pos 14496, Target Pos 14496 + 138956 [1146812][E](PTable): Averaged Entry: watts=206.199997, cad=82.300003, targetPosition=1438.599976, (4)(7) + 138957 [1146813][E](PTData): Cleaned 263 readings + 138958 [1146824][E](PTData): Existing entry averaged (4)(7)(1443), readings(2) + 138959 [1146825][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138960 [1146838][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 3 ms + 138961 [1146847][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 3 ms + 138962 [1146848][E](PTable): New Entry Processed in 36 ms + 138963 [1146848][E](PTable): Power Buffer Reset + 138964 [1147522][E](ERG_Mode): Watts previously processed. + 138965 [1148231][E](ERG_Mode): Proportional: 48.000000 + 138966 [1149636][E](ERG_Mode): Watts previously processed. + 138967 [1152461][E](ERG_Mode): Watts previously processed. + 138968 [1152778][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 217, Cad 82, HR 154, Gear 8, Res 49, Current Pos 14528, Target Pos 14528 + 138969 [1153164][E](PTable): Averaged Entry: watts=215.199997, cad=81.099998, targetPosition=1454.400024, (4)(7) + 138970 [1153165][E](PTData): Cleaned 263 readings + 138971 [1153175][E](PTData): Existing entry averaged (4)(7)(1445), readings(3) + 138972 [1153176][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138973 [1153189][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 2 ms + 138974 [1153199][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 3 ms + 138975 [1153200][E](PTable): New Entry Processed in 37 ms + 138976 [1153201][E](PTable): Power Buffer Reset + 138977 [1153871][E](ERG_Mode): Proportional: 8.000000 + 138978 [1154579][E](ERG_Mode): Watts previously processed. + 138979 [1157421][E](ERG_Mode): Watts previously processed. + 138980 [1158802][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 226, Cad 85, HR 155, Gear 8, Res 49, Current Pos 14472, Target Pos 14472 + 138981 [1159541][E](PTable): Averaged Entry: watts=216.399994, cad=82.000000, targetPosition=1451.599976, (4)(7) + 138982 [1159542][E](PTData): Cleaned 263 readings + 138983 [1159553][E](PTData): Existing entry averaged (4)(7)(1446), readings(4) + 138984 [1159554][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138985 [1159567][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 3 ms + 138986 [1159576][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 2 ms + 138987 [1159578][E](PTable): New Entry Processed in 38 ms + 138988 [1159578][E](PTable): Power Buffer Reset + 138989 [1159588][E](ERG_Mode): Watts previously processed. + 138990 [1160251][E](ERG_Mode): Proportional: -6.000000 + 138991 [1161664][E](ERG_Mode): Watts previously processed. + 138992 [1164484][E](ERG_Mode): Watts previously processed. + 138993 [1164820][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 205, Cad 80, HR 155, Gear 8, Res 49, Current Pos 14477, Target Pos 14477 + 138994 [1165894][E](PTable): Averaged Entry: watts=211.000000, cad=81.599998, targetPosition=1444.500000, (4)(7) + 138995 [1165895][E](PTData): Cleaned 263 readings + 138996 [1165906][E](PTData): Existing entry averaged (4)(7)(1445), readings(5) + 138997 [1165907][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 138998 [1165920][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 3 ms + 138999 [1165929][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 3 ms + 139000 [1165930][E](PTable): New Entry Processed in 37 ms + 139001 [1165930][E](PTable): Power Buffer Reset + 139002 [1165940][E](ERG_Mode): Proportional: 8.000000 + 139003 [1166602][E](ERG_Mode): Watts previously processed. + 139004 [1168720][E](ERG_Mode): Watts previously processed. + 139005 [1170842][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 206, Cad 80, HR 154, Gear 8, Res 49, Current Pos 14641, Target Pos 14641 + 139006 [1171552][E](ERG_Mode): Watts previously processed. + 139007 [1172260][E](PTable): Averaged Entry: watts=204.500000, cad=80.000000, targetPosition=1458.000000, (4)(7) + 139008 [1172261][E](PTData): Cleaned 263 readings + 139009 [1172271][E](PTData): Existing entry averaged (4)(7)(1446), readings(6) + 139010 [1172272][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139011 [1172285][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 2 ms + 139012 [1172294][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 2 ms + 139013 [1172296][E](PTable): New Entry Processed in 36 ms + 139014 [1172296][E](PTable): Power Buffer Reset + 139015 [1172306][E](ERG_Mode): Proportional: 9.000000 + 139016 [1173662][E](ERG_Mode): Watts previously processed. + 139017 [1176489][E](ERG_Mode): Watts previously processed. + 139018 [1176856][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 207, Cad 78, HR 152, Gear 8, Res 50, Current Pos 14784, Target Pos 14784 + 139019 [1177899][E](ERG_Mode): Proportional: 2.000000 + 139020 [1178604][E](PTable): Averaged Entry: watts=205.699997, cad=78.300003, targetPosition=1473.199951, (4)(7) + 139021 [1178605][E](PTData): Cleaned 263 readings + 139022 [1178616][E](PTData): Existing entry averaged (4)(7)(1449), readings(7) + 139023 [1178617][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139024 [1178630][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 3 ms + 139025 [1178639][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 3 ms + 139026 [1178640][E](PTable): New Entry Processed in 36 ms + 139027 [1178640][E](PTable): Power Buffer Reset + 139028 [1178651][E](ERG_Mode): Watts previously processed. + 139029 [1179015][E](FTMS_SERVER): 05 c8 00 -> ERG Mode Target: 200 Current: 212 Incline: 147.940002. Responding: 80 05 01 + 139030 [1179022][E](DirConManager): Sending response message type 0x04 to client 0 + 139031 [1179311][E](PTable): Using detected travel limits during homing + 139032 [1180722][E](ERG_Mode): Watts previously processed. + 139033 [1182844][E](ERG_Mode): Watts previously processed. + 139034 [1182868][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 201, Cad 78, HR 150, Gear 8, Res 49, Current Pos 14659, Target Pos 14659 + 139035 [1183545][E](ERG_Mode): Proportional: -1.000000 + 139036 [1184965][E](PTable): Averaged Entry: watts=211.500000, cad=78.099998, targetPosition=1470.699951, (4)(7) + 139037 [1184966][E](PTData): Cleaned 263 readings + 139038 [1184976][E](PTData): Existing entry averaged (4)(7)(1451), readings(8) + 139039 [1184977][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139040 [1184990][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 2 ms + 139041 [1185000][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 2 ms + 139042 [1185001][E](PTable): New Entry Processed in 37 ms + 139043 [1185001][E](PTable): Power Buffer Reset + 139044 [1185675][E](ERG_Mode): Watts previously processed. + 139045 [1188491][E](ERG_Mode): Watts previously processed. + 139046 [1188879][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 208, Cad 79, HR 149, Gear 8, Res 49, Current Pos 14550, Target Pos 14550 + 139047 [1189196][E](ERG_Mode): Proportional: -8.000000 + 139048 [1190613][E](ERG_Mode): Watts previously processed. + 139049 [1191314][E](PTable): Averaged Entry: watts=213.199997, cad=79.599998, targetPosition=1454.199951, (4)(7) + 139050 [1191315][E](PTData): Cleaned 263 readings + 139051 [1191325][E](PTData): Existing entry averaged (4)(7)(1451), readings(9) + 139052 [1191326][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139053 [1191339][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 2 ms + 139054 [1191348][E](PTData): Fit Valid: 1, N: 37, Quad: 1, Time: 2 ms + 139055 [1191350][E](PTable): New Entry Processed in 37 ms + 139056 [1191350][E](PTable): Power Buffer Reset + 139057 [1192725][E](ERG_Mode): Watts previously processed. + 139058 [1194846][E](ERG_Mode): Watts previously processed. + 139059 [1194893][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 182, Cad 77, HR 147, Gear 8, Res 49, Current Pos 14524, Target Pos 14524 + 139060 [1195551][E](ERG_Mode): Proportional: 54.000000 + 139061 [1196963][E](ERG_Mode): Watts previously processed. + 139062 [1197665][E](PTable): Averaged Entry: watts=188.199997, cad=79.300003, targetPosition=1450.000000, (4)(6) + 139063 [1197666][E](PTData): Cleaned 263 readings + 139064 [1197676][E](PTData): New entry recorded (4)(6)(1450) + 139065 [1197677][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139066 [1197690][E](PTData): Fit Valid: 1, N: 38, Quad: 1, Time: 2 ms + 139067 [1197699][E](PTData): Fit Valid: 1, N: 38, Quad: 1, Time: 2 ms + 139068 [1197701][E](PTable): New Entry Processed in 36 ms + 139069 [1197701][E](PTable): Power Buffer Reset + 139070 [1198372][E](ERG_Mode): Watts previously processed. + 139071 [1200495][E](ERG_Mode): Watts previously processed. + 139072 [1200904][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 190, Cad 76, HR 147, Gear 8, Res 50, Current Pos 14709, Target Pos 14709 + 139073 [1201198][E](ERG_Mode): Proportional: 30.000000 + 139074 [1202610][E](ERG_Mode): Watts previously processed. + 139075 [1204028][E](PTable): Averaged Entry: watts=192.000000, cad=76.400002, targetPosition=1470.699951, (3)(6) + 139076 [1204029][E](PTData): Cleaned 262 readings + 139077 [1204040][E](PTData): Existing entry averaged (3)(6)(1464), readings(2) + 139078 [1204041][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139079 [1204054][E](PTData): Fit Valid: 1, N: 38, Quad: 1, Time: 3 ms + 139080 [1204063][E](PTData): Fit Valid: 1, N: 38, Quad: 1, Time: 3 ms + 139081 [1204065][E](PTable): New Entry Processed in 38 ms + 139082 [1204065][E](PTable): Power Buffer Reset + 139083 [1204731][E](ERG_Mode): Watts previously processed. + 139084 [1206846][E](ERG_Mode): Watts previously processed. + 139085 [1206933][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 177, Cad 73, HR 145, Gear 8, Res 50, Current Pos 14892, Target Pos 14892 + 139086 [1207547][E](ERG_Mode): Proportional: 69.000000 + 139087 [1210364][E](PTable): Averaged Entry: watts=204.100006, cad=75.500000, targetPosition=1485.699951, (3)(7) + 139088 [1210365][E](PTData): Cleaned 262 readings + 139089 [1210375][E](PTData): New entry recorded (3)(7)(1485) + 139090 [1210376][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139091 [1210389][E](PTData): Fit Valid: 1, N: 39, Quad: 1, Time: 2 ms + 139092 [1210398][E](PTData): Fit Valid: 1, N: 39, Quad: 1, Time: 2 ms + 139093 [1210400][E](PTable): New Entry Processed in 37 ms + 139094 [1210400][E](PTable): Power Buffer Reset + 139095 [1210410][E](ERG_Mode): Watts previously processed. + 139096 [1212483][E](ERG_Mode): Watts previously processed. + 139097 [1212950][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 217, Cad 78, HR 145, Gear 8, Res 50, Current Pos 14707, Target Pos 14707 + 139098 [1213191][E](ERG_Mode): Proportional: -51.000000 + 139099 [1214600][E](ERG_Mode): Watts previously processed. + 139100 [1215319][E](PTable): Using detected travel limits during homing + 139101 [1216723][E](PTable): Averaged Entry: watts=213.199997, cad=80.099998, targetPosition=1462.800049, (4)(7) + 139102 [1216725][E](PTData): Cleaned 261 readings + 139103 [1216735][E](PTData): Existing entry averaged (4)(7)(1452), readings(10) + 139104 [1216736][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139105 [1216750][E](PTData): Fit Valid: 1, N: 39, Quad: 1, Time: 3 ms + 139106 [1216759][E](PTData): Fit Valid: 1, N: 39, Quad: 1, Time: 3 ms + 139107 [1216760][E](PTable): New Entry Processed in 37 ms + 139108 [1216760][E](PTable): Power Buffer Reset + 139109 [1216771][E](ERG_Mode): Watts previously processed. + 139110 [1218838][E](ERG_Mode): Watts previously processed. + 139111 [1218969][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 206, Cad 80, HR 144, Gear 8, Res 49, Current Pos 14476, Target Pos 14476 + 139112 [1219548][E](ERG_Mode): Proportional: 5.000000 + 139113 [1222376][E](ERG_Mode): Watts previously processed. + 139114 [1223085][E](PTable): Averaged Entry: watts=197.300003, cad=78.800003, targetPosition=1448.800049, (4)(7) + 139115 [1223086][E](PTData): Cleaned 261 readings + 139116 [1223096][E](PTData): Existing entry averaged (4)(7)(1451), readings(11) + 139117 [1223097][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139118 [1223110][E](PTData): Fit Valid: 1, N: 39, Quad: 1, Time: 2 ms + 139119 [1223120][E](PTData): Fit Valid: 1, N: 39, Quad: 1, Time: 3 ms + 139120 [1223121][E](PTable): New Entry Processed in 37 ms + 139121 [1223162][E](PTable): Writing File: /PowerTable.txt + 139122 [1223393][E](PTable): Power table saved successfully with 467 readings + 139123 [1223394][E](PTable): Power Buffer Reset + 139124 [1223794][E](ERG_Mode): Watts previously processed. + 139125 [1224999][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 201, Cad 79, HR 141, Gear 8, Res 49, Current Pos 14530, Target Pos 14530 + 139126 [1225211][E](ERG_Mode): Proportional: -1.000000 + 139127 [1225917][E](ERG_Mode): Watts previously processed. + 139128 [1229449][E](PTable): Averaged Entry: watts=204.100006, cad=78.800003, targetPosition=1450.500000, (4)(7) + 139129 [1229450][E](PTData): Cleaned 261 readings + 139130 [1229461][E](PTData): Existing entry averaged (4)(7)(1450), readings(12) + 139131 [1229462][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139132 [1229475][E](PTData): Fit Valid: 1, N: 39, Quad: 1, Time: 3 ms + 139133 [1229484][E](PTData): Fit Valid: 1, N: 39, Quad: 1, Time: 2 ms + 139134 [1229486][E](PTable): New Entry Processed in 38 ms + 139135 [1229486][E](PTable): Power Buffer Reset + 139136 [1229497][E](ERG_Mode): Watts previously processed. + 139137 [1230859][E](ERG_Mode): Proportional: 36.000000 + 139138 [1231011][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 188, Cad 80, HR 141, Gear 8, Res 49, Current Pos 14451, Target Pos 14456 + 139139 [1231560][E](ERG_Mode): Watts previously processed. + 139140 [1233679][E](ERG_Mode): Watts previously processed. + 139141 [1235797][E](PTable): Averaged Entry: watts=193.300003, cad=78.599998, targetPosition=1447.300049, (4)(6) + 139142 [1235799][E](PTData): Cleaned 261 readings + 139143 [1235809][E](PTData): Existing entry averaged (4)(6)(1449), readings(2) + 139144 [1235810][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139145 [1235823][E](PTData): Fit Valid: 1, N: 39, Quad: 1, Time: 2 ms + 139146 [1235833][E](PTData): Fit Valid: 1, N: 39, Quad: 1, Time: 3 ms + 139147 [1235834][E](PTable): New Entry Processed in 37 ms + 139148 [1235834][E](PTable): Power Buffer Reset + 139149 [1235845][E](ERG_Mode): Watts previously processed. + 139150 [1236509][E](ERG_Mode): Proportional: -54.000000 + 139151 [1237037][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 218, Cad 81, HR 142, Gear 8, Res 49, Current Pos 14491, Target Pos 14491 + 139152 [1237923][E](ERG_Mode): Watts previously processed. + 139153 [1238938][E](FTMS_SERVER): 05 b9 00 -> ERG Mode Target: 185 Current: 262 Incline: 141.889999. Responding: 80 05 01 + 139154 [1238946][E](DirConManager): Sending response message type 0x04 to client 0 + 139155 [1241454][E](ERG_Mode): Watts previously processed. + 139156 [1242162][E](PTable): Averaged Entry: watts=223.199997, cad=81.900002, targetPosition=1411.800049, (4)(7) + 139157 [1242163][E](PTData): Cleaned 261 readings + 139158 [1242173][E](PTData): Existing entry averaged (4)(7)(1447), readings(13) + 139159 [1242174][E](PTData): Greater Left Found 4, 6, tp1449 + 139160 [1242187][E](PTData): Fit Valid: 1, N: 39, Quad: 1, Time: 3 ms + 139161 [1242188][E](PTable): New Entry Processed in 26 ms + 139162 [1242188][E](PTable): Power Buffer Reset + 139163 [1242199][E](ERG_Mode): Proportional: -1.000000 + 139164 [1243046][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 170, Cad 81, HR 141, Gear 8, Res 46, Current Pos 13604, Target Pos 13608 + 139165 [1243573][E](ERG_Mode): Watts previously processed. + 139166 [1245696][E](ERG_Mode): Watts previously processed. + 139167 [1247812][E](ERG_Mode): Watts previously processed. + 139168 [1248528][E](PTable): Averaged Entry: watts=166.500000, cad=79.300003, targetPosition=1371.599976, (4)(6) + 139169 [1248530][E](PTData): Existing entry averaged (4)(6)(1423), readings(2) + 139170 [1248541][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139171 [1248544][E](PTData): Fit Valid: 1, N: 39, Quad: 1, Time: 3 ms + 139172 [1248563][E](PTData): Fit Valid: 1, N: 39, Quad: 1, Time: 2 ms + 139173 [1248564][E](PTable): New Entry Processed in 36 ms + 139174 [1248565][E](PTable): Power Buffer Reset + 139175 [1248575][E](ERG_Mode): Proportional: -9.000000 + 139176 [1249063][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 200, Cad 81, HR 140, Gear 8, Res 47, Current Pos 13908, Target Pos 13908 + 139177 [1251350][E](ERG_Mode): Watts previously processed. + 139178 [1251350][E](PTable): Using detected travel limits during homing + 139179 [1253472][E](ERG_Mode): Watts previously processed. + 139180 [1254181][E](ERG_Mode): Proportional: -51.000000 + 139181 [1254883][E](PTable): Averaged Entry: watts=204.899994, cad=83.800003, targetPosition=1372.900024, (5)(7) + 139182 [1254885][E](PTData): Cleaned 261 readings + 139183 [1254895][E](PTData): Existing entry averaged (5)(7)(1411), readings(7) + 139184 [1254896][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139185 [1254909][E](PTData): Fit Valid: 1, N: 39, Quad: 1, Time: 2 ms + 139186 [1254919][E](PTData): Fit Valid: 1, N: 39, Quad: 1, Time: 3 ms + 139187 [1254920][E](PTable): New Entry Processed in 37 ms + 139188 [1254920][E](PTable): Power Buffer Reset + 139189 [1255072][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 221, Cad 86, HR 141, Gear 8, Res 46, Current Pos 13551, Target Pos 13476 + 139190 [1255584][E](ERG_Mode): Watts previously processed. + 139191 [1257697][E](ERG_Mode): Watts previously processed. + 139192 [1259814][E](ERG_Mode): Watts previously processed. + 139193 [1260523][E](ERG_Mode): Proportional: 30.000000 + 139194 [1261092][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 234, Cad 87, HR 143, Gear 8, Res 45, Current Pos 13313, Target Pos 13313 + 139195 [1261224][E](PTable): Averaged Entry: watts=206.699997, cad=88.800003, targetPosition=1335.099976, (6)(7) + 139196 [1261225][E](PTData): Cleaned 261 readings + 139197 [1261236][E](PTData): Existing entry averaged (6)(7)(1320), readings(8) + 139198 [1261237][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139199 [1261250][E](PTData): Fit Valid: 1, N: 39, Quad: 1, Time: 3 ms + 139200 [1261259][E](PTData): Fit Valid: 1, N: 39, Quad: 1, Time: 2 ms + 139201 [1261261][E](PTable): New Entry Processed in 37 ms + 139202 [1261261][E](PTable): Power Buffer Reset + 139203 [1261766][E](FTMS_SERVER): 11 00 00 82 02 28 33 -> Sim Mode Incline 6.420000. Responding: 80 11 01 + 139204 [1261771][E](DirConManager): Sending response message type 0x04 to client 0 + 139205 [1262781][E](FTMS_SERVER): 11 00 00 83 02 28 33 -> Sim Mode Incline 6.430000. Responding: 80 11 01 + 139206 [1262787][E](DirConManager): Sending response message type 0x04 to client 0 + 139207 [1263806][E](FTMS_SERVER): 11 00 00 86 02 28 33 -> Sim Mode Incline 6.460000. Responding: 80 11 01 + 139208 [1263812][E](DirConManager): Sending response message type 0x04 to client 0 + 139209 [1264746][E](FTMS_SERVER): 11 00 00 85 02 28 33 -> Sim Mode Incline 6.450000. Responding: 80 11 01 + 139210 [1264753][E](DirConManager): Sending response message type 0x04 to client 0 + 139211 [1265848][E](FTMS_SERVER): 11 00 00 86 02 28 33 -> Sim Mode Incline 6.460000. Responding: 80 11 01 + 139212 [1265853][E](DirConManager): Sending response message type 0x04 to client 0 + 139213 [1266767][E](FTMS_SERVER): 11 00 00 85 02 28 33 -> Sim Mode Incline 6.450000. Responding: 80 11 01 + 139214 [1266775][E](DirConManager): Sending response message type 0x04 to client 0 + 139215 [1267105][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 37, HR 143, Gear 8, Res 48, Current Pos 14115, Target Pos 14115 + 139216 [1267805][E](FTMS_SERVER): 11 00 00 88 02 28 33 -> Sim Mode Incline 6.480000. Responding: 80 11 01 + 139217 [1267812][E](DirConManager): Sending response message type 0x04 to client 0 + 139218 [1269539][E](FTMS_SERVER): 11 00 00 8b 02 28 33 -> Sim Mode Incline 6.510000. Responding: 80 11 01 + 139219 [1269544][E](DirConManager): Sending response message type 0x04 to client 0 + 139220 [1272817][E](FTMS_SERVER): 11 00 00 89 02 28 33 -> Sim Mode Incline 6.490000. Responding: 80 11 01 + 139221 [1272824][E](DirConManager): Sending response message type 0x04 to client 0 + 139222 [1273133][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 157, Cad 66, HR 141, Gear 8, Res 48, Current Pos 14143, Target Pos 14143 + 139223 [1273762][E](FTMS_SERVER): 11 00 00 88 02 28 33 -> Sim Mode Incline 6.480000. Responding: 80 11 01 + 139224 [1273768][E](DirConManager): Sending response message type 0x04 to client 0 + 139225 [1275487][E](FTMS_SERVER): 11 00 00 8a 02 28 33 -> Sim Mode Incline 6.500000. Responding: 80 11 01 + 139226 [1275494][E](DirConManager): Sending response message type 0x04 to client 0 + 139227 [1276065][E](PTable): Averaged Entry: watts=135.199997, cad=75.300003, targetPosition=1393.000000, (3)(5) + 139228 [1276066][E](PTData): Cleaned 261 readings + 139229 [1276076][E](PTData): New entry recorded (3)(5)(1393) + 139230 [1276077][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 139231 [1276088][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 139232 [1276088][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 3 + 139233 [1276101][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 2 ms + 139234 [1276111][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 3 ms + 139235 [1276112][E](PTable): New Entry Processed in 48 ms + 139236 [1276112][E](PTable): Power Buffer Reset + 139237 [1276479][E](FTMS_SERVER): 11 00 00 8c 02 28 33 -> Sim Mode Incline 6.520000. Responding: 80 11 01 + 139238 [1276486][E](DirConManager): Sending response message type 0x04 to client 0 + 139239 [1277464][E](FTMS_SERVER): 11 00 00 91 02 28 33 -> Sim Mode Incline 6.570000. Responding: 80 11 01 + 139240 [1277471][E](DirConManager): Sending response message type 0x04 to client 0 + 139241 [1279144][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 110, Cad 62, HR 135, Gear 8, Res 48, Current Pos 14199, Target Pos 14199 + 139242 [1279179][E](FTMS_SERVER): 11 00 00 93 02 28 33 -> Sim Mode Incline 6.590000. Responding: 80 11 01 + 139243 [1279186][E](DirConManager): Sending response message type 0x04 to client 0 + 139244 [1280084][E](FTMS_SERVER): 11 00 00 94 02 28 33 -> Sim Mode Incline 6.600000. Responding: 80 11 01 + 139245 [1280089][E](DirConManager): Sending response message type 0x04 to client 0 + 139246 [1281108][E](FTMS_SERVER): 11 00 00 98 02 28 33 -> Sim Mode Incline 6.640000. Responding: 80 11 01 + 139247 [1281114][E](DirConManager): Sending response message type 0x04 to client 0 + 139248 [1282071][E](FTMS_SERVER): 11 00 00 9c 02 28 33 -> Sim Mode Incline 6.680000. Responding: 80 11 01 + 139249 [1282077][E](DirConManager): Sending response message type 0x04 to client 0 + 139250 [1282430][E](PTable): Averaged Entry: watts=115.800003, cad=62.400002, targetPosition=1420.199951, (0)(4) + 139251 [1282431][E](PTData): Cleaned 260 readings + 139252 [1282441][E](PTData): New entry recorded (0)(4)(1420) + 139253 [1282442][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 139254 [1282453][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 139255 [1282453][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 3 + 139256 [1282466][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139257 [1282476][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139258 [1282477][E](PTable): New Entry Processed in 48 ms + 139259 [1282477][E](PTable): Power Buffer Reset + 139260 [1283065][E](FTMS_SERVER): 11 00 00 a1 02 28 33 -> Sim Mode Incline 6.730000. Responding: 80 11 01 + 139261 [1283072][E](DirConManager): Sending response message type 0x04 to client 0 + 139262 [1283979][E](FTMS_SERVER): 11 00 00 a7 02 28 33 -> Sim Mode Incline 6.790000. Responding: 80 11 01 + 139263 [1283987][E](DirConManager): Sending response message type 0x04 to client 0 + 139264 [1284901][E](FTMS_SERVER): 11 00 00 9c 02 28 33 -> Sim Mode Incline 6.680000. Responding: 80 11 01 + 139265 [1284908][E](DirConManager): Sending response message type 0x04 to client 0 + 139266 [1285152][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 116, Cad 61, HR 134, Gear 8, Res 48, Current Pos 14283, Target Pos 14276 + 139267 [1285925][E](FTMS_SERVER): 11 00 00 92 02 28 33 -> Sim Mode Incline 6.580000. Responding: 80 11 01 + 139268 [1285932][E](DirConManager): Sending response message type 0x04 to client 0 + 139269 [1286872][E](FTMS_SERVER): 11 00 00 90 02 28 33 -> Sim Mode Incline 6.560000. Responding: 80 11 01 + 139270 [1286879][E](DirConManager): Sending response message type 0x04 to client 0 + 139271 [1287380][E](PTable): Using detected travel limits during homing + 139272 [1287871][E](FTMS_SERVER): 11 00 00 8b 02 28 33 -> Sim Mode Incline 6.510000. Responding: 80 11 01 + 139273 [1287878][E](DirConManager): Sending response message type 0x04 to client 0 + 139274 [1288788][E](PTable): Averaged Entry: watts=117.699997, cad=61.400002, targetPosition=1424.500000, (0)(4) + 139275 [1288790][E](PTData): Cleaned 259 readings + 139276 [1288800][E](PTData): Existing entry averaged (0)(4)(1421), readings(2) + 139277 [1288801][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 139278 [1288812][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 139279 [1288822][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 3 + 139280 [1288825][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139281 [1288835][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139282 [1288836][E](PTable): New Entry Processed in 48 ms + 139283 [1288836][E](PTable): Power Buffer Reset + 139284 [1288850][E](FTMS_SERVER): 11 00 00 86 02 28 33 -> Sim Mode Incline 6.460000. Responding: 80 11 01 + 139285 [1288857][E](DirConManager): Sending response message type 0x04 to client 0 + 139286 [1289931][E](FTMS_SERVER): 11 00 00 85 02 28 33 -> Sim Mode Incline 6.450000. Responding: 80 11 01 + 139287 [1289936][E](DirConManager): Sending response message type 0x04 to client 0 + 139288 [1290959][E](FTMS_SERVER): 11 00 00 7e 02 28 33 -> Sim Mode Incline 6.380000. Responding: 80 11 01 + 139289 [1290965][E](DirConManager): Sending response message type 0x04 to client 0 + 139290 [1291162][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 119, Cad 61, HR 134, Gear 8, Res 48, Current Pos 14072, Target Pos 14066 + 139291 [1291880][E](FTMS_SERVER): 11 00 00 7a 02 28 33 -> Sim Mode Incline 6.340000. Responding: 80 11 01 + 139292 [1291887][E](DirConManager): Sending response message type 0x04 to client 0 + 139293 [1292779][E](FTMS_SERVER): 11 00 00 74 02 28 33 -> Sim Mode Incline 6.280000. Responding: 80 11 01 + 139294 [1292786][E](DirConManager): Sending response message type 0x04 to client 0 + 139295 [1293706][E](FTMS_SERVER): 11 00 00 6e 02 28 33 -> Sim Mode Incline 6.220000. Responding: 80 11 01 + 139296 [1293715][E](DirConManager): Sending response message type 0x04 to client 0 + 139297 [1294630][E](FTMS_SERVER): 11 00 00 64 02 28 33 -> Sim Mode Incline 6.120000. Responding: 80 11 01 + 139298 [1294637][E](DirConManager): Sending response message type 0x04 to client 0 + 139299 [1295156][E](PTable): Averaged Entry: watts=109.400002, cad=60.000000, targetPosition=1403.599976, (0)(4) + 139300 [1295157][E](PTData): Cleaned 259 readings + 139301 [1295167][E](PTData): Existing entry averaged (0)(4)(1416), readings(3) + 139302 [1295168][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 139303 [1295179][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 139304 [1295192][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139305 [1295201][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139306 [1295202][E](PTable): New Entry Processed in 46 ms + 139307 [1295203][E](PTable): Power Buffer Reset + 139308 [1295589][E](FTMS_SERVER): 11 00 00 58 02 28 33 -> Sim Mode Incline 6.000000. Responding: 80 11 01 + 139309 [1295596][E](DirConManager): Sending response message type 0x04 to client 0 + 139310 [1296593][E](FTMS_SERVER): 11 00 00 40 02 28 33 -> Sim Mode Incline 5.760000. Responding: 80 11 01 + 139311 [1296600][E](DirConManager): Sending response message type 0x04 to client 0 + 139312 [1297173][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 104, Cad 60, HR 134, Gear 8, Res 46, Current Pos 13632, Target Pos 13632 + 139313 [1297500][E](FTMS_SERVER): 11 00 00 1e 02 28 33 -> Sim Mode Incline 5.420000. Responding: 80 11 01 + 139314 [1297506][E](DirConManager): Sending response message type 0x04 to client 0 + 139315 [1298411][E](FTMS_SERVER): 11 00 00 db 01 28 33 -> Sim Mode Incline 4.750000. Responding: 80 11 01 + 139316 [1298416][E](DirConManager): Sending response message type 0x04 to client 0 + 139317 [1299452][E](FTMS_SERVER): 11 00 00 5f 01 28 33 -> Sim Mode Incline 3.510000. Responding: 80 11 01 + 139318 [1299457][E](DirConManager): Sending response message type 0x04 to client 0 + 139319 [1300475][E](FTMS_SERVER): 11 00 00 9e 00 28 33 -> Sim Mode Incline 1.580000. Responding: 80 11 01 + 139320 [1300479][E](DirConManager): Sending response message type 0x04 to client 0 + 139321 [1301502][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 139322 [1301502][E](PTable): Power Buffer Reset + 139323 [1301506][E](FTMS_SERVER): 11 00 00 04 00 28 33 -> Sim Mode Incline 0.040000. Responding: 80 11 01 + 139324 [1301523][E](DirConManager): Sending response message type 0x04 to client 0 + 139325 [1302536][E](FTMS_SERVER): 11 00 00 d8 ff 28 33 -> Sim Mode Incline -0.400000. Responding: 80 11 01 + 139326 [1302543][E](DirConManager): Sending response message type 0x04 to client 0 + 139327 [1303184][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 85, Cad 62, HR 133, Gear 8, Res 31, Current Pos 9321, Target Pos 9320 + 139328 [1303540][E](FTMS_SERVER): 11 00 00 cb ff 28 33 -> Sim Mode Incline -0.530000. Responding: 80 11 01 + 139329 [1303548][E](DirConManager): Sending response message type 0x04 to client 0 + 139330 [1305277][E](FTMS_SERVER): 11 00 00 d2 ff 28 33 -> Sim Mode Incline -0.460000. Responding: 80 11 01 + 139331 [1305282][E](DirConManager): Sending response message type 0x04 to client 0 + 139332 [1306319][E](FTMS_SERVER): 11 00 00 e3 ff 28 33 -> Sim Mode Incline -0.290000. Responding: 80 11 01 + 139333 [1306324][E](DirConManager): Sending response message type 0x04 to client 0 + 139334 [1307241][E](FTMS_SERVER): 11 00 00 fb ff 28 33 -> Sim Mode Incline -0.050000. Responding: 80 11 01 + 139335 [1307249][E](DirConManager): Sending response message type 0x04 to client 0 + 139336 [1307858][E](PTable): Averaged Entry: watts=82.199997, cad=69.800003, targetPosition=944.599976, (2)(3) + 139337 [1307859][E](PTData): Cleaned 259 readings + 139338 [1307869][E](PTData): New entry recorded (2)(3)(944) + 139339 [1307870][E](PTData): Greater Down Found 3, 3, tp1082 + 139340 [1307883][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 3 ms + 139341 [1307884][E](PTable): New Entry Processed in 27 ms + 139342 [1307885][E](PTable): Power Buffer Reset + 139343 [1308261][E](FTMS_SERVER): 11 00 00 28 00 28 33 -> Sim Mode Incline 0.400000. Responding: 80 11 01 + 139344 [1308268][E](DirConManager): Sending response message type 0x04 to client 0 + 139345 [1309194][E](FTMS_SERVER): 11 00 00 6a 00 28 33 -> Sim Mode Incline 1.060000. Responding: 80 11 01 + 139346 [1309203][E](DirConManager): Sending response message type 0x04 to client 0 + 139347 [1309205][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 52, Cad 79, HR 130, Gear 8, Res 33, Current Pos 9880, Target Pos 9880 + 139348 [1310123][E](FTMS_SERVER): 11 00 00 a8 00 28 33 -> Sim Mode Incline 1.680000. Responding: 80 11 01 + 139349 [1310131][E](DirConManager): Sending response message type 0x04 to client 0 + 139350 [1311110][E](FTMS_SERVER): 11 00 00 ec 00 28 33 -> Sim Mode Incline 2.360000. Responding: 80 11 01 + 139351 [1311116][E](DirConManager): Sending response message type 0x04 to client 0 + 139352 [1312133][E](FTMS_SERVER): 11 00 00 42 01 28 33 -> Sim Mode Incline 3.220000. Responding: 80 11 01 + 139353 [1312140][E](DirConManager): Sending response message type 0x04 to client 0 + 139354 [1313099][E](FTMS_SERVER): 11 00 00 6c 01 28 33 -> Sim Mode Incline 3.640000. Responding: 80 11 01 + 139355 [1313106][E](DirConManager): Sending response message type 0x04 to client 0 + 139356 [1314124][E](FTMS_SERVER): 11 00 00 87 01 28 33 -> Sim Mode Incline 3.910000. Responding: 80 11 01 + 139357 [1314130][E](DirConManager): Sending response message type 0x04 to client 0 + 139358 [1314204][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 139359 [1314204][E](PTable): Power Buffer Reset + 139360 [1315123][E](FTMS_SERVER): 11 00 00 98 01 28 33 -> Sim Mode Incline 4.080000. Responding: 80 11 01 + 139361 [1315130][E](DirConManager): Sending response message type 0x04 to client 0 + 139362 [1315227][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 94, Cad 77, HR 126, Gear 8, Res 42, Current Pos 12350, Target Pos 12456 + 139363 [1316140][E](FTMS_SERVER): 11 00 00 a3 01 28 33 -> Sim Mode Incline 4.190000. Responding: 80 11 01 + 139364 [1316147][E](DirConManager): Sending response message type 0x04 to client 0 + 139365 [1317160][E](FTMS_SERVER): 11 00 00 aa 01 28 33 -> Sim Mode Incline 4.260000. Responding: 80 11 01 + 139366 [1317167][E](DirConManager): Sending response message type 0x04 to client 0 + 139367 [1317322][E](Main): Shift -1 pos 7 tgt 11382 min 0 max 29356 r_min -2000 r_max 2000 + 139368 [1317705][E](Main): Shift -1 pos 6 tgt 10182 min 0 max 29356 r_min -2000 r_max 2000 + 139369 [1318054][E](Main): Shift -1 pos 5 tgt 8982 min 0 max 29356 r_min -2000 r_max 2000 + 139370 [1318120][E](FTMS_SERVER): 11 00 00 af 01 28 33 -> Sim Mode Incline 4.310000. Responding: 80 11 01 + 139371 [1318127][E](DirConManager): Sending response message type 0x04 to client 0 + 139372 [1318383][E](Main): Shift -1 pos 4 tgt 7817 min 0 max 29356 r_min -2000 r_max 2000 + 139373 [1318695][E](Main): Shift -1 pos 3 tgt 6617 min 0 max 29356 r_min -2000 r_max 2000 + 139374 [1319014][E](Main): Shift -1 pos 2 tgt 5417 min 0 max 29356 r_min -2000 r_max 2000 + 139375 [1319119][E](FTMS_SERVER): 11 00 00 b2 01 28 33 -> Sim Mode Incline 4.340000. Responding: 80 11 01 + 139376 [1319126][E](DirConManager): Sending response message type 0x04 to client 0 + 139377 [1319139][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 139378 [1319139][E](PTable): Power Buffer Reset + 139379 [1319328][E](Main): Shift -1 pos 1 tgt 4238 min 0 max 29356 r_min -2000 r_max 2000 + 139380 [1319713][E](Main): Shift -1 pos 0 tgt 3038 min 0 max 29356 r_min -2000 r_max 2000 + 139381 [1320028][E](FTMS_SERVER): 11 00 00 af 01 28 33 -> Sim Mode Incline 4.310000. Responding: 80 11 01 + 139382 [1320034][E](DirConManager): Sending response message type 0x04 to client 0 + 139383 [1320961][E](FTMS_SERVER): 11 00 00 ad 01 28 33 -> Sim Mode Incline 4.290000. Responding: 80 11 01 + 139384 [1320966][E](DirConManager): Sending response message type 0x04 to client 0 + 139385 [1321240][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 112, Cad 78, HR 124, Gear 0, Res 11, Current Pos 3010, Target Pos 3003 + 139386 [1321251][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 139387 [1321251][E](PTable): Power Buffer Reset + 139388 [1321966][E](FTMS_SERVER): 11 00 00 a9 01 28 33 -> Sim Mode Incline 4.250000. Responding: 80 11 01 + 139389 [1321971][E](DirConManager): Sending response message type 0x04 to client 0 + 139390 [1322988][E](FTMS_SERVER): 11 00 00 a5 01 28 33 -> Sim Mode Incline 4.210000. Responding: 80 11 01 + 139391 [1322994][E](DirConManager): Sending response message type 0x04 to client 0 + 139392 [1323368][E](PTable): Using detected travel limits during homing + 139393 [1324021][E](FTMS_SERVER): 11 00 00 a0 01 28 33 -> Sim Mode Incline 4.160000. Responding: 80 11 01 + 139394 [1324026][E](DirConManager): Sending response message type 0x04 to client 0 + 139395 [1324941][E](FTMS_SERVER): 11 00 00 9b 01 28 33 -> Sim Mode Incline 4.110000. Responding: 80 11 01 + 139396 [1324949][E](DirConManager): Sending response message type 0x04 to client 0 + 139397 [1325963][E](FTMS_SERVER): 11 00 00 95 01 28 33 -> Sim Mode Incline 4.050000. Responding: 80 11 01 + 139398 [1325970][E](DirConManager): Sending response message type 0x04 to client 0 + 139399 [1326927][E](FTMS_SERVER): 11 00 00 91 01 28 33 -> Sim Mode Incline 4.010000. Responding: 80 11 01 + 139400 [1326934][E](DirConManager): Sending response message type 0x04 to client 0 + 139401 [1327253][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 83, HR 122, Gear 0, Res 9, Current Pos 2807, Target Pos 2807 + 139402 [1327923][E](FTMS_SERVER): 11 00 00 94 01 28 33 -> Sim Mode Incline 4.040000. Responding: 80 11 01 + 139403 [1327930][E](DirConManager): Sending response message type 0x04 to client 0 + 139404 [1328827][E](FTMS_SERVER): 11 00 00 96 01 28 33 -> Sim Mode Incline 4.060000. Responding: 80 11 01 + 139405 [1328832][E](DirConManager): Sending response message type 0x04 to client 0 + 139406 [1329774][E](FTMS_SERVER): 11 00 00 92 01 28 33 -> Sim Mode Incline 4.020000. Responding: 80 11 01 + 139407 [1329778][E](DirConManager): Sending response message type 0x04 to client 0 + 139408 [1330418][E](PTable): Averaged Entry: watts=25.000000, cad=85.000000, targetPosition=291.200012, (5)(1) + 139409 [1330419][E](PTData): Cleaned 1 readings + 139410 [1330429][E](PTData): New entry recorded (5)(1)(291) + 139411 [1330430][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 139412 [1330441][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 139413 [1330444][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139414 [1330464][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 2 ms + 139415 [1330466][E](PTable): New Entry Processed in 49 ms + 139416 [1330466][E](PTable): Power Buffer Reset + 139417 [1330781][E](FTMS_SERVER): 11 00 00 90 01 28 33 -> Sim Mode Incline 4.000000. Responding: 80 11 01 + 139418 [1330788][E](DirConManager): Sending response message type 0x04 to client 0 + 139419 [1331728][E](FTMS_SERVER): 11 00 00 8e 01 28 33 -> Sim Mode Incline 3.980000. Responding: 80 11 01 + 139420 [1331735][E](DirConManager): Sending response message type 0x04 to client 0 + 139421 [1333268][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 3, Cad 88, HR 121, Gear 0, Res 9, Current Pos 2786, Target Pos 2786 + 139422 [1333457][E](FTMS_SERVER): 11 00 00 8d 01 28 33 -> Sim Mode Incline 3.970000. Responding: 80 11 01 + 139423 [1333462][E](DirConManager): Sending response message type 0x04 to client 0 + 139424 [1334985][E](Main): Shift +1 pos 1 tgt 3979 min 0 max 29356 r_min -2000 r_max 2000 + 139425 [1335884][E](Main): Shift +1 pos 2 tgt 5179 min 0 max 29356 r_min -2000 r_max 2000 + 139426 [1336711][E](FTMS_SERVER): 11 00 00 8f 01 28 33 -> Sim Mode Incline 3.990000. Responding: 80 11 01 + 139427 [1336718][E](DirConManager): Sending response message type 0x04 to client 0 + 139428 [1337655][E](FTMS_SERVER): 11 00 00 8e 01 28 33 -> Sim Mode Incline 3.980000. Responding: 80 11 01 + 139429 [1337659][E](DirConManager): Sending response message type 0x04 to client 0 + 139430 [1338566][E](FTMS_SERVER): 11 00 00 8c 01 28 33 -> Sim Mode Incline 3.960000. Responding: 80 11 01 + 139431 [1338573][E](DirConManager): Sending response message type 0x04 to client 0 + 139432 [1339286][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 5, Cad 90, HR 116, Gear 2, Res 17, Current Pos 5172, Target Pos 5172 + 139433 [1339593][E](FTMS_SERVER): 11 00 00 8d 01 28 33 -> Sim Mode Incline 3.970000. Responding: 80 11 01 + 139434 [1339600][E](DirConManager): Sending response message type 0x04 to client 0 + 139435 [1340534][E](FTMS_SERVER): 11 00 00 8c 01 28 33 -> Sim Mode Incline 3.960000. Responding: 80 11 01 + 139436 [1340541][E](DirConManager): Sending response message type 0x04 to client 0 + 139437 [1341536][E](FTMS_SERVER): 11 00 00 8a 01 28 33 -> Sim Mode Incline 3.940000. Responding: 80 11 01 + 139438 [1341543][E](DirConManager): Sending response message type 0x04 to client 0 + 139439 [1342458][E](FTMS_SERVER): 11 00 00 8c 01 28 33 -> Sim Mode Incline 3.960000. Responding: 80 11 01 + 139440 [1342463][E](DirConManager): Sending response message type 0x04 to client 0 + 139441 [1343490][E](FTMS_SERVER): 11 00 00 8a 01 28 33 -> Sim Mode Incline 3.940000. Responding: 80 11 01 + 139442 [1343496][E](DirConManager): Sending response message type 0x04 to client 0 + 139443 [1345302][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 8, Cad 87, HR 112, Gear 2, Res 17, Current Pos 5158, Target Pos 5158 + 139444 [1346032][E](FTMS_SERVER): 11 00 00 87 01 28 33 -> Sim Mode Incline 3.910000. Responding: 80 11 01 + 139445 [1346037][E](DirConManager): Sending response message type 0x04 to client 0 + 139446 [1346971][E](FTMS_SERVER): 11 00 00 88 01 28 33 -> Sim Mode Incline 3.920000. Responding: 80 11 01 + 139447 [1346978][E](DirConManager): Sending response message type 0x04 to client 0 + 139448 [1347989][E](FTMS_SERVER): 11 00 00 89 01 28 33 -> Sim Mode Incline 3.930000. Responding: 80 11 01 + 139449 [1347997][E](DirConManager): Sending response message type 0x04 to client 0 + 139450 [1348947][E](FTMS_SERVER): 11 00 00 87 01 28 33 -> Sim Mode Incline 3.910000. Responding: 80 11 01 + 139451 [1348954][E](DirConManager): Sending response message type 0x04 to client 0 + 139452 [1349938][E](FTMS_SERVER): 11 00 00 88 01 28 33 -> Sim Mode Incline 3.920000. Responding: 80 11 01 + 139453 [1349945][E](DirConManager): Sending response message type 0x04 to client 0 + 139454 [1350844][E](FTMS_SERVER): 11 00 00 8a 01 28 33 -> Sim Mode Incline 3.940000. Responding: 80 11 01 + 139455 [1350850][E](DirConManager): Sending response message type 0x04 to client 0 + 139456 [1351320][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 18, Cad 86, HR 111, Gear 2, Res 17, Current Pos 5158, Target Pos 5158 + 139457 [1351769][E](FTMS_SERVER): 11 00 00 87 01 28 33 -> Sim Mode Incline 3.910000. Responding: 80 11 01 + 139458 [1351774][E](DirConManager): Sending response message type 0x04 to client 0 + 139459 [1352695][E](FTMS_SERVER): 11 00 00 85 01 28 33 -> Sim Mode Incline 3.890000. Responding: 80 11 01 + 139460 [1352702][E](DirConManager): Sending response message type 0x04 to client 0 + 139461 [1353656][E](FTMS_SERVER): 11 00 00 82 01 28 33 -> Sim Mode Incline 3.860000. Responding: 80 11 01 + 139462 [1353663][E](DirConManager): Sending response message type 0x04 to client 0 + 139463 [1354645][E](FTMS_SERVER): 11 00 00 80 01 28 33 -> Sim Mode Incline 3.840000. Responding: 80 11 01 + 139464 [1354652][E](DirConManager): Sending response message type 0x04 to client 0 + 139465 [1355567][E](FTMS_SERVER): 11 00 00 7c 01 28 33 -> Sim Mode Incline 3.800000. Responding: 80 11 01 + 139466 [1355572][E](DirConManager): Sending response message type 0x04 to client 0 + 139467 [1355845][E](PTable): Averaged Entry: watts=26.400000, cad=93.500000, targetPosition=490.100006, (7)(1) + 139468 [1355846][E](PTData): Cleaned 259 readings + 139469 [1355856][E](PTData): New entry recorded (7)(1)(490) + 139470 [1355857][E](PTData): Lower Up Found 5, 1, tp291 + 139471 [1355860][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 3 ms + 139472 [1355871][E](PTable): New Entry Processed in 27 ms + 139473 [1355871][E](PTable): Power Buffer Reset + 139474 [1357303][E](FTMS_SERVER): 11 00 00 79 01 28 33 -> Sim Mode Incline 3.770000. Responding: 80 11 01 + 139475 [1357310][E](DirConManager): Sending response message type 0x04 to client 0 + 139476 [1357334][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 8, Cad 103, HR 109, Gear 2, Res 17, Current Pos 5059, Target Pos 5039 + 139477 [1358245][E](FTMS_SERVER): 11 00 00 78 01 28 33 -> Sim Mode Incline 3.760000. Responding: 80 11 01 + 139478 [1358253][E](DirConManager): Sending response message type 0x04 to client 0 + 139479 [1359251][E](FTMS_SERVER): 11 00 00 77 01 28 33 -> Sim Mode Incline 3.750000. Responding: 80 11 01 + 139480 [1359259][E](DirConManager): Sending response message type 0x04 to client 0 + 139481 [1359363][E](PTable): Using detected travel limits during homing + 139482 [1360178][E](FTMS_SERVER): 11 00 00 75 01 28 33 -> Sim Mode Incline 3.730000. Responding: 80 11 01 + 139483 [1360183][E](DirConManager): Sending response message type 0x04 to client 0 + 139484 [1361104][E](FTMS_SERVER): 11 00 00 74 01 28 33 -> Sim Mode Incline 3.720000. Responding: 80 11 01 + 139485 [1361111][E](DirConManager): Sending response message type 0x04 to client 0 + 139486 [1362114][E](FTMS_SERVER): 11 00 00 73 01 28 33 -> Sim Mode Incline 3.710000. Responding: 80 11 01 + 139487 [1362121][E](DirConManager): Sending response message type 0x04 to client 0 + 139488 [1363053][E](FTMS_SERVER): 11 00 00 72 01 28 33 -> Sim Mode Incline 3.700000. Responding: 80 11 01 + 139489 [1363060][E](DirConManager): Sending response message type 0x04 to client 0 + 139490 [1363352][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 13, Cad 107, HR 110, Gear 2, Res 16, Current Pos 4990, Target Pos 4990 + 139491 [1363953][E](FTMS_SERVER): 11 00 00 71 01 28 33 -> Sim Mode Incline 3.690000. Responding: 80 11 01 + 139492 [1363960][E](DirConManager): Sending response message type 0x04 to client 0 + 139493 [1364875][E](FTMS_SERVER): 11 00 00 6f 01 28 33 -> Sim Mode Incline 3.670000. Responding: 80 11 01 + 139494 [1364880][E](DirConManager): Sending response message type 0x04 to client 0 + 139495 [1365898][E](FTMS_SERVER): 11 00 00 6d 01 28 33 -> Sim Mode Incline 3.650000. Responding: 80 11 01 + 139496 [1365904][E](DirConManager): Sending response message type 0x04 to client 0 + 139497 [1366864][E](FTMS_SERVER): 11 00 00 70 01 28 33 -> Sim Mode Incline 3.680000. Responding: 80 11 01 + 139498 [1366871][E](DirConManager): Sending response message type 0x04 to client 0 + 139499 [1367959][E](FTMS_SERVER): 11 00 00 71 01 28 33 -> Sim Mode Incline 3.690000. Responding: 80 11 01 + 139500 [1367964][E](DirConManager): Sending response message type 0x04 to client 0 + 139501 [1368886][E](FTMS_SERVER): 11 00 00 6c 01 28 33 -> Sim Mode Incline 3.640000. Responding: 80 11 01 + 139502 [1368894][E](DirConManager): Sending response message type 0x04 to client 0 + 139503 [1369361][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 12, Cad 103, HR 111, Gear 2, Res 16, Current Pos 4948, Target Pos 4948 + 139504 [1372146][E](FTMS_SERVER): 11 00 00 6a 01 28 33 -> Sim Mode Incline 3.620000. Responding: 80 11 01 + 139505 [1372150][E](DirConManager): Sending response message type 0x04 to client 0 + 139506 [1373179][E](FTMS_SERVER): 11 00 00 69 01 28 33 -> Sim Mode Incline 3.610000. Responding: 80 11 01 + 139507 [1373184][E](DirConManager): Sending response message type 0x04 to client 0 + 139508 [1374910][E](FTMS_SERVER): 11 00 00 66 01 28 33 -> Sim Mode Incline 3.580000. Responding: 80 11 01 + 139509 [1374915][E](DirConManager): Sending response message type 0x04 to client 0 + 139510 [1375372][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 11, Cad 104, HR 113, Gear 2, Res 16, Current Pos 4906, Target Pos 4906 + 139511 [1376566][E](FTMS_SERVER): 11 00 00 64 01 28 33 -> Sim Mode Incline 3.560000. Responding: 80 11 01 + 139512 [1376573][E](DirConManager): Sending response message type 0x04 to client 0 + 139513 [1377469][E](FTMS_SERVER): 11 00 00 63 01 28 33 -> Sim Mode Incline 3.550000. Responding: 80 11 01 + 139514 [1377474][E](DirConManager): Sending response message type 0x04 to client 0 + 139515 [1379218][E](FTMS_SERVER): 11 00 00 61 01 28 33 -> Sim Mode Incline 3.530000. Responding: 80 11 01 + 139516 [1379226][E](DirConManager): Sending response message type 0x04 to client 0 + 139517 [1380241][E](FTMS_SERVER): 11 00 00 5f 01 28 33 -> Sim Mode Incline 3.510000. Responding: 80 11 01 + 139518 [1380248][E](DirConManager): Sending response message type 0x04 to client 0 + 139519 [1380545][E](PTable): Averaged Entry: watts=15.000000, cad=103.199997, targetPosition=493.700012, (9)(1) + 139520 [1380546][E](PTData): Cleaned 1 readings + 139521 [1380556][E](PTData): New entry recorded (9)(1)(493) + 139522 [1380557][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 139523 [1380568][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 139524 [1380571][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139525 [1380590][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 2 ms + 139526 [1380592][E](PTable): New Entry Processed in 47 ms + 139527 [1380592][E](PTable): Power Buffer Reset + 139528 [1381389][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 5, Cad 98, HR 114, Gear 2, Res 16, Current Pos 4857, Target Pos 4857 + 139529 [1382702][E](FTMS_SERVER): 11 00 00 5e 01 28 33 -> Sim Mode Incline 3.500000. Responding: 80 11 01 + 139530 [1382707][E](DirConManager): Sending response message type 0x04 to client 0 + 139531 [1383712][E](FTMS_SERVER): 11 00 00 5c 01 28 33 -> Sim Mode Incline 3.480000. Responding: 80 11 01 + 139532 [1383717][E](DirConManager): Sending response message type 0x04 to client 0 + 139533 [1385380][E](FTMS_SERVER): 11 00 00 5a 01 28 33 -> Sim Mode Incline 3.460000. Responding: 80 11 01 + 139534 [1385387][E](DirConManager): Sending response message type 0x04 to client 0 + 139535 [1386284][E](FTMS_SERVER): 11 00 00 59 01 28 33 -> Sim Mode Incline 3.450000. Responding: 80 11 01 + 139536 [1386290][E](DirConManager): Sending response message type 0x04 to client 0 + 139537 [1387195][E](FTMS_SERVER): 11 00 00 58 01 28 33 -> Sim Mode Incline 3.440000. Responding: 80 11 01 + 139538 [1387203][E](DirConManager): Sending response message type 0x04 to client 0 + 139539 [1387357][E](Main): Shift +1 pos 3 tgt 6008 min 0 max 29356 r_min -2000 r_max 2000 + 139540 [1387400][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 5, Cad 102, HR 113, Gear 3, Res 16, Current Pos 4814, Target Pos 6008 + 139541 [1387848][E](Main): Shift +1 pos 4 tgt 7208 min 0 max 29356 r_min -2000 r_max 2000 + 139542 [1388170][E](Main): Shift +1 pos 5 tgt 8408 min 0 max 29356 r_min -2000 r_max 2000 + 139543 [1388236][E](FTMS_SERVER): 11 00 00 57 01 28 33 -> Sim Mode Incline 3.430000. Responding: 80 11 01 + 139544 [1388243][E](DirConManager): Sending response message type 0x04 to client 0 + 139545 [1388611][E](Main): Shift +1 pos 6 tgt 9601 min 0 max 29356 r_min -2000 r_max 2000 + 139546 [1388940][E](Main): Shift +1 pos 7 tgt 10801 min 0 max 29356 r_min -2000 r_max 2000 + 139547 [1389186][E](FTMS_SERVER): 11 00 00 56 01 28 33 -> Sim Mode Incline 3.420000. Responding: 80 11 01 + 139548 [1389193][E](DirConManager): Sending response message type 0x04 to client 0 + 139549 [1389709][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 139550 [1389709][E](PTable): Power Buffer Reset + 139551 [1390189][E](FTMS_SERVER): 11 00 00 55 01 28 33 -> Sim Mode Incline 3.410000. Responding: 80 11 01 + 139552 [1390196][E](DirConManager): Sending response message type 0x04 to client 0 + 139553 [1391090][E](FTMS_SERVER): 11 00 00 54 01 28 33 -> Sim Mode Incline 3.400000. Responding: 80 11 01 + 139554 [1391095][E](DirConManager): Sending response message type 0x04 to client 0 + 139555 [1392033][E](FTMS_SERVER): 11 00 00 51 01 28 33 -> Sim Mode Incline 3.370000. Responding: 80 11 01 + 139556 [1392038][E](DirConManager): Sending response message type 0x04 to client 0 + 139557 [1393054][E](FTMS_SERVER): 11 00 00 4e 01 28 33 -> Sim Mode Incline 3.340000. Responding: 80 11 01 + 139558 [1393060][E](DirConManager): Sending response message type 0x04 to client 0 + 139559 [1393414][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 104, Cad 100, HR 109, Gear 7, Res 36, Current Pos 10738, Target Pos 10738 + 139560 [1394077][E](FTMS_SERVER): 11 00 00 49 01 28 33 -> Sim Mode Incline 3.290000. Responding: 80 11 01 + 139561 [1394084][E](DirConManager): Sending response message type 0x04 to client 0 + 139562 [1394994][E](FTMS_SERVER): 11 00 00 40 01 28 33 -> Sim Mode Incline 3.200000. Responding: 80 11 01 + 139563 [1395001][E](DirConManager): Sending response message type 0x04 to client 0 + 139564 [1395359][E](PTable): Using detected travel limits during homing + 139565 [1395896][E](FTMS_SERVER): 11 00 00 37 01 28 33 -> Sim Mode Incline 3.110000. Responding: 80 11 01 + 139566 [1395904][E](DirConManager): Sending response message type 0x04 to client 0 + 139567 [1396068][E](PTable): Averaged Entry: watts=83.500000, cad=100.500000, targetPosition=1072.599976, (8)(3) + 139568 [1396069][E](PTData): Cleaned 259 readings + 139569 [1396079][E](PTData): New entry recorded (8)(3)(1072) + 139570 [1396080][E](PTData): Lower Up Found 4, 3, tp1017 + 139571 [1396093][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139572 [1396094][E](PTable): New Entry Processed in 26 ms + 139573 [1396095][E](PTable): Power Buffer Reset + 139574 [1396825][E](FTMS_SERVER): 11 00 00 2d 01 28 33 -> Sim Mode Incline 3.010000. Responding: 80 11 01 + 139575 [1396830][E](DirConManager): Sending response message type 0x04 to client 0 + 139576 [1397858][E](FTMS_SERVER): 11 00 00 22 01 28 33 -> Sim Mode Incline 2.900000. Responding: 80 11 01 + 139577 [1397863][E](DirConManager): Sending response message type 0x04 to client 0 + 139578 [1398871][E](FTMS_SERVER): 11 00 00 15 01 28 33 -> Sim Mode Incline 2.770000. Responding: 80 11 01 + 139579 [1398877][E](DirConManager): Sending response message type 0x04 to client 0 + 139580 [1399425][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 102, Cad 100, HR 109, Gear 7, Res 35, Current Pos 10339, Target Pos 10339 + 139581 [1399914][E](FTMS_SERVER): 11 00 00 05 01 28 33 -> Sim Mode Incline 2.610000. Responding: 80 11 01 + 139582 [1399919][E](DirConManager): Sending response message type 0x04 to client 0 + 139583 [1400831][E](FTMS_SERVER): 11 00 00 f6 00 28 33 -> Sim Mode Incline 2.460000. Responding: 80 11 01 + 139584 [1400838][E](DirConManager): Sending response message type 0x04 to client 0 + 139585 [1401853][E](FTMS_SERVER): 11 00 00 e7 00 28 33 -> Sim Mode Incline 2.310000. Responding: 80 11 01 + 139586 [1401860][E](DirConManager): Sending response message type 0x04 to client 0 + 139587 [1402413][E](PTable): Averaged Entry: watts=103.699997, cad=100.300003, targetPosition=1033.599976, (8)(3) + 139588 [1402414][E](PTData): New entry recorded (8)(3)(1033) + 139589 [1402424][E](PTData): Lower Up Found 4, 3, tp1017 + 139590 [1402427][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 2 ms + 139591 [1402429][E](PTable): New Entry Processed in 17 ms + 139592 [1402439][E](PTable): Power Buffer Reset + 139593 [1402802][E](FTMS_SERVER): 11 00 00 d5 00 28 33 -> Sim Mode Incline 2.130000. Responding: 80 11 01 + 139594 [1402809][E](DirConManager): Sending response message type 0x04 to client 0 + 139595 [1403802][E](FTMS_SERVER): 11 00 00 c4 00 28 33 -> Sim Mode Incline 1.960000. Responding: 80 11 01 + 139596 [1403809][E](DirConManager): Sending response message type 0x04 to client 0 + 139597 [1404706][E](FTMS_SERVER): 11 00 00 b2 00 28 33 -> Sim Mode Incline 1.780000. Responding: 80 11 01 + 139598 [1404711][E](DirConManager): Sending response message type 0x04 to client 0 + 139599 [1405442][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 82, Cad 100, HR 112, Gear 7, Res 32, Current Pos 9646, Target Pos 9646 + 139600 [1405639][E](FTMS_SERVER): 11 00 00 9f 00 28 33 -> Sim Mode Incline 1.590000. Responding: 80 11 01 + 139601 [1405644][E](DirConManager): Sending response message type 0x04 to client 0 + 139602 [1406668][E](FTMS_SERVER): 11 00 00 8e 00 28 33 -> Sim Mode Incline 1.420000. Responding: 80 11 01 + 139603 [1406673][E](DirConManager): Sending response message type 0x04 to client 0 + 139604 [1407689][E](FTMS_SERVER): 11 00 00 79 00 28 33 -> Sim Mode Incline 1.210000. Responding: 80 11 01 + 139605 [1407696][E](DirConManager): Sending response message type 0x04 to client 0 + 139606 [1408609][E](FTMS_SERVER): 11 00 00 64 00 28 33 -> Sim Mode Incline 1.000000. Responding: 80 11 01 + 139607 [1408616][E](DirConManager): Sending response message type 0x04 to client 0 + 139608 [1408763][E](PTable): Averaged Entry: watts=85.099998, cad=99.599998, targetPosition=959.900024, (8)(3) + 139609 [1408765][E](PTData): Cleaned 1 readings + 139610 [1408775][E](PTData): New entry recorded (8)(3)(959) + 139611 [1408776][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 139612 [1408787][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 139613 [1408790][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139614 [1408811][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139615 [1408812][E](PTable): New Entry Processed in 49 ms + 139616 [1408813][E](PTable): Power Buffer Reset + 139617 [1409517][E](FTMS_SERVER): 11 00 00 50 00 28 33 -> Sim Mode Incline 0.800000. Responding: 80 11 01 + 139618 [1409524][E](DirConManager): Sending response message type 0x04 to client 0 + 139619 [1410440][E](FTMS_SERVER): 11 00 00 3d 00 28 33 -> Sim Mode Incline 0.610000. Responding: 80 11 01 + 139620 [1410446][E](DirConManager): Sending response message type 0x04 to client 0 + 139621 [1411403][E](FTMS_SERVER): 11 00 00 28 00 28 33 -> Sim Mode Incline 0.400000. Responding: 80 11 01 + 139622 [1411409][E](DirConManager): Sending response message type 0x04 to client 0 + 139623 [1411452][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 61, Cad 98, HR 113, Gear 7, Res 30, Current Pos 8823, Target Pos 8680 + 139624 [1412488][E](FTMS_SERVER): 11 00 00 12 00 28 33 -> Sim Mode Incline 0.180000. Responding: 80 11 01 + 139625 [1412492][E](DirConManager): Sending response message type 0x04 to client 0 + 139626 [1413521][E](FTMS_SERVER): 11 00 00 fe ff 28 33 -> Sim Mode Incline -0.020000. Responding: 80 11 01 + 139627 [1413526][E](DirConManager): Sending response message type 0x04 to client 0 + 139628 [1414452][E](FTMS_SERVER): 11 00 00 f3 ff 28 33 -> Sim Mode Incline -0.130000. Responding: 80 11 01 + 139629 [1414459][E](DirConManager): Sending response message type 0x04 to client 0 + 139630 [1415138][E](PTable): Averaged Entry: watts=58.099998, cad=98.400002, targetPosition=870.900024, (8)(2) + 139631 [1415140][E](PTData): Cleaned 259 readings + 139632 [1415150][E](PTData): New entry recorded (8)(2)(870) + 139633 [1415151][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 139634 [1415162][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 139635 [1415165][E](PTData): Fit Valid: 1, N: 42, Quad: 1, Time: 3 ms + 139636 [1415184][E](PTData): Fit Valid: 1, N: 42, Quad: 1, Time: 2 ms + 139637 [1415186][E](PTable): New Entry Processed in 48 ms + 139638 [1415186][E](PTable): Power Buffer Reset + 139639 [1415463][E](FTMS_SERVER): 11 00 00 e8 ff 28 33 -> Sim Mode Incline -0.240000. Responding: 80 11 01 + 139640 [1415470][E](DirConManager): Sending response message type 0x04 to client 0 + 139641 [1416421][E](FTMS_SERVER): 11 00 00 dc ff 28 33 -> Sim Mode Incline -0.360000. Responding: 80 11 01 + 139642 [1416428][E](DirConManager): Sending response message type 0x04 to client 0 + 139643 [1417422][E](FTMS_SERVER): 11 00 00 d1 ff 28 33 -> Sim Mode Incline -0.470000. Responding: 80 11 01 + 139644 [1417429][E](DirConManager): Sending response message type 0x04 to client 0 + 139645 [1417463][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 41, Cad 97, HR 114, Gear 7, Res 27, Current Pos 8146, Target Pos 8071 + 139646 [1418240][E](FTMS_SERVER): 05 b9 00 -> ERG Mode Target: 185 Current: 37 Incline: -0.470000. Responding: 80 05 01 + 139647 [1418245][E](DirConManager): Sending response message type 0x04 to client 0 + 139648 [1418675][E](ERG_Mode): Proportional: 2960.000000 + 139649 [1420791][E](ERG_Mode): Watts previously processed. + 139650 [1421501][E](PTable): Averaged Entry: watts=44.799999, cad=97.000000, targetPosition=818.599976, (7)(1) + 139651 [1421502][E](PTData): Cleaned 258 readings + 139652 [1421512][E](PTData): New entry recorded (7)(1)(818) + 139653 [1421513][E](PTData): Lower Up Found 4, 1, tp779 + 139654 [1421516][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139655 [1421527][E](PTable): New Entry Processed in 26 ms + 139656 [1421527][E](PTable): Power Buffer Reset + 139657 [1423473][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 52, Cad 100, HR 115, Gear 7, Res 39, Current Pos 11662, Target Pos 11254 + 139658 [1423615][E](ERG_Mode): Watts previously processed. + 139659 [1424159][E](FTMS_SERVER): 11 00 00 64 00 28 33 -> Sim Mode Incline 1.000000. Responding: 80 11 01 + 139660 [1424167][E](DirConManager): Sending response message type 0x04 to client 0 + 139661 [1426890][E](Main): Shift +1 pos 8 tgt 10300 min 0 max 29356 r_min -2000 r_max 2000 + 139662 [1427290][E](Main): Shift +1 pos 9 tgt 11500 min 0 max 29356 r_min -2000 r_max 2000 + 139663 [1427847][E](PTable): Averaged Entry: watts=88.400002, cad=101.099998, targetPosition=1003.000000, (8)(3) + 139664 [1427850][E](PTData): Cleaned 1 readings + 139665 [1427860][E](PTData): Existing entry averaged (8)(3)(973), readings(2) + 139666 [1427861][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 139667 [1427872][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 139668 [1427885][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139669 [1427894][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 2 ms + 139670 [1427896][E](PTable): New Entry Processed in 49 ms + 139671 [1427896][E](PTable): Power Buffer Reset + 139672 [1429484][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 128, Cad 101, HR 115, Gear 9, Res 39, Current Pos 11500, Target Pos 11500 + 139673 [1431375][E](PTable): Using detected travel limits during homing + 139674 [1434200][E](PTable): Averaged Entry: watts=116.000000, cad=100.699997, targetPosition=1149.599976, (8)(4) + 139675 [1434201][E](PTData): Cleaned 259 readings + 139676 [1434211][E](PTData): New entry recorded (8)(4)(1149) + 139677 [1434211][E](PTData): Lower Up Found 7, 4, tp1102 + 139678 [1434225][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139679 [1434226][E](PTable): New Entry Processed in 27 ms + 139680 [1434226][E](PTable): Power Buffer Reset + 139681 [1435495][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 144, Cad 100, HR 116, Gear 9, Res 39, Current Pos 11500, Target Pos 11500 + 139682 [1437973][E](Main): Shift +1 pos 10 tgt 12700 min 0 max 29356 r_min -2000 r_max 2000 + 139683 [1438450][E](Main): Shift +1 pos 11 tgt 13900 min 0 max 29356 r_min -2000 r_max 2000 + 139684 [1440549][E](PTable): Averaged Entry: watts=158.000000, cad=101.199997, targetPosition=1220.000000, (8)(5) + 139685 [1440550][E](PTData): New entry recorded (8)(5)(1220) + 139686 [1440560][E](PTData): Lower Up Found 7, 5, tp1164 + 139687 [1440563][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139688 [1440565][E](PTable): New Entry Processed in 17 ms + 139689 [1440575][E](PTable): Power Buffer Reset + 139690 [1441508][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 212, Cad 105, HR 118, Gear 11, Res 47, Current Pos 13900, Target Pos 13900 + 139691 [1446895][E](PTable): Averaged Entry: watts=256.500000, cad=100.599998, targetPosition=1390.000000, (8)(9) + 139692 [1446896][E](PTData): Existing entry averaged (8)(9)(1354), readings(3) + 139693 [1446907][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139694 [1446920][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139695 [1446930][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139696 [1446931][E](PTable): New Entry Processed in 37 ms + 139697 [1446931][E](PTable): Power Buffer Reset + 139698 [1447523][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 266, Cad 99, HR 120, Gear 11, Res 47, Current Pos 13900, Target Pos 13900 + 139699 [1453256][E](PTable): Averaged Entry: watts=238.399994, cad=95.000000, targetPosition=1390.000000, (7)(8) + 139700 [1453257][E](PTData): Cleaned 259 readings + 139701 [1453267][E](PTData): Existing entry averaged (7)(8)(1363), readings(16) + 139702 [1453268][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139703 [1453282][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139704 [1453291][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139705 [1453292][E](PTable): New Entry Processed in 37 ms + 139706 [1453292][E](PTable): Power Buffer Reset + 139707 [1453535][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 163, Cad 86, HR 122, Gear 11, Res 47, Current Pos 13900, Target Pos 13900 + 139708 [1455599][E](FTMS_SERVER): 05 b9 00 -> ERG Mode Target: 185 Current: 206 Incline: 1.000000. Responding: 80 05 01 + 139709 [1455606][E](DirConManager): Sending response message type 0x04 to client 0 + 139710 [1455961][E](FTMS_SERVER): 05 aa 00 -> ERG Mode Target: 170 Current: 187 Incline: 1.000000. Responding: 80 05 01 + 139711 [1455967][E](DirConManager): Sending response message type 0x04 to client 0 + 139712 [1456071][E](ERG_Mode): Proportional: -51.000000 + 139713 [1456776][E](ERG_Mode): Watts previously processed. + 139714 [1458888][E](ERG_Mode): Watts previously processed. + 139715 [1459549][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 176, Cad 81, HR 126, Gear 11, Res 45, Current Pos 13468, Target Pos 13468 + 139716 [1459590][E](PTable): Averaged Entry: watts=176.699997, cad=80.400002, targetPosition=1362.500000, (4)(6) + 139717 [1459591][E](PTData): Cleaned 259 readings + 139718 [1459601][E](PTData): Existing entry averaged (4)(6)(1407), readings(3) + 139719 [1459602][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139720 [1459615][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139721 [1459624][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 2 ms + 139722 [1459626][E](PTable): New Entry Processed in 36 ms + 139723 [1459626][E](PTable): Power Buffer Reset + 139724 [1461002][E](ERG_Mode): Watts previously processed. + 139725 [1461711][E](ERG_Mode): Proportional: -8.000000 + 139726 [1463115][E](ERG_Mode): Watts previously processed. + 139727 [1465231][E](ERG_Mode): Watts previously processed. + 139728 [1465558][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 226, Cad 85, HR 129, Gear 11, Res 45, Current Pos 13407, Target Pos 13407 + 139729 [1465935][E](PTable): Averaged Entry: watts=180.500000, cad=81.300003, targetPosition=1344.099976, (4)(6) + 139730 [1465937][E](PTData): Cleaned 259 readings + 139731 [1465947][E](PTData): Existing entry averaged (4)(6)(1394), readings(4) + 139732 [1465948][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139733 [1465962][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139734 [1465971][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139735 [1465972][E](PTable): New Entry Processed in 37 ms + 139736 [1466039][E](PTable): Writing File: /PowerTable.txt + 139737 [1466276][E](PTable): Power table saved successfully with 477 readings + 139738 [1466276][E](PTable): Power Buffer Reset + 139739 [1466639][E](ERG_Mode): Watts previously processed. + 139740 [1467349][E](ERG_Mode): Proportional: -111.000000 + 139741 [1467350][E](PTable): Using detected travel limits during homing + 139742 [1468752][E](ERG_Mode): Watts previously processed. + 139743 [1470870][E](ERG_Mode): Watts previously processed. + 139744 [1471572][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 206, Cad 87, HR 131, Gear 11, Res 44, Current Pos 12989, Target Pos 12989 + 139745 [1472281][E](PTable): Averaged Entry: watts=196.000000, cad=87.000000, targetPosition=1306.000000, (5)(7) + 139746 [1472283][E](PTData): Cleaned 259 readings + 139747 [1472293][E](PTData): Existing entry averaged (5)(7)(1399), readings(8) + 139748 [1472294][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139749 [1472308][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139750 [1472317][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139751 [1472318][E](PTable): New Entry Processed in 37 ms + 139752 [1472318][E](PTable): Power Buffer Reset + 139753 [1472988][E](ERG_Mode): Watts previously processed. + 139754 [1473695][E](ERG_Mode): Proportional: -36.000000 + 139755 [1475106][E](ERG_Mode): Watts previously processed. + 139756 [1476511][E](ERG_Mode): Watts previously processed. + 139757 [1477585][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 169, Cad 87, HR 134, Gear 11, Res 43, Current Pos 12785, Target Pos 12785 + 139758 [1478625][E](PTable): Averaged Entry: watts=175.500000, cad=88.500000, targetPosition=1278.900024, (6)(6) + 139759 [1478627][E](PTData): Cleaned 259 readings + 139760 [1478637][E](PTData): Existing entry averaged (6)(6)(1270), readings(14) + 139761 [1478638][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139762 [1478652][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139763 [1478661][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139764 [1478662][E](PTable): New Entry Processed in 38 ms + 139765 [1478662][E](PTable): Power Buffer Reset + 139766 [1478673][E](ERG_Mode): Watts previously processed. + 139767 [1479326][E](ERG_Mode): Proportional: 5.000000 + 139768 [1480733][E](ERG_Mode): Watts previously processed. + 139769 [1482850][E](ERG_Mode): Watts previously processed. + 139770 [1483598][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 175, Cad 91, HR 136, Gear 11, Res 43, Current Pos 12781, Target Pos 12780 + 139771 [1484970][E](PTable): Averaged Entry: watts=167.899994, cad=88.599998, targetPosition=1278.300049, (6)(6) + 139772 [1484971][E](PTData): Cleaned 259 readings + 139773 [1484981][E](PTData): Existing entry averaged (6)(6)(1270), readings(15) + 139774 [1484982][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139775 [1484996][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139776 [1485005][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139777 [1485006][E](PTable): New Entry Processed in 36 ms + 139778 [1485006][E](PTable): Power Buffer Reset + 139779 [1485017][E](ERG_Mode): Watts previously processed. + 139780 [1485672][E](ERG_Mode): Proportional: 8.000000 + 139781 [1487083][E](ERG_Mode): Watts previously processed. + 139782 [1488507][E](ERG_Mode): Watts previously processed. + 139783 [1489610][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 222, Cad 90, HR 138, Gear 11, Res 43, Current Pos 12616, Target Pos 12593 + 139784 [1490632][E](ERG_Mode): Watts previously processed. + 139785 [1491340][E](PTable): Averaged Entry: watts=185.199997, cad=88.900002, targetPosition=1269.000000, (6)(6) + 139786 [1491341][E](PTData): Cleaned 259 readings + 139787 [1491352][E](PTData): Existing entry averaged (6)(6)(1269), readings(16) + 139788 [1491353][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139789 [1491366][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139790 [1491375][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139791 [1491376][E](PTable): New Entry Processed in 36 ms + 139792 [1491376][E](PTable): Power Buffer Reset + 139793 [1491387][E](ERG_Mode): Proportional: -60.000000 + 139794 [1492746][E](ERG_Mode): Watts previously processed. + 139795 [1494859][E](ERG_Mode): Watts previously processed. + 139796 [1495627][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 150, Cad 90, HR 139, Gear 11, Res 42, Current Pos 12401, Target Pos 12454 + 139797 [1496981][E](ERG_Mode): Watts previously processed. + 139798 [1497688][E](PTable): Averaged Entry: watts=159.300003, cad=90.400002, targetPosition=1239.000000, (6)(5) + 139799 [1497689][E](PTData): Cleaned 259 readings + 139800 [1497699][E](PTData): Existing entry averaged (6)(5)(1192), readings(18) + 139801 [1497700][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139802 [1497714][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139803 [1497723][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139804 [1497724][E](PTable): New Entry Processed in 37 ms + 139805 [1497724][E](PTable): Power Buffer Reset + 139806 [1497735][E](ERG_Mode): Proportional: 4.000000 + 139807 [1499801][E](ERG_Mode): Watts previously processed. + 139808 [1501639][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 164, Cad 91, HR 140, Gear 11, Res 42, Current Pos 12510, Target Pos 12510 + 139809 [1501910][E](ERG_Mode): Watts previously processed. + 139810 [1503322][E](ERG_Mode): Proportional: -30.000000 + 139811 [1503323][E](PTable): Using detected travel limits during homing + 139812 [1504033][E](PTable): Averaged Entry: watts=169.199997, cad=91.000000, targetPosition=1249.599976, (6)(6) + 139813 [1504035][E](PTData): Cleaned 259 readings + 139814 [1504046][E](PTData): Existing entry averaged (6)(6)(1267), readings(17) + 139815 [1504047][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139816 [1504060][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139817 [1504069][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139818 [1504070][E](PTable): New Entry Processed in 37 ms + 139819 [1504071][E](PTable): Power Buffer Reset + 139820 [1504742][E](ERG_Mode): Watts previously processed. + 139821 [1506863][E](ERG_Mode): Watts previously processed. + 139822 [1507652][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 165, Cad 90, HR 140, Gear 11, Res 42, Current Pos 12468, Target Pos 12468 + 139823 [1508982][E](ERG_Mode): Watts previously processed. + 139824 [1509690][E](ERG_Mode): Proportional: 8.000000 + 139825 [1510391][E](PTable): Averaged Entry: watts=165.800003, cad=90.800003, targetPosition=1246.000000, (6)(6) + 139826 [1510392][E](PTData): Cleaned 259 readings + 139827 [1510402][E](PTData): Existing entry averaged (6)(6)(1265), readings(18) + 139828 [1510403][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139829 [1510417][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139830 [1510426][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139831 [1510427][E](PTable): New Entry Processed in 36 ms + 139832 [1510427][E](PTable): Power Buffer Reset + 139833 [1511797][E](ERG_Mode): Watts previously processed. + 139834 [1513667][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 161, Cad 87, HR 139, Gear 11, Res 43, Current Pos 12649, Target Pos 12649 + 139835 [1513920][E](ERG_Mode): Watts previously processed. + 139836 [1515333][E](ERG_Mode): Proportional: 5.000000 + 139837 [1516034][E](FTMS_SERVER): 05 04 01 -> ERG Mode Target: 260 Current: 165 Incline: 126.629997. Responding: 80 05 01 + 139838 [1516041][E](DirConManager): Sending response message type 0x04 to client 0 + 139839 [1516065][E](ERG_Mode): SetPoint changed:230w Waiting:1119ms PowerTable Result: 14130 + 139840 [1518585][E](ERG_Mode): ERG wait expired, pos: 14130, tgt: 0 + 139841 [1518586][E](PTable): Averaged Entry: watts=158.500000, cad=87.699997, targetPosition=1276.199951, (5)(5) + 139842 [1518597][E](PTData): Cleaned 259 readings + 139843 [1518598][E](PTData): New entry recorded (5)(5)(1276) + 139844 [1518608][E](PTData): Lower Up Found 4, 5, tp1252 + 139845 [1518611][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 3 ms + 139846 [1518612][E](PTable): New Entry Processed in 26 ms + 139847 [1518613][E](PTable): Power Buffer Reset + 139848 [1519682][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 193, Cad 88, HR 138, Gear 11, Res 49, Current Pos 14695, Target Pos 14757 + 139849 [1519999][E](ERG_Mode): Watts previously processed. + 139850 [1520705][E](ERG_Mode): Proportional: 2.000000 + 139851 [1522820][E](ERG_Mode): Watts previously processed. + 139852 [1524930][E](PTable): Averaged Entry: watts=251.899994, cad=90.800003, targetPosition=1464.099976, (6)(8) + 139853 [1524931][E](PTData): Cleaned 1 readings + 139854 [1524941][E](PTData): Existing entry averaged (6)(8)(1408), readings(16) + 139855 [1524942][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139856 [1524955][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 2 ms + 139857 [1524965][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 3 ms + 139858 [1524966][E](PTable): New Entry Processed in 36 ms + 139859 [1524966][E](PTable): Power Buffer Reset + 139860 [1524977][E](ERG_Mode): Watts previously processed. + 139861 [1525690][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 286, Cad 92, HR 137, Gear 11, Res 49, Current Pos 14530, Target Pos 14457 + 139862 [1526349][E](ERG_Mode): Proportional: -36.000000 + 139863 [1527059][E](ERG_Mode): Watts previously processed. + 139864 [1529890][E](ERG_Mode): Watts previously processed. + 139865 [1531305][E](PTable): Averaged Entry: watts=278.200012, cad=93.099998, targetPosition=1437.599976, (7)(9) + 139866 [1531306][E](PTData): Cleaned 260 readings + 139867 [1531317][E](PTData): Existing entry averaged (7)(9)(1421), readings(3) + 139868 [1531318][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139869 [1531331][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 3 ms + 139870 [1531340][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 3 ms + 139871 [1531341][E](PTable): New Entry Processed in 37 ms + 139872 [1531341][E](PTable): Power Buffer Reset + 139873 [1531352][E](ERG_Mode): Proportional: -66.000000 + 139874 [1531705][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 282, Cad 94, HR 136, Gear 11, Res 48, Current Pos 14180, Target Pos 14180 + 139875 [1532012][E](ERG_Mode): Watts previously processed. + 139876 [1534836][E](ERG_Mode): Watts previously processed. + 139877 [1536944][E](ERG_Mode): Watts previously processed. + 139878 [1537651][E](PTable): Averaged Entry: watts=272.200012, cad=94.900002, targetPosition=1410.500000, (7)(9) + 139879 [1537652][E](PTData): Cleaned 260 readings + 139880 [1537662][E](PTData): Existing entry averaged (7)(9)(1418), readings(4) + 139881 [1537663][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139882 [1537677][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 3 ms + 139883 [1537686][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 2 ms + 139884 [1537688][E](PTable): New Entry Processed in 37 ms + 139885 [1537688][E](PTable): Power Buffer Reset + 139886 [1537698][E](ERG_Mode): Proportional: -39.000000 + 139887 [1537721][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 273, Cad 96, HR 139, Gear 11, Res 47, Current Pos 14059, Target Pos 14021 + 139888 [1539056][E](ERG_Mode): Watts previously processed. + 139889 [1541164][E](ERG_Mode): Watts previously processed. + 139890 [1541164][E](PTable): Using detected travel limits during homing + 139891 [1543277][E](ERG_Mode): Watts previously processed. + 139892 [1543736][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 284, Cad 98, HR 142, Gear 11, Res 47, Current Pos 13941, Target Pos 13941 + 139893 [1543978][E](PTable): Averaged Entry: watts=268.200012, cad=96.800003, targetPosition=1397.900024, (7)(9) + 139894 [1543979][E](PTData): Cleaned 260 readings + 139895 [1543989][E](PTData): Existing entry averaged (7)(9)(1414), readings(5) + 139896 [1543990][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139897 [1544004][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 3 ms + 139898 [1544013][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 3 ms + 139899 [1544014][E](PTable): New Entry Processed in 37 ms + 139900 [1544014][E](PTable): Power Buffer Reset + 139901 [1544025][E](ERG_Mode): Proportional: -42.000000 + 139902 [1544688][E](ERG_Mode): Watts previously processed. + 139903 [1546801][E](ERG_Mode): Watts previously processed. + 139904 [1548918][E](ERG_Mode): Watts previously processed. + 139905 [1549637][E](ERG_Mode): Proportional: -1.000000 + 139906 [1549750][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 261, Cad 103, HR 146, Gear 11, Res 46, Current Pos 13520, Target Pos 13520 + 139907 [1550348][E](PTable): Averaged Entry: watts=282.500000, cad=100.500000, targetPosition=1370.199951, (8)(9) + 139908 [1550349][E](PTData): Cleaned 260 readings + 139909 [1550359][E](PTData): Existing entry averaged (8)(9)(1357), readings(4) + 139910 [1550360][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139911 [1550374][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 3 ms + 139912 [1550383][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 3 ms + 139913 [1550384][E](PTable): New Entry Processed in 36 ms + 139914 [1550384][E](PTable): Power Buffer Reset + 139915 [1551052][E](ERG_Mode): Watts previously processed. + 139916 [1553166][E](ERG_Mode): Watts previously processed. + 139917 [1554570][E](ERG_Mode): Watts previously processed. + 139918 [1555278][E](ERG_Mode): Watts previously processed. + 139919 [1555765][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 292, Cad 104, HR 148, Gear 11, Res 45, Current Pos 13449, Target Pos 13449 + 139920 [1555981][E](ERG_Mode): Proportional: -117.000000 + 139921 [1556688][E](ERG_Mode): Watts previously processed. + 139922 [1558809][E](ERG_Mode): Watts previously processed. + 139923 [1560228][E](PTable): Averaged Entry: watts=267.600006, cad=102.599998, targetPosition=1344.099976, (8)(9) + 139924 [1560229][E](PTData): Cleaned 260 readings + 139925 [1560239][E](PTData): Existing entry averaged (8)(9)(1354), readings(5) + 139926 [1560240][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139927 [1560254][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 3 ms + 139928 [1560263][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 3 ms + 139929 [1560264][E](PTable): New Entry Processed in 36 ms + 139930 [1560264][E](PTable): Power Buffer Reset + 139931 [1560935][E](ERG_Mode): Watts previously processed. + 139932 [1561652][E](ERG_Mode): Proportional: 7.000000 + 139933 [1561775][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 253, Cad 105, HR 150, Gear 11, Res 45, Current Pos 13262, Target Pos 13262 + 139934 [1563066][E](ERG_Mode): Watts previously processed. + 139935 [1565177][E](ERG_Mode): Watts previously processed. + 139936 [1567294][E](PTable): Averaged Entry: watts=251.899994, cad=104.699997, targetPosition=1327.500000, (9)(8) + 139937 [1567295][E](PTData): Cleaned 260 readings + 139938 [1567305][E](PTData): Existing entry averaged (9)(8)(1296), readings(3) + 139939 [1567306][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 139940 [1567318][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 139941 [1567321][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 3 ms + 139942 [1567340][E](PTData): Fit Valid: 1, N: 40, Quad: 1, Time: 3 ms + 139943 [1567341][E](PTable): New Entry Processed in 48 ms + 139944 [1567342][E](PTable): Power Buffer Reset + 139945 [1567352][E](ERG_Mode): Proportional: 2.000000 + 139946 [1567785][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 258, Cad 105, HR 153, Gear 11, Res 45, Current Pos 13319, Target Pos 13319 + 139947 [1568706][E](ERG_Mode): Watts previously processed. + 139948 [1570821][E](ERG_Mode): Watts previously processed. + 139949 [1572939][E](ERG_Mode): Watts previously processed. + 139950 [1573646][E](ERG_Mode): Proportional: -6.000000 + 139951 [1573801][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 266, Cad 107, HR 154, Gear 11, Res 44, Current Pos 13183, Target Pos 13183 + 139952 [1575051][E](ERG_Mode): Watts previously processed. + 139953 [1577171][E](ERG_Mode): Watts previously processed. + 139954 [1577171][E](PTable): Using detected travel limits during homing + 139955 [1579294][E](ERG_Mode): Proportional: -6.000000 + 139956 [1579818][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 266, Cad 106, HR 156, Gear 11, Res 45, Current Pos 13213, Target Pos 13213 + 139957 [1580707][E](ERG_Mode): Watts previously processed. + 139958 [1582828][E](ERG_Mode): Watts previously processed. + 139959 [1584945][E](ERG_Mode): Watts previously processed. + 139960 [1585653][E](ERG_Mode): Proportional: -3.000000 + 139961 [1585830][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 263, Cad 106, HR 158, Gear 11, Res 44, Current Pos 13199, Target Pos 13199 + 139962 [1587062][E](ERG_Mode): Watts previously processed. + 139963 [1589183][E](PTable): Averaged Entry: watts=262.200012, cad=104.800003, targetPosition=1324.500000, (9)(9) + 139964 [1589184][E](PTData): Cleaned 260 readings + 139965 [1589194][E](PTData): New entry recorded (9)(9)(1324) + 139966 [1589195][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 139967 [1589206][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 139968 [1589209][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139969 [1589228][E](PTData): Fit Valid: 1, N: 41, Quad: 1, Time: 3 ms + 139970 [1589229][E](PTable): New Entry Processed in 47 ms + 139971 [1589230][E](PTable): Power Buffer Reset + 139972 [1589890][E](ERG_Mode): Watts previously processed. + 139973 [1591297][E](ERG_Mode): Proportional: 8.000000 + 139974 [1591843][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 252, Cad 104, HR 159, Gear 11, Res 45, Current Pos 13219, Target Pos 13219 + 139975 [1592004][E](ERG_Mode): Watts previously processed. + 139976 [1594829][E](ERG_Mode): Watts previously processed. + 139977 [1595536][E](PTable): Averaged Entry: watts=240.899994, cad=102.199997, targetPosition=1328.500000, (8)(8) + 139978 [1595537][E](PTData): Cleaned 259 readings + 139979 [1595548][E](PTData): New entry recorded (8)(8)(1328) + 139980 [1595549][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139981 [1595562][E](PTData): Fit Valid: 1, N: 42, Quad: 1, Time: 3 ms + 139982 [1595571][E](PTData): Fit Valid: 1, N: 42, Quad: 1, Time: 3 ms + 139983 [1595573][E](PTable): New Entry Processed in 38 ms + 139984 [1595573][E](PTable): Power Buffer Reset + 139985 [1596940][E](ERG_Mode): Watts previously processed. + 139986 [1597648][E](ERG_Mode): Proportional: 96.000000 + 139987 [1597853][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 228, Cad 96, HR 160, Gear 11, Res 46, Current Pos 13789, Target Pos 13821 + 139988 [1599054][E](ERG_Mode): Watts previously processed. + 139989 [1601879][E](PTable): Averaged Entry: watts=236.300003, cad=95.500000, targetPosition=1381.300049, (7)(8) + 139990 [1601880][E](PTData): Cleaned 258 readings + 139991 [1601890][E](PTData): Existing entry averaged (7)(8)(1364), readings(17) + 139992 [1601891][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 139993 [1601905][E](PTData): Fit Valid: 1, N: 42, Quad: 1, Time: 3 ms + 139994 [1601914][E](PTData): Fit Valid: 1, N: 42, Quad: 1, Time: 3 ms + 139995 [1601915][E](PTable): New Entry Processed in 37 ms + 139996 [1601916][E](PTable): Power Buffer Reset + 139997 [1601926][E](ERG_Mode): Watts previously processed. + 139998 [1603287][E](ERG_Mode): Proportional: 78.000000 + 139999 [1603864][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 234, Cad 91, HR 162, Gear 11, Res 48, Current Pos 14205, Target Pos 14205 + 140000 [1603995][E](ERG_Mode): Watts previously processed. + 140001 [1606105][E](ERG_Mode): Watts previously processed. + 140002 [1608219][E](PTable): Averaged Entry: watts=248.300003, cad=92.699997, targetPosition=1418.800049, (6)(8) + 140003 [1608220][E](PTData): Cleaned 258 readings + 140004 [1608230][E](PTData): Existing entry averaged (6)(8)(1408), readings(17) + 140005 [1608231][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140006 [1608245][E](PTData): Fit Valid: 1, N: 42, Quad: 1, Time: 3 ms + 140007 [1608254][E](PTData): Fit Valid: 1, N: 42, Quad: 1, Time: 3 ms + 140008 [1608255][E](PTable): New Entry Processed in 37 ms + 140009 [1608255][E](PTable): Power Buffer Reset + 140010 [1608266][E](ERG_Mode): Watts previously processed. + 140011 [1608924][E](ERG_Mode): Proportional: 4.000000 + 140012 [1609881][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 262, Cad 93, HR 163, Gear 11, Res 48, Current Pos 14263, Target Pos 14263 + 140013 [1610332][E](ERG_Mode): Watts previously processed. + 140014 [1613160][E](PTable): Using detected travel limits during homing + 140015 [1613866][E](ERG_Mode): Watts previously processed. + 140016 [1614573][E](PTable): Averaged Entry: watts=261.200012, cad=92.800003, targetPosition=1426.500000, (6)(9) + 140017 [1614574][E](PTData): Cleaned 258 readings + 140018 [1614584][E](PTData): New entry recorded (6)(9)(1426) + 140019 [1614585][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140020 [1614599][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140021 [1614608][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140022 [1614609][E](PTable): New Entry Processed in 37 ms + 140023 [1614609][E](PTable): Power Buffer Reset + 140024 [1614620][E](ERG_Mode): Proportional: -4.000000 + 140025 [1615895][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 261, Cad 93, HR 164, Gear 11, Res 48, Current Pos 14261, Target Pos 14261 + 140026 [1615988][E](ERG_Mode): Watts previously processed. + 140027 [1618100][E](ERG_Mode): Watts previously processed. + 140028 [1620215][E](ERG_Mode): Watts previously processed. + 140029 [1620925][E](PTable): Averaged Entry: watts=247.800003, cad=91.199997, targetPosition=1431.800049, (6)(8) + 140030 [1620926][E](PTData): Cleaned 257 readings + 140031 [1620936][E](PTData): Existing entry averaged (6)(8)(1409), readings(18) + 140032 [1620937][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140033 [1620951][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140034 [1620960][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140035 [1620961][E](PTable): New Entry Processed in 37 ms + 140036 [1620961][E](PTable): Power Buffer Reset + 140037 [1620972][E](ERG_Mode): Proportional: 63.000000 + 140038 [1621911][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 255, Cad 90, HR 164, Gear 11, Res 49, Current Pos 14551, Target Pos 14551 + 140039 [1623755][E](ERG_Mode): Watts previously processed. + 140040 [1625874][E](ERG_Mode): Watts previously processed. + 140041 [1626582][E](ERG_Mode): Proportional: -45.000000 + 140042 [1627292][E](PTable): Averaged Entry: watts=266.100006, cad=91.800003, targetPosition=1447.500000, (6)(9) + 140043 [1627293][E](PTData): Cleaned 257 readings + 140044 [1627303][E](PTData): Existing entry averaged (6)(9)(1433), readings(2) + 140045 [1627304][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140046 [1627318][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140047 [1627328][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140048 [1627329][E](PTable): New Entry Processed in 37 ms + 140049 [1627329][E](PTable): Power Buffer Reset + 140050 [1627920][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 261, Cad 93, HR 163, Gear 11, Res 48, Current Pos 14369, Target Pos 14369 + 140051 [1628002][E](ERG_Mode): Watts previously processed. + 140052 [1630124][E](ERG_Mode): Watts previously processed. + 140053 [1632242][E](ERG_Mode): Watts previously processed. + 140054 [1632952][E](ERG_Mode): Proportional: 2.000000 + 140055 [1633654][E](PTable): Averaged Entry: watts=255.899994, cad=91.699997, targetPosition=1437.400024, (6)(9) + 140056 [1633655][E](PTData): Cleaned 257 readings + 140057 [1633665][E](PTData): Existing entry averaged (6)(9)(1434), readings(3) + 140058 [1633667][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140059 [1633680][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140060 [1633689][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 2 ms + 140061 [1633691][E](PTable): New Entry Processed in 37 ms + 140062 [1633691][E](PTable): Power Buffer Reset + 140063 [1633953][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 253, Cad 92, HR 163, Gear 11, Res 49, Current Pos 14398, Target Pos 14398 + 140064 [1635769][E](ERG_Mode): Watts previously processed. + 140065 [1637886][E](ERG_Mode): Watts previously processed. + 140066 [1638592][E](ERG_Mode): Proportional: 8.000000 + 140067 [1639966][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 252, Cad 90, HR 162, Gear 11, Res 49, Current Pos 14474, Target Pos 14474 + 140068 [1639998][E](PTable): Averaged Entry: watts=251.500000, cad=90.800003, targetPosition=1442.400024, (6)(8) + 140069 [1639999][E](PTData): Cleaned 257 readings + 140070 [1640009][E](PTData): Existing entry averaged (6)(8)(1410), readings(19) + 140071 [1640010][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140072 [1640024][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140073 [1640033][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140074 [1640034][E](PTable): New Entry Processed in 37 ms + 140075 [1640034][E](PTable): Power Buffer Reset + 140076 [1640045][E](ERG_Mode): Watts previously processed. + 140077 [1642108][E](ERG_Mode): Watts previously processed. + 140078 [1644227][E](ERG_Mode): Watts previously processed. + 140079 [1644935][E](ERG_Mode): Proportional: 1.000000 + 140080 [1645979][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 253, Cad 91, HR 162, Gear 11, Res 49, Current Pos 14443, Target Pos 14443 + 140081 [1646345][E](PTable): Averaged Entry: watts=261.299988, cad=91.500000, targetPosition=1445.599976, (6)(9) + 140082 [1646346][E](PTData): Cleaned 257 readings + 140083 [1646356][E](PTData): Existing entry averaged (6)(9)(1436), readings(4) + 140084 [1646357][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140085 [1646371][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140086 [1646380][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140087 [1646381][E](PTable): New Entry Processed in 36 ms + 140088 [1646382][E](PTable): Power Buffer Reset + 140089 [1647767][E](ERG_Mode): Watts previously processed. + 140090 [1649186][E](PTable): Using detected travel limits during homing + 140091 [1649893][E](ERG_Mode): Watts previously processed. + 140092 [1650601][E](ERG_Mode): Proportional: 4.000000 + 140093 [1651995][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 261, Cad 91, HR 162, Gear 11, Res 49, Current Pos 14496, Target Pos 14496 + 140094 [1652017][E](ERG_Mode): Watts previously processed. + 140095 [1652724][E](PTable): Averaged Entry: watts=255.500000, cad=90.699997, targetPosition=1446.900024, (6)(9) + 140096 [1652725][E](PTData): Cleaned 257 readings + 140097 [1652735][E](PTData): Existing entry averaged (6)(9)(1437), readings(5) + 140098 [1652736][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140099 [1652750][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140100 [1652759][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140101 [1652760][E](PTable): New Entry Processed in 36 ms + 140102 [1652761][E](PTable): Power Buffer Reset + 140103 [1654132][E](ERG_Mode): Watts previously processed. + 140104 [1656256][E](ERG_Mode): Proportional: 36.000000 + 140105 [1657679][E](ERG_Mode): Watts previously processed. + 140106 [1658015][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 255, Cad 89, HR 161, Gear 11, Res 49, Current Pos 14580, Target Pos 14580 + 140107 [1659096][E](PTable): Averaged Entry: watts=259.100006, cad=90.300003, targetPosition=1451.900024, (6)(9) + 140108 [1659097][E](PTData): Cleaned 257 readings + 140109 [1659107][E](PTData): Existing entry averaged (6)(9)(1439), readings(6) + 140110 [1659108][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140111 [1659122][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140112 [1659131][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140113 [1659132][E](PTable): New Entry Processed in 36 ms + 140114 [1659132][E](PTable): Power Buffer Reset + 140115 [1659806][E](ERG_Mode): Watts previously processed. + 140116 [1661926][E](ERG_Mode): Watts previously processed. + 140117 [1662635][E](ERG_Mode): Proportional: -57.000000 + 140118 [1664031][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 279, Cad 93, HR 161, Gear 11, Res 48, Current Pos 14354, Target Pos 14354 + 140119 [1664053][E](ERG_Mode): Watts previously processed. + 140120 [1665470][E](PTable): Averaged Entry: watts=275.899994, cad=92.199997, targetPosition=1444.500000, (6)(9) + 140121 [1665471][E](PTData): Cleaned 257 readings + 140122 [1665481][E](PTData): Existing entry averaged (6)(9)(1439), readings(7) + 140123 [1665482][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140124 [1665496][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140125 [1665505][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140126 [1665506][E](PTable): New Entry Processed in 37 ms + 140127 [1665507][E](PTable): Power Buffer Reset + 140128 [1666180][E](ERG_Mode): Watts previously processed. + 140129 [1668308][E](ERG_Mode): Watts previously processed. + 140130 [1669018][E](ERG_Mode): Proportional: -8.000000 + 140131 [1669726][E](ERG_Mode): Watts previously processed. + 140132 [1670044][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 265, Cad 95, HR 160, Gear 11, Res 48, Current Pos 14163, Target Pos 14163 + 140133 [1671831][E](PTable): Averaged Entry: watts=271.500000, cad=94.800003, targetPosition=1418.800049, (7)(9) + 140134 [1671832][E](PTData): Cleaned 257 readings + 140135 [1671842][E](PTData): Existing entry averaged (7)(9)(1414), readings(6) + 140136 [1671843][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140137 [1671857][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140138 [1671866][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140139 [1671868][E](PTable): New Entry Processed in 38 ms + 140140 [1671868][E](PTable): Power Buffer Reset + 140141 [1671878][E](ERG_Mode): Watts previously processed. + 140142 [1673951][E](ERG_Mode): Watts previously processed. + 140143 [1674658][E](ERG_Mode): Proportional: -1.000000 + 140144 [1676055][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 257, Cad 94, HR 160, Gear 11, Res 48, Current Pos 14141, Target Pos 14141 + 140145 [1676066][E](ERG_Mode): Watts previously processed. + 140146 [1678181][E](PTable): Averaged Entry: watts=260.200012, cad=94.599998, targetPosition=1413.900024, (7)(9) + 140147 [1678182][E](PTData): Cleaned 257 readings + 140148 [1678192][E](PTData): Existing entry averaged (7)(9)(1413), readings(7) + 140149 [1678193][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140150 [1678207][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140151 [1678216][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140152 [1678217][E](PTable): New Entry Processed in 37 ms + 140153 [1678217][E](PTable): Power Buffer Reset + 140154 [1678228][E](ERG_Mode): Watts previously processed. + 140155 [1680298][E](ERG_Mode): Proportional: 9.000000 + 140156 [1681004][E](ERG_Mode): Watts previously processed. + 140157 [1682083][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 253, Cad 94, HR 160, Gear 11, Res 48, Current Pos 14199, Target Pos 14199 + 140158 [1683837][E](ERG_Mode): Watts previously processed. + 140159 [1684538][E](PTable): Averaged Entry: watts=251.699997, cad=93.500000, targetPosition=1418.300049, (7)(8) + 140160 [1684539][E](PTData): Cleaned 257 readings + 140161 [1684549][E](PTData): Existing entry averaged (7)(8)(1366), readings(18) + 140162 [1684550][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140163 [1684564][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140164 [1684573][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140165 [1684574][E](PTable): New Entry Processed in 37 ms + 140166 [1684575][E](PTable): Power Buffer Reset + 140167 [1685241][E](PTable): Using detected travel limits during homing + 140168 [1685945][E](ERG_Mode): Watts previously processed. + 140169 [1686651][E](ERG_Mode): Proportional: 45.000000 + 140170 [1688064][E](ERG_Mode): Watts previously processed. + 140171 [1688095][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 250, Cad 91, HR 160, Gear 11, Res 49, Current Pos 14420, Target Pos 14420 + 140172 [1690186][E](ERG_Mode): Watts previously processed. + 140173 [1690894][E](PTable): Averaged Entry: watts=252.399994, cad=92.099998, targetPosition=1436.599976, (6)(8) + 140174 [1690895][E](PTData): Cleaned 257 readings + 140175 [1690905][E](PTData): Existing entry averaged (6)(8)(1411), readings(20) + 140176 [1690906][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140177 [1690920][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140178 [1690929][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140179 [1690930][E](PTable): New Entry Processed in 36 ms + 140180 [1690931][E](PTable): Power Buffer Reset + 140181 [1692301][E](ERG_Mode): Proportional: -45.000000 + 140182 [1693006][E](ERG_Mode): Watts previously processed. + 140183 [1694110][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 256, Cad 94, HR 161, Gear 11, Res 48, Current Pos 14244, Target Pos 14244 + 140184 [1695117][E](ERG_Mode): Watts previously processed. + 140185 [1697231][E](PTable): Averaged Entry: watts=261.600006, cad=93.900002, targetPosition=1426.800049, (7)(9) + 140186 [1697232][E](PTData): Cleaned 257 readings + 140187 [1697242][E](PTData): Existing entry averaged (7)(9)(1414), readings(8) + 140188 [1697243][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140189 [1697257][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140190 [1697266][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 2 ms + 140191 [1697268][E](PTable): New Entry Processed in 38 ms + 140192 [1697268][E](PTable): Power Buffer Reset + 140193 [1697278][E](ERG_Mode): Watts previously processed. + 140194 [1697938][E](ERG_Mode): Proportional: 39.000000 + 140195 [1699349][E](ERG_Mode): Watts previously processed. + 140196 [1700119][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 249, Cad 92, HR 161, Gear 11, Res 48, Current Pos 14350, Target Pos 14375 + 140197 [1701463][E](ERG_Mode): Watts previously processed. + 140198 [1702876][E](ERG_Mode): Watts previously processed. + 140199 [1703583][E](PTable): Averaged Entry: watts=254.300003, cad=92.099998, targetPosition=1434.800049, (6)(8) + 140200 [1703585][E](PTData): Cleaned 257 readings + 140201 [1703595][E](PTData): Existing entry averaged (6)(8)(1412), readings(20) + 140202 [1703596][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140203 [1703610][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140204 [1703619][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140205 [1703620][E](PTable): New Entry Processed in 37 ms + 140206 [1703620][E](PTable): Power Buffer Reset + 140207 [1703631][E](ERG_Mode): Proportional: -6.000000 + 140208 [1704989][E](ERG_Mode): Watts previously processed. + 140209 [1706133][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 250, Cad 93, HR 161, Gear 11, Res 48, Current Pos 14405, Target Pos 14405 + 140210 [1707103][E](ERG_Mode): Watts previously processed. + 140211 [1709220][E](ERG_Mode): Watts previously processed. + 140212 [1709921][E](PTable): Averaged Entry: watts=255.199997, cad=92.300003, targetPosition=1439.400024, (6)(9) + 140213 [1709922][E](PTData): Cleaned 257 readings + 140214 [1709933][E](PTData): Existing entry averaged (6)(9)(1439), readings(8) + 140215 [1709934][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140216 [1709947][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140217 [1709959][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140218 [1709960][E](PTable): New Entry Processed in 39 ms + 140219 [1710051][E](PTable): Writing File: /PowerTable.txt + 140220 [1710290][E](PTable): Power table saved successfully with 508 readings + 140221 [1710290][E](PTable): Power Buffer Reset + 140222 [1710291][E](ERG_Mode): Proportional: 57.000000 + 140223 [1711331][E](ERG_Mode): Watts previously processed. + 140224 [1712141][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 241, Cad 89, HR 162, Gear 11, Res 49, Current Pos 14624, Target Pos 14663 + 140225 [1713452][E](ERG_Mode): Watts previously processed. + 140226 [1714861][E](ERG_Mode): Watts previously processed. + 140227 [1715569][E](ERG_Mode): Proportional: 2.000000 + 140228 [1716271][E](PTable): Averaged Entry: watts=248.600006, cad=88.599998, targetPosition=1465.699951, (6)(8) + 140229 [1716272][E](PTData): Cleaned 257 readings + 140230 [1716282][E](PTData): Existing entry averaged (6)(8)(1414), readings(20) + 140231 [1716283][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140232 [1716297][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140233 [1716308][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140234 [1716309][E](PTable): New Entry Processed in 38 ms + 140235 [1716310][E](PTable): Power Buffer Reset + 140236 [1716977][E](ERG_Mode): Watts previously processed. + 140237 [1718153][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 250, Cad 88, HR 162, Gear 11, Res 50, Current Pos 14762, Target Pos 14762 + 140238 [1719090][E](ERG_Mode): Watts previously processed. + 140239 [1721220][E](ERG_Mode): Watts previously processed. + 140240 [1721220][E](PTable): Using detected travel limits during homing + 140241 [1721921][E](ERG_Mode): Proportional: 39.000000 + 140242 [1722630][E](PTable): Averaged Entry: watts=250.600006, cad=87.099998, targetPosition=1478.300049, (5)(8) + 140243 [1722631][E](PTData): Cleaned 257 readings + 140244 [1722641][E](PTData): Existing entry averaged (5)(8)(1441), readings(14) + 140245 [1722642][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140246 [1722656][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140247 [1722666][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140248 [1722667][E](PTable): New Entry Processed in 37 ms + 140249 [1722667][E](PTable): Power Buffer Reset + 140250 [1723337][E](ERG_Mode): Watts previously processed. + 140251 [1724169][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 242, Cad 84, HR 163, Gear 11, Res 50, Current Pos 14967, Target Pos 14992 + 140252 [1724747][E](ERG_Mode): Watts previously processed. + 140253 [1726863][E](ERG_Mode): Watts previously processed. + 140254 [1727569][E](ERG_Mode): Proportional: 60.000000 + 140255 [1728974][E](PTable): Averaged Entry: watts=247.899994, cad=84.400002, targetPosition=1500.800049, (5)(8) + 140256 [1728975][E](PTData): Cleaned 257 readings + 140257 [1728986][E](PTData): Existing entry averaged (5)(8)(1444), readings(15) + 140258 [1728987][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140259 [1729000][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140260 [1729009][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 2 ms + 140261 [1729011][E](PTable): New Entry Processed in 37 ms + 140262 [1729011][E](PTable): Power Buffer Reset + 140263 [1729021][E](ERG_Mode): Watts previously processed. + 140264 [1730179][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 249, Cad 83, HR 163, Gear 11, Res 51, Current Pos 15164, Target Pos 15164 + 140265 [1731079][E](ERG_Mode): Watts previously processed. + 140266 [1733199][E](ERG_Mode): Watts previously processed. + 140267 [1733921][E](ERG_Mode): Proportional: -39.000000 + 140268 [1735326][E](PTable): Averaged Entry: watts=265.899994, cad=85.099998, targetPosition=1507.800049, (5)(9) + 140269 [1735327][E](PTData): Cleaned 257 readings + 140270 [1735337][E](PTData): Existing entry averaged (5)(9)(1474), readings(3) + 140271 [1735338][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140272 [1735352][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140273 [1735361][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140274 [1735362][E](PTable): New Entry Processed in 37 ms + 140275 [1735363][E](PTable): Power Buffer Reset + 140276 [1735373][E](ERG_Mode): Watts previously processed. + 140277 [1736191][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 251, Cad 84, HR 162, Gear 11, Res 51, Current Pos 14987, Target Pos 14987 + 140278 [1736737][E](ERG_Mode): Watts previously processed. + 140279 [1738853][E](ERG_Mode): Watts previously processed. + 140280 [1739560][E](ERG_Mode): Proportional: 8.000000 + 140281 [1740972][E](ERG_Mode): Watts previously processed. + 140282 [1741682][E](PTable): Averaged Entry: watts=249.399994, cad=84.000000, targetPosition=1501.800049, (5)(8) + 140283 [1741683][E](PTData): Cleaned 257 readings + 140284 [1741693][E](PTData): Existing entry averaged (5)(8)(1447), readings(16) + 140285 [1741694][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140286 [1741708][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140287 [1741717][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140288 [1741718][E](PTable): New Entry Processed in 37 ms + 140289 [1741718][E](PTable): Power Buffer Reset + 140290 [1742209][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 250, Cad 84, HR 163, Gear 11, Res 51, Current Pos 15113, Target Pos 15113 + 140291 [1743089][E](ERG_Mode): Watts previously processed. + 140292 [1745209][E](ERG_Mode): Watts previously processed. + 140293 [1745910][E](ERG_Mode): Proportional: -54.000000 + 140294 [1747323][E](ERG_Mode): Watts previously processed. + 140295 [1748029][E](PTable): Averaged Entry: watts=264.399994, cad=85.800003, targetPosition=1509.300049, (5)(9) + 140296 [1748030][E](PTData): Cleaned 257 readings + 140297 [1748040][E](PTData): Existing entry averaged (5)(9)(1481), readings(4) + 140298 [1748041][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140299 [1748055][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140300 [1748064][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140301 [1748065][E](PTable): New Entry Processed in 37 ms + 140302 [1748066][E](PTable): Power Buffer Reset + 140303 [1748227][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 277, Cad 87, HR 163, Gear 11, Res 51, Current Pos 14989, Target Pos 14983 + 140304 [1750141][E](ERG_Mode): Watts previously processed. + 140305 [1751547][E](ERG_Mode): Proportional: -4.000000 + 140306 [1752252][E](ERG_Mode): Watts previously processed. + 140307 [1754241][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 264, Cad 86, HR 163, Gear 11, Res 50, Current Pos 14916, Target Pos 14916 + 140308 [1754387][E](PTable): Averaged Entry: watts=266.100006, cad=86.800003, targetPosition=1493.000000, (5)(9) + 140309 [1754388][E](PTData): Cleaned 257 readings + 140310 [1754399][E](PTData): Existing entry averaged (5)(9)(1483), readings(5) + 140311 [1754400][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140312 [1754413][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140313 [1754422][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 2 ms + 140314 [1754424][E](PTable): New Entry Processed in 37 ms + 140315 [1754424][E](PTable): Power Buffer Reset + 140316 [1755096][E](ERG_Mode): Watts previously processed. + 140317 [1755964][E](FTMS_SERVER): 05 b9 00 -> ERG Mode Target: 185 Current: 261 Incline: 149.139999. Responding: 80 05 01 + 140318 [1755969][E](DirConManager): Sending response message type 0x04 to client 0 + 140319 [1756501][E](ERG_Mode): SetPoint changed:215w Waiting:964ms PowerTable Result: 13990 + 140320 [1758874][E](ERG_Mode): ERG wait expired, pos: 13990, tgt: 0 + 140321 [1758875][E](ERG_Mode): Proportional: -675.000000 + 140322 [1758876][E](PTable): Using detected travel limits during homing + 140323 [1760259][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 205, Cad 85, HR 164, Gear 11, Res 45, Current Pos 13337, Target Pos 13337 + 140324 [1760985][E](ERG_Mode): Watts previously processed. + 140325 [1762403][E](PTable): Averaged Entry: watts=239.399994, cad=86.800003, targetPosition=1401.400024, (5)(8) + 140326 [1762404][E](PTData): Cleaned 257 readings + 140327 [1762414][E](PTData): Existing entry averaged (5)(8)(1444), readings(17) + 140328 [1762415][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140329 [1762429][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140330 [1762438][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140331 [1762439][E](PTable): New Entry Processed in 37 ms + 140332 [1762439][E](PTable): Power Buffer Reset + 140333 [1763109][E](ERG_Mode): Watts previously processed. + 140334 [1764525][E](ERG_Mode): Proportional: 6.000000 + 140335 [1765234][E](ERG_Mode): Watts previously processed. + 140336 [1766274][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 176, Cad 86, HR 163, Gear 11, Res 44, Current Pos 13178, Target Pos 13178 + 140337 [1767356][E](ERG_Mode): Watts previously processed. + 140338 [1768773][E](PTable): Averaged Entry: watts=184.100006, cad=86.300003, targetPosition=1316.500000, (5)(6) + 140339 [1768774][E](PTData): Cleaned 257 readings + 140340 [1768785][E](PTData): Existing entry averaged (5)(6)(1317), readings(4) + 140341 [1768786][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140342 [1768799][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140343 [1768808][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 2 ms + 140344 [1768810][E](PTable): New Entry Processed in 38 ms + 140345 [1768810][E](PTable): Power Buffer Reset + 140346 [1769475][E](ERG_Mode): Watts previously processed. + 140347 [1770177][E](ERG_Mode): Proportional: 36.000000 + 140348 [1772287][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 215, Cad 89, HR 162, Gear 11, Res 45, Current Pos 13261, Target Pos 13261 + 140349 [1772988][E](ERG_Mode): Watts previously processed. + 140350 [1775110][E](PTable): Averaged Entry: watts=185.100006, cad=87.099998, targetPosition=1321.500000, (5)(6) + 140351 [1775111][E](PTData): Cleaned 257 readings + 140352 [1775121][E](PTData): Existing entry averaged (5)(6)(1317), readings(5) + 140353 [1775122][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140354 [1775136][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140355 [1775145][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140356 [1775146][E](PTable): New Entry Processed in 36 ms + 140357 [1775147][E](PTable): Power Buffer Reset + 140358 [1775157][E](ERG_Mode): Watts previously processed. + 140359 [1775812][E](ERG_Mode): Proportional: 36.000000 + 140360 [1777218][E](ERG_Mode): Watts previously processed. + 140361 [1778295][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 181, Cad 85, HR 161, Gear 11, Res 45, Current Pos 13238, Target Pos 13238 + 140362 [1779335][E](ERG_Mode): Watts previously processed. + 140363 [1781445][E](PTable): Averaged Entry: watts=177.300003, cad=85.000000, targetPosition=1323.800049, (5)(6) + 140364 [1781446][E](PTData): Cleaned 257 readings + 140365 [1781456][E](PTData): Existing entry averaged (5)(6)(1317), readings(6) + 140366 [1781457][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140367 [1781471][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140368 [1781480][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140369 [1781481][E](PTable): New Entry Processed in 37 ms + 140370 [1781482][E](PTable): Power Buffer Reset + 140371 [1781492][E](ERG_Mode): Watts previously processed. + 140372 [1782146][E](ERG_Mode): Proportional: 48.000000 + 140373 [1782853][E](ERG_Mode): Watts previously processed. + 140374 [1784310][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 168, Cad 83, HR 161, Gear 11, Res 45, Current Pos 13383, Target Pos 13430 + 140375 [1784970][E](ERG_Mode): Watts previously processed. + 140376 [1787086][E](ERG_Mode): Watts previously processed. + 140377 [1787795][E](PTable): Averaged Entry: watts=168.399994, cad=82.300003, targetPosition=1340.099976, (4)(6) + 140378 [1787796][E](PTData): Cleaned 257 readings + 140379 [1787806][E](PTData): Existing entry averaged (4)(6)(1385), readings(5) + 140380 [1787807][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140381 [1787821][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140382 [1787830][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140383 [1787832][E](PTable): New Entry Processed in 38 ms + 140384 [1787832][E](PTable): Power Buffer Reset + 140385 [1787843][E](ERG_Mode): Proportional: 48.000000 + 140386 [1789206][E](ERG_Mode): Watts previously processed. + 140387 [1790319][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 173, Cad 80, HR 158, Gear 11, Res 46, Current Pos 13691, Target Pos 13691 + 140388 [1791319][E](ERG_Mode): Watts previously processed. + 140389 [1793441][E](ERG_Mode): Proportional: 4.000000 + 140390 [1794152][E](PTable): Averaged Entry: watts=178.100006, cad=80.900002, targetPosition=1368.199951, (4)(6) + 140391 [1794154][E](PTData): Cleaned 257 readings + 140392 [1794164][E](PTData): Existing entry averaged (4)(6)(1382), readings(6) + 140393 [1794165][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140394 [1794178][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140395 [1794188][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140396 [1794189][E](PTable): New Entry Processed in 37 ms + 140397 [1794189][E](PTable): Power Buffer Reset + 140398 [1794863][E](ERG_Mode): Watts previously processed. + 140399 [1794863][E](PTable): Using detected travel limits during homing + 140400 [1796328][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 187, Cad 85, HR 156, Gear 11, Res 46, Current Pos 13615, Target Pos 13615 + 140401 [1796986][E](ERG_Mode): Watts previously processed. + 140402 [1799105][E](ERG_Mode): Watts previously processed. + 140403 [1799813][E](ERG_Mode): Proportional: 30.000000 + 140404 [1800518][E](PTable): Averaged Entry: watts=194.000000, cad=84.099998, targetPosition=1362.500000, (5)(6) + 140405 [1800519][E](PTData): Cleaned 257 readings + 140406 [1800529][E](PTData): Existing entry averaged (5)(6)(1322), readings(7) + 140407 [1800530][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140408 [1800544][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140409 [1800553][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140410 [1800554][E](PTable): New Entry Processed in 37 ms + 140411 [1800554][E](PTable): Power Buffer Reset + 140412 [1801226][E](ERG_Mode): Watts previously processed. + 140413 [1802345][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 201, Cad 87, HR 155, Gear 11, Res 46, Current Pos 13580, Target Pos 13580 + 140414 [1803337][E](ERG_Mode): Watts previously processed. + 140415 [1805461][E](ERG_Mode): Proportional: -2.000000 + 140416 [1806167][E](ERG_Mode): Watts previously processed. + 140417 [1806875][E](PTable): Averaged Entry: watts=191.600006, cad=85.000000, targetPosition=1358.900024, (5)(6) + 140418 [1806876][E](PTData): Cleaned 257 readings + 140419 [1806886][E](PTData): Existing entry averaged (5)(6)(1326), readings(8) + 140420 [1806887][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140421 [1806901][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140422 [1806910][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140423 [1806911][E](PTable): New Entry Processed in 37 ms + 140424 [1806911][E](PTable): Power Buffer Reset + 140425 [1808354][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 184, Cad 86, HR 154, Gear 11, Res 46, Current Pos 13509, Target Pos 13509 + 140426 [1809004][E](ERG_Mode): Watts previously processed. + 140427 [1811123][E](ERG_Mode): Watts previously processed. + 140428 [1811830][E](ERG_Mode): Proportional: 1.000000 + 140429 [1813235][E](PTable): Averaged Entry: watts=186.100006, cad=85.099998, targetPosition=1351.099976, (5)(6) + 140430 [1813236][E](PTData): Cleaned 257 readings + 140431 [1813246][E](PTData): Existing entry averaged (5)(6)(1328), readings(9) + 140432 [1813247][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140433 [1813261][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140434 [1813270][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140435 [1813271][E](PTable): New Entry Processed in 37 ms + 140436 [1813272][E](PTable): Power Buffer Reset + 140437 [1813282][E](ERG_Mode): Watts previously processed. + 140438 [1814368][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 203, Cad 86, HR 151, Gear 11, Res 45, Current Pos 13460, Target Pos 13460 + 140439 [1815347][E](ERG_Mode): Watts previously processed. + 140440 [1815947][E](FTMS_SERVER): 05 04 01 -> ERG Mode Target: 260 Current: 180 Incline: 134.570007. Responding: 80 05 01 + 140441 [1815954][E](DirConManager): Sending response message type 0x04 to client 0 + 140442 [1816050][E](ERG_Mode): SetPoint changed:230w Waiting:987ms PowerTable Result: 14460 + 140443 [1818442][E](ERG_Mode): ERG wait expired, pos: 14460, tgt: 0 + 140444 [1818443][E](ERG_Mode): Proportional: 264.000000 + 140445 [1819150][E](ERG_Mode): Watts previously processed. + 140446 [1820376][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 261, Cad 89, HR 149, Gear 11, Res 50, Current Pos 14787, Target Pos 14787 + 140447 [1821273][E](PTable): Averaged Entry: watts=211.100006, cad=86.199997, targetPosition=1408.400024, (5)(7) + 140448 [1821274][E](PTData): Cleaned 257 readings + 140449 [1821284][E](PTData): Existing entry averaged (5)(7)(1399), readings(9) + 140450 [1821285][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140451 [1821299][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140452 [1821308][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140453 [1821309][E](PTable): New Entry Processed in 36 ms + 140454 [1821310][E](PTable): Power Buffer Reset + 140455 [1821320][E](ERG_Mode): Watts previously processed. + 140456 [1823382][E](ERG_Mode): Watts previously processed. + 140457 [1824092][E](ERG_Mode): Proportional: -4.000000 + 140458 [1825505][E](ERG_Mode): Watts previously processed. + 140459 [1826393][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 261, Cad 89, HR 148, Gear 11, Res 50, Current Pos 14702, Target Pos 14702 + 140460 [1826918][E](ERG_Mode): Watts previously processed. + 140461 [1827626][E](PTable): Averaged Entry: watts=265.299988, cad=90.199997, targetPosition=1472.000000, (6)(9) + 140462 [1827627][E](PTData): Cleaned 257 readings + 140463 [1827637][E](PTData): Existing entry averaged (6)(9)(1442), readings(9) + 140464 [1827638][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140465 [1827652][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140466 [1827661][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140467 [1827662][E](PTable): New Entry Processed in 37 ms + 140468 [1827663][E](PTable): Power Buffer Reset + 140469 [1829031][E](ERG_Mode): Watts previously processed. + 140470 [1829738][E](ERG_Mode): Proportional: -9.000000 + 140471 [1831142][E](ERG_Mode): Watts previously processed. + 140472 [1832408][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 255, Cad 88, HR 148, Gear 11, Res 50, Current Pos 14694, Target Pos 14694 + 140473 [1832561][E](PTable): Using detected travel limits during homing + 140474 [1833269][E](ERG_Mode): Watts previously processed. + 140475 [1833978][E](PTable): Averaged Entry: watts=260.700012, cad=88.699997, targetPosition=1468.900024, (6)(9) + 140476 [1833979][E](PTData): Cleaned 257 readings + 140477 [1833990][E](PTData): Existing entry averaged (6)(9)(1444), readings(10) + 140478 [1833991][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140479 [1834004][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140480 [1834013][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 2 ms + 140481 [1834015][E](PTable): New Entry Processed in 37 ms + 140482 [1834015][E](PTable): Power Buffer Reset + 140483 [1835396][E](ERG_Mode): Watts previously processed. + 140484 [1836099][E](ERG_Mode): Proportional: -30.000000 + 140485 [1837512][E](ERG_Mode): Watts previously processed. + 140486 [1838423][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 278, Cad 91, HR 148, Gear 11, Res 49, Current Pos 14613, Target Pos 14608 + 140487 [1838928][E](ERG_Mode): Watts previously processed. + 140488 [1840334][E](PTable): Averaged Entry: watts=266.399994, cad=89.900002, targetPosition=1465.699951, (6)(9) + 140489 [1840335][E](PTData): Cleaned 257 readings + 140490 [1840345][E](PTData): Existing entry averaged (6)(9)(1445), readings(11) + 140491 [1840346][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140492 [1840360][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140493 [1840369][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140494 [1840370][E](PTable): New Entry Processed in 36 ms + 140495 [1840370][E](PTable): Power Buffer Reset + 140496 [1841041][E](ERG_Mode): Watts previously processed. + 140497 [1841747][E](ERG_Mode): Proportional: 0.000000 + 140498 [1843162][E](ERG_Mode): Watts previously processed. + 140499 [1844441][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 272, Cad 91, HR 150, Gear 11, Res 49, Current Pos 14599, Target Pos 14599 + 140500 [1845279][E](ERG_Mode): Watts previously processed. + 140501 [1846704][E](PTable): Averaged Entry: watts=266.000000, cad=90.599998, targetPosition=1458.599976, (6)(9) + 140502 [1846705][E](PTData): Cleaned 257 readings + 140503 [1846715][E](PTData): Existing entry averaged (6)(9)(1446), readings(12) + 140504 [1846716][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140505 [1846730][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140506 [1846739][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140507 [1846740][E](PTable): New Entry Processed in 37 ms + 140508 [1846740][E](PTable): Power Buffer Reset + 140509 [1846751][E](ERG_Mode): Proportional: -69.000000 + 140510 [1847413][E](ERG_Mode): Watts previously processed. + 140511 [1849529][E](ERG_Mode): Watts previously processed. + 140512 [1850450][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 262, Cad 92, HR 152, Gear 11, Res 49, Current Pos 14413, Target Pos 14413 + 140513 [1850944][E](ERG_Mode): Watts previously processed. + 140514 [1852353][E](ERG_Mode): Proportional: -8.000000 + 140515 [1853062][E](PTable): Averaged Entry: watts=271.000000, cad=92.400002, targetPosition=1442.199951, (6)(9) + 140516 [1853063][E](PTData): Cleaned 257 readings + 140517 [1853073][E](PTData): Existing entry averaged (6)(9)(1445), readings(13) + 140518 [1853074][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140519 [1853088][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140520 [1853097][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140521 [1853098][E](PTable): New Entry Processed in 36 ms + 140522 [1853098][E](PTable): Power Buffer Reset + 140523 [1853109][E](ERG_Mode): Watts previously processed. + 140524 [1855176][E](ERG_Mode): Watts previously processed. + 140525 [1856479][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 254, Cad 91, HR 153, Gear 11, Res 49, Current Pos 14387, Target Pos 14387 + 140526 [1857298][E](ERG_Mode): Watts previously processed. + 140527 [1858008][E](ERG_Mode): Proportional: 2.000000 + 140528 [1859414][E](PTable): Averaged Entry: watts=257.100006, cad=91.599998, targetPosition=1437.599976, (6)(9) + 140529 [1859415][E](PTData): Cleaned 257 readings + 140530 [1859425][E](PTData): Existing entry averaged (6)(9)(1444), readings(14) + 140531 [1859426][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140532 [1859440][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140533 [1859449][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140534 [1859450][E](PTable): New Entry Processed in 37 ms + 140535 [1859450][E](PTable): Power Buffer Reset + 140536 [1859461][E](ERG_Mode): Watts previously processed. + 140537 [1862490][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 264, Cad 93, HR 155, Gear 11, Res 49, Current Pos 14402, Target Pos 14402 + 140538 [1862946][E](ERG_Mode): Watts previously processed. + 140539 [1863654][E](ERG_Mode): Proportional: -33.000000 + 140540 [1865063][E](ERG_Mode): Watts previously processed. + 140541 [1865771][E](PTable): Averaged Entry: watts=260.500000, cad=92.599998, targetPosition=1438.000000, (6)(9) + 140542 [1865772][E](PTData): Cleaned 257 readings + 140543 [1865782][E](PTData): Existing entry averaged (6)(9)(1443), readings(15) + 140544 [1865783][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140545 [1865797][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140546 [1865806][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140547 [1865808][E](PTable): New Entry Processed in 37 ms + 140548 [1865808][E](PTable): Power Buffer Reset + 140549 [1867176][E](ERG_Mode): Watts previously processed. + 140550 [1868502][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 262, Cad 94, HR 156, Gear 11, Res 48, Current Pos 14343, Target Pos 14343 + 140551 [1868593][E](PTable): Using detected travel limits during homing + 140552 [1869300][E](ERG_Mode): Watts previously processed. + 140553 [1870009][E](ERG_Mode): Proportional: 33.000000 + 140554 [1871419][E](ERG_Mode): Watts previously processed. + 140555 [1872126][E](PTable): Averaged Entry: watts=260.500000, cad=92.900002, targetPosition=1435.500000, (6)(9) + 140556 [1872127][E](PTData): Cleaned 257 readings + 140557 [1872137][E](PTData): Existing entry averaged (6)(9)(1442), readings(16) + 140558 [1872138][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140559 [1872152][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140560 [1872162][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 4 ms + 140561 [1872163][E](PTable): New Entry Processed in 37 ms + 140562 [1872163][E](PTable): Power Buffer Reset + 140563 [1874235][E](ERG_Mode): Watts previously processed. + 140564 [1874511][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 242, Cad 91, HR 157, Gear 11, Res 49, Current Pos 14435, Target Pos 14435 + 140565 [1875646][E](ERG_Mode): Proportional: 78.000000 + 140566 [1876355][E](ERG_Mode): Watts previously processed. + 140567 [1878483][E](PTable): Averaged Entry: watts=247.500000, cad=90.099998, targetPosition=1449.000000, (6)(8) + 140568 [1878484][E](PTData): Cleaned 257 readings + 140569 [1878494][E](PTData): Existing entry averaged (6)(8)(1415), readings(20) + 140570 [1878495][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140571 [1878509][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140572 [1878518][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140573 [1878519][E](PTable): New Entry Processed in 36 ms + 140574 [1878520][E](PTable): Power Buffer Reset + 140575 [1879194][E](ERG_Mode): Watts previously processed. + 140576 [1880526][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 250, Cad 89, HR 157, Gear 11, Res 50, Current Pos 14706, Target Pos 14706 + 140577 [1881308][E](ERG_Mode): Watts previously processed. + 140578 [1882017][E](ERG_Mode): Proportional: 60.000000 + 140579 [1884135][E](ERG_Mode): Watts previously processed. + 140580 [1884845][E](PTable): Averaged Entry: watts=248.899994, cad=87.599998, targetPosition=1477.300049, (5)(8) + 140581 [1884846][E](PTData): Cleaned 257 readings + 140582 [1884857][E](PTData): Existing entry averaged (5)(8)(1445), readings(18) + 140583 [1884858][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140584 [1884871][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140585 [1884881][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140586 [1884882][E](PTable): New Entry Processed in 38 ms + 140587 [1884882][E](PTable): Power Buffer Reset + 140588 [1886261][E](ERG_Mode): Watts previously processed. + 140589 [1886538][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 262, Cad 87, HR 159, Gear 11, Res 50, Current Pos 14919, Target Pos 14919 + 140590 [1887667][E](ERG_Mode): Proportional: -36.000000 + 140591 [1888374][E](ERG_Mode): Watts previously processed. + 140592 [1890488][E](ERG_Mode): Watts previously processed. + 140593 [1891196][E](PTable): Averaged Entry: watts=266.100006, cad=87.500000, targetPosition=1489.500000, (5)(9) + 140594 [1891198][E](PTData): Cleaned 257 readings + 140595 [1891208][E](PTData): Existing entry averaged (5)(9)(1483), readings(6) + 140596 [1891210][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140597 [1891223][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140598 [1891232][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 2 ms + 140599 [1891234][E](PTable): New Entry Processed in 38 ms + 140600 [1891234][E](PTable): Power Buffer Reset + 140601 [1892550][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 279, Cad 89, HR 159, Gear 11, Res 50, Current Pos 14763, Target Pos 14763 + 140602 [1892601][E](ERG_Mode): Watts previously processed. + 140603 [1893302][E](ERG_Mode): Proportional: -45.000000 + 140604 [1896129][E](ERG_Mode): Watts previously processed. + 140605 [1897541][E](PTable): Averaged Entry: watts=278.000000, cad=90.199997, targetPosition=1465.699951, (6)(9) + 140606 [1897542][E](PTData): Cleaned 257 readings + 140607 [1897552][E](PTData): Existing entry averaged (6)(9)(1443), readings(17) + 140608 [1897553][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140609 [1897567][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140610 [1897576][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140611 [1897577][E](PTable): New Entry Processed in 37 ms + 140612 [1897578][E](PTable): Power Buffer Reset + 140613 [1898251][E](ERG_Mode): Watts previously processed. + 140614 [1898568][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 231, Cad 87, HR 159, Gear 11, Res 49, Current Pos 14524, Target Pos 14524 + 140615 [1898953][E](ERG_Mode): Proportional: 87.000000 + 140616 [1900365][E](ERG_Mode): Watts previously processed. + 140617 [1902482][E](ERG_Mode): Watts previously processed. + 140618 [1903891][E](PTable): Averaged Entry: watts=238.500000, cad=86.500000, targetPosition=1469.599976, (5)(8) + 140619 [1903892][E](PTData): Cleaned 257 readings + 140620 [1903902][E](PTData): Existing entry averaged (5)(8)(1446), readings(19) + 140621 [1903903][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140622 [1903917][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140623 [1903926][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140624 [1903927][E](PTable): New Entry Processed in 37 ms + 140625 [1903927][E](PTable): Power Buffer Reset + 140626 [1904581][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 242, Cad 86, HR 160, Gear 11, Res 50, Current Pos 14944, Target Pos 14944 + 140627 [1904592][E](ERG_Mode): Watts previously processed. + 140628 [1904592][E](PTable): Using detected travel limits during homing + 140629 [1905298][E](ERG_Mode): Proportional: 87.000000 + 140630 [1906003][E](ERG_Mode): Watts previously processed. + 140631 [1908121][E](ERG_Mode): Watts previously processed. + 140632 [1910240][E](PTable): Averaged Entry: watts=239.500000, cad=83.500000, targetPosition=1506.900024, (5)(8) + 140633 [1910241][E](PTData): Cleaned 257 readings + 140634 [1910251][E](PTData): Existing entry averaged (5)(8)(1448), readings(20) + 140635 [1910252][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140636 [1910266][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140637 [1910275][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140638 [1910276][E](PTable): New Entry Processed in 37 ms + 140639 [1910277][E](PTable): Power Buffer Reset + 140640 [1910287][E](ERG_Mode): Watts previously processed. + 140641 [1910598][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 246, Cad 81, HR 161, Gear 11, Res 52, Current Pos 15276, Target Pos 15276 + 140642 [1910963][E](ERG_Mode): Proportional: 42.000000 + 140643 [1912373][E](ERG_Mode): Watts previously processed. + 140644 [1914493][E](ERG_Mode): Watts previously processed. + 140645 [1916607][E](PTable): Averaged Entry: watts=254.800003, cad=81.199997, targetPosition=1535.599976, (4)(8) + 140646 [1916608][E](PTData): Cleaned 257 readings + 140647 [1916619][E](PTData): Existing entry averaged (4)(8)(1496), readings(3) + 140648 [1916619][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140649 [1916633][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140650 [1916642][E](PTData): Fit Valid: 1, N: 43, Quad: 1, Time: 3 ms + 140651 [1916643][E](PTable): New Entry Processed in 36 ms + 140652 [1916644][E](PTable): Power Buffer Reset + 140653 [1916654][E](ERG_Mode): Watts previously processed. + 140654 [1916655][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 267, Cad 82, HR 166, Gear 11, Res 52, Current Pos 15395, Target Pos 15395 + 140655 [1917313][E](ERG_Mode): Proportional: -2.000000 + 140656 [1918021][E](ERG_Mode): Watts previously processed. + 140657 [1920140][E](ERG_Mode): Watts previously processed. + 140658 [1922260][E](ERG_Mode): Watts previously processed. + 140659 [1922681][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 336, Cad 84, HR 166, Gear 11, Res 52, Current Pos 15381, Target Pos 15381 + 140660 [1922962][E](PTable): Averaged Entry: watts=270.200012, cad=82.400002, targetPosition=1538.500000, (4)(9) + 140661 [1922963][E](PTData): Cleaned 257 readings + 140662 [1922973][E](PTData): New entry recorded (4)(9)(1538) + 140663 [1922974][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140664 [1922988][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 4 ms + 140665 [1922997][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140666 [1922998][E](PTable): New Entry Processed in 37 ms + 140667 [1922998][E](PTable): Power Buffer Reset + 140668 [1923009][E](ERG_Mode): Proportional: -304.000000 + 140669 [1924372][E](ERG_Mode): Watts previously processed. + 140670 [1926492][E](ERG_Mode): Watts previously processed. + 140671 [1928614][E](ERG_Mode): Proportional: -36.000000 + 140672 [1928696][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 272, Cad 87, HR 167, Gear 11, Res 50, Current Pos 14828, Target Pos 14805 + 140673 [1929335][E](PTable): Averaged Entry: watts=275.899994, cad=87.199997, targetPosition=1494.699951, (5)(9) + 140674 [1929337][E](PTData): Cleaned 256 readings + 140675 [1929347][E](PTData): Existing entry averaged (5)(9)(1484), readings(7) + 140676 [1929348][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140677 [1929362][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 4 ms + 140678 [1929371][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140679 [1929372][E](PTable): New Entry Processed in 37 ms + 140680 [1929372][E](PTable): Power Buffer Reset + 140681 [1930044][E](ERG_Mode): Watts previously processed. + 140682 [1932164][E](ERG_Mode): Watts previously processed. + 140683 [1934286][E](ERG_Mode): Watts previously processed. + 140684 [1934712][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 238, Cad 85, HR 166, Gear 11, Res 50, Current Pos 14850, Target Pos 14850 + 140685 [1934993][E](ERG_Mode): Proportional: 66.000000 + 140686 [1935696][E](PTable): Averaged Entry: watts=251.500000, cad=85.699997, targetPosition=1482.400024, (5)(8) + 140687 [1935697][E](PTData): Cleaned 256 readings + 140688 [1935707][E](PTData): Existing entry averaged (5)(8)(1449), readings(20) + 140689 [1935708][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140690 [1935722][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140691 [1935731][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140692 [1935732][E](PTable): New Entry Processed in 36 ms + 140693 [1935733][E](PTable): Power Buffer Reset + 140694 [1936403][E](ERG_Mode): Watts previously processed. + 140695 [1939231][E](ERG_Mode): Watts previously processed. + 140696 [1940636][E](ERG_Mode): Proportional: 6.000000 + 140697 [1940637][E](PTable): Using detected travel limits during homing + 140698 [1940729][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 254, Cad 83, HR 165, Gear 11, Res 51, Current Pos 15228, Target Pos 15228 + 140699 [1942054][E](PTable): Averaged Entry: watts=245.300003, cad=83.500000, targetPosition=1511.000000, (5)(8) + 140700 [1942055][E](PTData): Cleaned 256 readings + 140701 [1942065][E](PTData): Existing entry averaged (5)(8)(1451), readings(20) + 140702 [1942066][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140703 [1942080][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140704 [1942089][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140705 [1942091][E](PTable): New Entry Processed in 38 ms + 140706 [1942091][E](PTable): Power Buffer Reset + 140707 [1942101][E](ERG_Mode): Watts previously processed. + 140708 [1944167][E](ERG_Mode): Watts previously processed. + 140709 [1946286][E](ERG_Mode): Watts previously processed. + 140710 [1946743][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 252, Cad 82, HR 163, Gear 11, Res 52, Current Pos 15282, Target Pos 15282 + 140711 [1946994][E](ERG_Mode): Proportional: 8.000000 + 140712 [1948400][E](PTable): Averaged Entry: watts=251.699997, cad=82.500000, targetPosition=1525.099976, (4)(8) + 140713 [1948401][E](PTData): Cleaned 256 readings + 140714 [1948411][E](PTData): Existing entry averaged (4)(8)(1501), readings(4) + 140715 [1948412][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140716 [1948426][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140717 [1948435][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140718 [1948436][E](PTable): New Entry Processed in 36 ms + 140719 [1948437][E](PTable): Power Buffer Reset + 140720 [1948447][E](ERG_Mode): Watts previously processed. + 140721 [1951213][E](ERG_Mode): Watts previously processed. + 140722 [1952627][E](ERG_Mode): Proportional: 5.000000 + 140723 [1952759][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 255, Cad 81, HR 162, Gear 11, Res 52, Current Pos 15415, Target Pos 15415 + 140724 [1953337][E](ERG_Mode): Watts previously processed. + 140725 [1954742][E](PTable): Averaged Entry: watts=254.500000, cad=81.300003, targetPosition=1537.699951, (4)(8) + 140726 [1954743][E](PTData): Cleaned 256 readings + 140727 [1954753][E](PTData): Existing entry averaged (4)(8)(1507), readings(5) + 140728 [1954754][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140729 [1954768][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140730 [1954777][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140731 [1954778][E](PTable): New Entry Processed in 37 ms + 140732 [1954892][E](PTable): Writing File: /PowerTable.txt + 140733 [1955131][E](PTable): Power table saved successfully with 541 readings + 140734 [1955131][E](PTable): Power Buffer Reset + 140735 [1955445][E](ERG_Mode): Watts previously processed. + 140736 [1958270][E](ERG_Mode): Watts previously processed. + 140737 [1958768][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 266, Cad 82, HR 163, Gear 11, Res 52, Current Pos 15348, Target Pos 15348 + 140738 [1958974][E](ERG_Mode): Proportional: -6.000000 + 140739 [1961100][E](PTable): Averaged Entry: watts=262.500000, cad=82.000000, targetPosition=1536.099976, (4)(9) + 140740 [1961101][E](PTData): Cleaned 256 readings + 140741 [1961111][E](PTData): Existing entry averaged (4)(9)(1537), readings(2) + 140742 [1961112][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140743 [1961126][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140744 [1961135][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140745 [1961137][E](PTable): New Entry Processed in 38 ms + 140746 [1961137][E](PTable): Power Buffer Reset + 140747 [1961147][E](ERG_Mode): Watts previously processed. + 140748 [1963214][E](ERG_Mode): Watts previously processed. + 140749 [1964626][E](ERG_Mode): Proportional: -1.000000 + 140750 [1964778][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 261, Cad 81, HR 162, Gear 11, Res 52, Current Pos 15334, Target Pos 15334 + 140751 [1965336][E](ERG_Mode): Watts previously processed. + 140752 [1967456][E](PTable): Averaged Entry: watts=260.899994, cad=80.599998, targetPosition=1533.199951, (4)(9) + 140753 [1967457][E](PTData): Cleaned 256 readings + 140754 [1967467][E](PTData): Existing entry averaged (4)(9)(1536), readings(3) + 140755 [1967468][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140756 [1967482][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140757 [1967491][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140758 [1967493][E](PTable): New Entry Processed in 38 ms + 140759 [1967493][E](PTable): Power Buffer Reset + 140760 [1967503][E](ERG_Mode): Watts previously processed. + 140761 [1970279][E](ERG_Mode): Watts previously processed. + 140762 [1970790][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 268, Cad 81, HR 162, Gear 11, Res 52, Current Pos 15335, Target Pos 15335 + 140763 [1970987][E](ERG_Mode): Proportional: -8.000000 + 140764 [1972399][E](ERG_Mode): Watts previously processed. + 140765 [1973815][E](PTable): Averaged Entry: watts=256.600006, cad=80.699997, targetPosition=1534.199951, (4)(9) + 140766 [1973817][E](PTData): Cleaned 256 readings + 140767 [1973827][E](PTData): Existing entry averaged (4)(9)(1535), readings(4) + 140768 [1973828][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140769 [1973842][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 4 ms + 140770 [1973851][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140771 [1973852][E](PTable): New Entry Processed in 37 ms + 140772 [1973852][E](PTable): Power Buffer Reset + 140773 [1974523][E](ERG_Mode): Watts previously processed. + 140774 [1976650][E](ERG_Mode): Proportional: 60.000000 + 140775 [1976651][E](PTable): Using detected travel limits during homing + 140776 [1976803][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 240, Cad 79, HR 163, Gear 11, Res 52, Current Pos 15378, Target Pos 15401 + 140777 [1977360][E](ERG_Mode): Watts previously processed. + 140778 [1980186][E](PTable): Averaged Entry: watts=246.899994, cad=79.099998, targetPosition=1544.199951, (4)(8) + 140779 [1980187][E](PTData): Cleaned 256 readings + 140780 [1980197][E](PTData): Existing entry averaged (4)(8)(1512), readings(6) + 140781 [1980198][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140782 [1980212][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140783 [1980221][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140784 [1980222][E](PTable): New Entry Processed in 37 ms + 140785 [1980223][E](PTable): Power Buffer Reset + 140786 [1980233][E](ERG_Mode): Watts previously processed. + 140787 [1982304][E](ERG_Mode): Watts previously processed. + 140788 [1982812][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 252, Cad 81, HR 162, Gear 11, Res 53, Current Pos 15647, Target Pos 15647 + 140789 [1983006][E](ERG_Mode): Proportional: 8.000000 + 140790 [1984417][E](ERG_Mode): Watts previously processed. + 140791 [1986540][E](PTable): Averaged Entry: watts=256.100006, cad=79.300003, targetPosition=1564.400024, (4)(9) + 140792 [1986541][E](PTData): Cleaned 256 readings + 140793 [1986551][E](PTData): Existing entry averaged (4)(9)(1539), readings(5) + 140794 [1986552][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140795 [1986566][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140796 [1986575][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140797 [1986576][E](PTable): New Entry Processed in 37 ms + 140798 [1986577][E](PTable): Power Buffer Reset + 140799 [1986587][E](ERG_Mode): Watts previously processed. + 140800 [1988663][E](ERG_Mode): Watts previously processed. + 140801 [1988830][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 259, Cad 81, HR 162, Gear 11, Res 53, Current Pos 15651, Target Pos 15651 + 140802 [1989368][E](ERG_Mode): Proportional: 1.000000 + 140803 [1992205][E](ERG_Mode): Watts previously processed. + 140804 [1992913][E](PTable): Averaged Entry: watts=266.500000, cad=81.400002, targetPosition=1561.400024, (4)(9) + 140805 [1992914][E](PTData): Cleaned 256 readings + 140806 [1992924][E](PTData): Existing entry averaged (4)(9)(1542), readings(6) + 140807 [1992925][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140808 [1992939][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140809 [1992948][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140810 [1992950][E](PTable): New Entry Processed in 38 ms + 140811 [1992950][E](PTable): Power Buffer Reset + 140812 [1994321][E](ERG_Mode): Watts previously processed. + 140813 [1994839][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 259, Cad 79, HR 162, Gear 11, Res 52, Current Pos 15542, Target Pos 15542 + 140814 [1995024][E](ERG_Mode): Proportional: 1.000000 + 140815 [1996437][E](ERG_Mode): Watts previously processed. + 140816 [1998555][E](ERG_Mode): Watts previously processed. + 140817 [1999258][E](PTable): Averaged Entry: watts=266.299988, cad=80.500000, targetPosition=1550.400024, (4)(9) + 140818 [1999259][E](PTData): Cleaned 256 readings + 140819 [1999269][E](PTData): Existing entry averaged (4)(9)(1543), readings(7) + 140820 [1999270][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140821 [1999284][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140822 [1999293][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140823 [1999294][E](PTable): New Entry Processed in 37 ms + 140824 [1999295][E](PTable): Power Buffer Reset + 140825 [2000664][E](ERG_Mode): Watts previously processed. + 140826 [2000852][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 251, Cad 79, HR 161, Gear 11, Res 52, Current Pos 15407, Target Pos 15407 + 140827 [2001367][E](ERG_Mode): Proportional: 9.000000 + 140828 [2004197][E](ERG_Mode): Watts previously processed. + 140829 [2005603][E](PTable): Averaged Entry: watts=252.399994, cad=79.500000, targetPosition=1547.199951, (4)(8) + 140830 [2005604][E](PTData): Cleaned 256 readings + 140831 [2005614][E](PTData): Existing entry averaged (4)(8)(1516), readings(7) + 140832 [2005615][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140833 [2005629][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140834 [2005638][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140835 [2005639][E](PTable): New Entry Processed in 36 ms + 140836 [2005640][E](PTable): Power Buffer Reset + 140837 [2006311][E](ERG_Mode): Watts previously processed. + 140838 [2006869][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 298, Cad 83, HR 163, Gear 11, Res 53, Current Pos 15569, Target Pos 15569 + 140839 [2007014][E](ERG_Mode): Proportional: -114.000000 + 140840 [2008426][E](ERG_Mode): Watts previously processed. + 140841 [2010537][E](ERG_Mode): Watts previously processed. + 140842 [2011949][E](PTable): Averaged Entry: watts=275.799988, cad=82.400002, targetPosition=1541.000000, (4)(9) + 140843 [2011950][E](PTData): Cleaned 256 readings + 140844 [2011960][E](PTData): Existing entry averaged (4)(9)(1542), readings(8) + 140845 [2011961][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140846 [2011975][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140847 [2011984][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140848 [2011986][E](PTable): New Entry Processed in 37 ms + 140849 [2011986][E](PTable): Power Buffer Reset + 140850 [2012656][E](ERG_Mode): Watts previously processed. + 140851 [2012657][E](PTable): Using detected travel limits during homing + 140852 [2012885][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 262, Cad 82, HR 163, Gear 11, Res 52, Current Pos 15269, Target Pos 15269 + 140853 [2013361][E](ERG_Mode): Proportional: -2.000000 + 140854 [2014778][E](ERG_Mode): Watts previously processed. + 140855 [2016187][E](ERG_Mode): Watts previously processed. + 140856 [2018317][E](PTable): Averaged Entry: watts=260.299988, cad=81.400002, targetPosition=1526.599976, (4)(9) + 140857 [2018318][E](PTData): Cleaned 256 readings + 140858 [2018328][E](PTData): Existing entry averaged (4)(9)(1540), readings(9) + 140859 [2018329][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140860 [2018343][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140861 [2018352][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140862 [2018353][E](PTable): New Entry Processed in 37 ms + 140863 [2018353][E](PTable): Power Buffer Reset + 140864 [2018364][E](ERG_Mode): Watts previously processed. + 140865 [2018895][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 250, Cad 81, HR 162, Gear 11, Res 52, Current Pos 15278, Target Pos 15278 + 140866 [2019023][E](ERG_Mode): Proportional: 30.000000 + 140867 [2020435][E](ERG_Mode): Watts previously processed. + 140868 [2022553][E](ERG_Mode): Watts previously processed. + 140869 [2024662][E](PTable): Averaged Entry: watts=257.100006, cad=81.400002, targetPosition=1529.699951, (4)(9) + 140870 [2024663][E](PTData): Cleaned 256 readings + 140871 [2024673][E](PTData): Existing entry averaged (4)(9)(1539), readings(10) + 140872 [2024674][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140873 [2024688][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140874 [2024697][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140875 [2024698][E](PTable): New Entry Processed in 37 ms + 140876 [2024699][E](PTable): Power Buffer Reset + 140877 [2024709][E](ERG_Mode): Watts previously processed. + 140878 [2024910][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 256, Cad 81, HR 163, Gear 11, Res 52, Current Pos 15338, Target Pos 15338 + 140879 [2025367][E](ERG_Mode): Proportional: 57.000000 + 140880 [2026075][E](ERG_Mode): Watts previously processed. + 140881 [2028198][E](ERG_Mode): Watts previously processed. + 140882 [2030317][E](ERG_Mode): Watts previously processed. + 140883 [2030925][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 260, Cad 79, HR 166, Gear 11, Res 53, Current Pos 15596, Target Pos 15596 + 140884 [2031026][E](PTable): Averaged Entry: watts=244.100006, cad=79.099998, targetPosition=1545.699951, (4)(8) + 140885 [2031027][E](PTData): Cleaned 256 readings + 140886 [2031037][E](PTData): Existing entry averaged (4)(8)(1519), readings(8) + 140887 [2031038][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140888 [2031052][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140889 [2031061][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140890 [2031062][E](PTable): New Entry Processed in 36 ms + 140891 [2031063][E](PTable): Power Buffer Reset + 140892 [2031073][E](ERG_Mode): Proportional: 0.000000 + 140893 [2032435][E](ERG_Mode): Watts previously processed. + 140894 [2034552][E](ERG_Mode): Watts previously processed. + 140895 [2036674][E](ERG_Mode): Proportional: -6.000000 + 140896 [2036939][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 266, Cad 81, HR 168, Gear 11, Res 52, Current Pos 15524, Target Pos 15524 + 140897 [2037394][E](PTable): Averaged Entry: watts=265.799988, cad=80.400002, targetPosition=1556.099976, (4)(9) + 140898 [2037396][E](PTData): Cleaned 256 readings + 140899 [2037406][E](PTData): Existing entry averaged (4)(9)(1540), readings(11) + 140900 [2037407][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140901 [2037420][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140902 [2037430][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140903 [2037431][E](PTable): New Entry Processed in 37 ms + 140904 [2037432][E](PTable): Power Buffer Reset + 140905 [2038101][E](ERG_Mode): Watts previously processed. + 140906 [2040225][E](ERG_Mode): Watts previously processed. + 140907 [2042345][E](ERG_Mode): Watts previously processed. + 140908 [2042952][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 265, Cad 81, HR 169, Gear 11, Res 52, Current Pos 15439, Target Pos 15439 + 140909 [2043054][E](ERG_Mode): Proportional: -5.000000 + 140910 [2043764][E](PTable): Averaged Entry: watts=265.299988, cad=81.099998, targetPosition=1546.500000, (4)(9) + 140911 [2043765][E](PTData): Cleaned 256 readings + 140912 [2043777][E](PTData): Existing entry averaged (4)(9)(1540), readings(12) + 140913 [2043778][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140914 [2043791][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140915 [2043801][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140916 [2043802][E](PTable): New Entry Processed in 39 ms + 140917 [2043802][E](PTable): Power Buffer Reset + 140918 [2044465][E](ERG_Mode): Watts previously processed. + 140919 [2046576][E](ERG_Mode): Watts previously processed. + 140920 [2048695][E](ERG_Mode): Proportional: 33.000000 + 140921 [2048696][E](PTable): Using detected travel limits during homing + 140922 [2048964][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 249, Cad 80, HR 169, Gear 11, Res 52, Current Pos 15445, Target Pos 15445 + 140923 [2049396][E](ERG_Mode): Watts previously processed. + 140924 [2050098][E](PTable): Averaged Entry: watts=259.899994, cad=80.699997, targetPosition=1542.599976, (4)(9) + 140925 [2050099][E](PTData): Cleaned 256 readings + 140926 [2050109][E](PTData): Existing entry averaged (4)(9)(1540), readings(13) + 140927 [2050110][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140928 [2050124][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140929 [2050135][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140930 [2050136][E](PTable): New Entry Processed in 38 ms + 140931 [2050136][E](PTable): Power Buffer Reset + 140932 [2052221][E](ERG_Mode): Watts previously processed. + 140933 [2054344][E](ERG_Mode): Watts previously processed. + 140934 [2054972][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 242, Cad 78, HR 168, Gear 11, Res 53, Current Pos 15572, Target Pos 15572 + 140935 [2055053][E](ERG_Mode): Proportional: 54.000000 + 140936 [2055974][E](FTMS_SERVER): 05 b9 00 -> ERG Mode Target: 185 Current: 242 Incline: 156.800003. Responding: 80 05 01 + 140937 [2055981][E](DirConManager): Sending response message type 0x04 to client 0 + 140938 [2056463][E](PTable): Averaged Entry: watts=246.399994, cad=78.699997, targetPosition=1554.000000, (4)(8) + 140939 [2056464][E](PTData): Cleaned 256 readings + 140940 [2056475][E](PTData): Existing entry averaged (4)(8)(1522), readings(9) + 140941 [2056477][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140942 [2056490][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140943 [2056499][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140944 [2056501][E](PTable): New Entry Processed in 39 ms + 140945 [2056501][E](PTable): Power Buffer Reset + 140946 [2056511][E](ERG_Mode): SetPoint changed:215w Waiting:923ms PowerTable Result: 14900 + 140947 [2058791][E](ERG_Mode): ERG wait expired, pos: 14900, tgt: 0 + 140948 [2060203][E](ERG_Mode): Proportional: -105.000000 + 140949 [2060985][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 219, Cad 79, HR 168, Gear 11, Res 49, Current Pos 14430, Target Pos 14335 + 140950 [2062329][E](ERG_Mode): Watts previously processed. + 140951 [2064451][E](PTable): Averaged Entry: watts=223.399994, cad=79.400002, targetPosition=1445.300049, (4)(7) + 140952 [2064452][E](PTData): Cleaned 256 readings + 140953 [2064462][E](PTData): Existing entry averaged (4)(7)(1449), readings(13) + 140954 [2064463][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140955 [2064477][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140956 [2064486][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140957 [2064488][E](PTable): New Entry Processed in 37 ms + 140958 [2064488][E](PTable): Power Buffer Reset + 140959 [2064498][E](ERG_Mode): Watts previously processed. + 140960 [2065859][E](ERG_Mode): Proportional: -99.000000 + 140961 [2066567][E](ERG_Mode): Watts previously processed. + 140962 [2067003][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 193, Cad 84, HR 167, Gear 11, Res 46, Current Pos 13658, Target Pos 13658 + 140963 [2068688][E](ERG_Mode): Watts previously processed. + 140964 [2070803][E](PTable): Averaged Entry: watts=207.699997, cad=84.500000, targetPosition=1373.300049, (5)(7) + 140965 [2070804][E](PTData): Cleaned 256 readings + 140966 [2070814][E](PTData): Existing entry averaged (5)(7)(1396), readings(10) + 140967 [2070815][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140968 [2070829][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140969 [2070838][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140970 [2070839][E](PTable): New Entry Processed in 37 ms + 140971 [2070840][E](PTable): Power Buffer Reset + 140972 [2071513][E](ERG_Mode): Proportional: 48.000000 + 140973 [2072219][E](ERG_Mode): Watts previously processed. + 140974 [2073020][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 171, Cad 80, HR 165, Gear 11, Res 46, Current Pos 13737, Target Pos 13763 + 140975 [2074343][E](ERG_Mode): Watts previously processed. + 140976 [2076464][E](ERG_Mode): Watts previously processed. + 140977 [2077173][E](PTable): Averaged Entry: watts=174.800003, cad=80.099998, targetPosition=1375.800049, (4)(6) + 140978 [2077174][E](PTData): Cleaned 256 readings + 140979 [2077184][E](PTData): Existing entry averaged (4)(6)(1381), readings(7) + 140980 [2077185][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140981 [2077199][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140982 [2077208][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140983 [2077209][E](PTable): New Entry Processed in 36 ms + 140984 [2077209][E](PTable): Power Buffer Reset + 140985 [2077220][E](ERG_Mode): Proportional: 2.000000 + 140986 [2078582][E](ERG_Mode): Watts previously processed. + 140987 [2079031][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 185, Cad 81, HR 162, Gear 11, Res 47, Current Pos 13826, Target Pos 13826 + 140988 [2080693][E](ERG_Mode): Watts previously processed. + 140989 [2082811][E](ERG_Mode): Proportional: -7.000000 + 140990 [2083520][E](PTable): Averaged Entry: watts=186.600006, cad=81.000000, targetPosition=1382.000000, (4)(6) + 140991 [2083521][E](PTData): Cleaned 256 readings + 140992 [2083531][E](PTData): Existing entry averaged (4)(6)(1381), readings(8) + 140993 [2083532][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 140994 [2083546][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140995 [2083555][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 140996 [2083556][E](PTable): New Entry Processed in 36 ms + 140997 [2083556][E](PTable): Power Buffer Reset + 140998 [2084228][E](ERG_Mode): Watts previously processed. + 140999 [2085039][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 186, Cad 81, HR 161, Gear 11, Res 47, Current Pos 13818, Target Pos 13818 + 141000 [2086350][E](ERG_Mode): Watts previously processed. + 141001 [2086350][E](PTable): Using detected travel limits during homing + 141002 [2088463][E](ERG_Mode): Watts previously processed. + 141003 [2089169][E](ERG_Mode): Proportional: -5.000000 + 141004 [2089874][E](PTable): Averaged Entry: watts=186.699997, cad=81.500000, targetPosition=1380.500000, (4)(6) + 141005 [2089875][E](PTData): Cleaned 256 readings + 141006 [2089885][E](PTData): Existing entry averaged (4)(6)(1380), readings(9) + 141007 [2089886][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141008 [2089900][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141009 [2089909][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141010 [2089911][E](PTable): New Entry Processed in 37 ms + 141011 [2089911][E](PTable): Power Buffer Reset + 141012 [2090577][E](ERG_Mode): Watts previously processed. + 141013 [2091056][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 183, Cad 80, HR 158, Gear 11, Res 47, Current Pos 13834, Target Pos 13834 + 141014 [2092682][E](ERG_Mode): Watts previously processed. + 141015 [2094106][E](ERG_Mode): Watts previously processed. + 141016 [2094813][E](ERG_Mode): Proportional: -4.000000 + 141017 [2096226][E](PTable): Averaged Entry: watts=184.399994, cad=81.599998, targetPosition=1382.800049, (4)(6) + 141018 [2096227][E](PTData): Cleaned 256 readings + 141019 [2096237][E](PTData): Existing entry averaged (4)(6)(1380), readings(10) + 141020 [2096238][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141021 [2096252][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141022 [2096261][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141023 [2096262][E](PTable): New Entry Processed in 37 ms + 141024 [2096263][E](PTable): Power Buffer Reset + 141025 [2096273][E](ERG_Mode): Watts previously processed. + 141026 [2097071][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 184, Cad 82, HR 157, Gear 11, Res 47, Current Pos 13825, Target Pos 13825 + 141027 [2097635][E](ERG_Mode): Watts previously processed. + 141028 [2100461][E](ERG_Mode): Watts previously processed. + 141029 [2101170][E](ERG_Mode): Proportional: -60.000000 + 141030 [2102578][E](PTable): Averaged Entry: watts=196.100006, cad=84.000000, targetPosition=1373.500000, (5)(7) + 141031 [2102579][E](PTData): Cleaned 256 readings + 141032 [2102589][E](PTData): Existing entry averaged (5)(7)(1394), readings(11) + 141033 [2102590][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141034 [2102604][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141035 [2102613][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141036 [2102614][E](PTable): New Entry Processed in 37 ms + 141037 [2102615][E](PTable): Power Buffer Reset + 141038 [2102625][E](ERG_Mode): Watts previously processed. + 141039 [2103080][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 189, Cad 85, HR 156, Gear 11, Res 46, Current Pos 13603, Target Pos 13603 + 141040 [2105399][E](ERG_Mode): Watts previously processed. + 141041 [2106813][E](ERG_Mode): Proportional: -3.000000 + 141042 [2108236][E](ERG_Mode): Watts previously processed. + 141043 [2108943][E](PTable): Averaged Entry: watts=186.199997, cad=84.599998, targetPosition=1358.800049, (5)(6) + 141044 [2108944][E](PTData): Cleaned 256 readings + 141045 [2108954][E](PTData): Existing entry averaged (5)(6)(1330), readings(10) + 141046 [2108955][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141047 [2108969][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141048 [2108978][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141049 [2108980][E](PTable): New Entry Processed in 36 ms + 141050 [2108980][E](PTable): Power Buffer Reset + 141051 [2109099][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 180, Cad 83, HR 154, Gear 11, Res 46, Current Pos 13595, Target Pos 13595 + 141052 [2110357][E](ERG_Mode): Watts previously processed. + 141053 [2112477][E](ERG_Mode): Watts previously processed. + 141054 [2113183][E](ERG_Mode): Proportional: 7.000000 + 141055 [2114598][E](ERG_Mode): Watts previously processed. + 141056 [2115108][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 189, Cad 83, HR 153, Gear 11, Res 46, Current Pos 13647, Target Pos 13647 + 141057 [2115300][E](PTable): Averaged Entry: watts=180.100006, cad=82.500000, targetPosition=1361.900024, (4)(6) + 141058 [2115301][E](PTData): Cleaned 256 readings + 141059 [2115311][E](PTData): Existing entry averaged (4)(6)(1378), readings(11) + 141060 [2115312][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141061 [2115325][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141062 [2115335][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141063 [2115336][E](PTable): New Entry Processed in 37 ms + 141064 [2115336][E](PTable): Power Buffer Reset + 141065 [2115995][E](FTMS_SERVER): 05 f5 00 -> ERG Mode Target: 245 Current: 185 Incline: 136.429993. Responding: 80 05 01 + 141066 [2116000][E](DirConManager): Sending response message type 0x04 to client 0 + 141067 [2116022][E](ERG_Mode): SetPoint changed:215w Waiting:913ms PowerTable Result: 14390 + 141068 [2118345][E](ERG_Mode): ERG wait expired, pos: 14390, tgt: 0 + 141069 [2118346][E](ERG_Mode): Proportional: 228.000000 + 141070 [2120458][E](ERG_Mode): Watts previously processed. + 141071 [2121125][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 227, Cad 85, HR 152, Gear 11, Res 50, Current Pos 14901, Target Pos 14901 + 141072 [2122565][E](ERG_Mode): Watts previously processed. + 141073 [2123274][E](PTable): Averaged Entry: watts=213.800003, cad=84.000000, targetPosition=1457.699951, (5)(7) + 141074 [2123275][E](PTData): Cleaned 256 readings + 141075 [2123285][E](PTData): Existing entry averaged (5)(7)(1398), readings(12) + 141076 [2123286][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141077 [2123300][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141078 [2123309][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141079 [2123310][E](PTable): New Entry Processed in 37 ms + 141080 [2123310][E](PTable): Power Buffer Reset + 141081 [2123979][E](ERG_Mode): Proportional: -5.000000 + 141082 [2123980][E](PTable): Using detected travel limits during homing + 141083 [2124687][E](ERG_Mode): Watts previously processed. + 141084 [2126802][E](ERG_Mode): Watts previously processed. + 141085 [2127140][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 249, Cad 85, HR 151, Gear 11, Res 50, Current Pos 14913, Target Pos 14913 + 141086 [2128214][E](ERG_Mode): Watts previously processed. + 141087 [2129627][E](PTable): Averaged Entry: watts=249.600006, cad=84.500000, targetPosition=1492.699951, (5)(8) + 141088 [2129628][E](PTData): Cleaned 256 readings + 141089 [2129638][E](PTData): Existing entry averaged (5)(8)(1452), readings(20) + 141090 [2129639][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141091 [2129653][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141092 [2129662][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141093 [2129663][E](PTable): New Entry Processed in 37 ms + 141094 [2129664][E](PTable): Power Buffer Reset + 141095 [2129674][E](ERG_Mode): Proportional: 3.000000 + 141096 [2130329][E](ERG_Mode): Watts previously processed. + 141097 [2132449][E](ERG_Mode): Watts previously processed. + 141098 [2133158][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 259, Cad 85, HR 150, Gear 11, Res 50, Current Pos 14871, Target Pos 14871 + 141099 [2134573][E](ERG_Mode): Watts previously processed. + 141100 [2135289][E](ERG_Mode): Proportional: 7.000000 + 141101 [2135999][E](PTable): Averaged Entry: watts=246.500000, cad=84.400002, targetPosition=1486.699951, (5)(8) + 141102 [2136000][E](PTData): Cleaned 256 readings + 141103 [2136010][E](PTData): Existing entry averaged (5)(8)(1453), readings(20) + 141104 [2136011][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141105 [2136025][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141106 [2136034][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141107 [2136036][E](PTable): New Entry Processed in 38 ms + 141108 [2136036][E](PTable): Power Buffer Reset + 141109 [2136705][E](ERG_Mode): Watts previously processed. + 141110 [2138111][E](ERG_Mode): Watts previously processed. + 141111 [2139173][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 250, Cad 83, HR 150, Gear 11, Res 50, Current Pos 14923, Target Pos 14923 + 141112 [2140231][E](ERG_Mode): Watts previously processed. + 141113 [2140938][E](ERG_Mode): Proportional: 1.000000 + 141114 [2142345][E](PTable): Averaged Entry: watts=252.800003, cad=84.300003, targetPosition=1487.699951, (5)(8) + 141115 [2142346][E](PTData): Cleaned 256 readings + 141116 [2142356][E](PTData): Existing entry averaged (5)(8)(1454), readings(20) + 141117 [2142357][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141118 [2142371][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141119 [2142380][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141120 [2142382][E](PTable): New Entry Processed in 37 ms + 141121 [2142382][E](PTable): Power Buffer Reset + 141122 [2142392][E](ERG_Mode): Watts previously processed. + 141123 [2144458][E](ERG_Mode): Watts previously processed. + 141124 [2145184][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 285, Cad 97, HR 151, Gear 11, Res 47, Current Pos 14037, Target Pos 13918 + 141125 [2146578][E](ERG_Mode): Watts previously processed. + 141126 [2147286][E](ERG_Mode): Proportional: 33.000000 + 141127 [2148693][E](PTable): Averaged Entry: watts=274.700012, cad=93.000000, targetPosition=1413.800049, (7)(9) + 141128 [2148694][E](PTData): Cleaned 256 readings + 141129 [2148704][E](PTData): Existing entry averaged (7)(9)(1413), readings(9) + 141130 [2148705][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141131 [2148719][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141132 [2148728][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141133 [2148729][E](PTable): New Entry Processed in 36 ms + 141134 [2148730][E](PTable): Power Buffer Reset + 141135 [2148740][E](ERG_Mode): Watts previously processed. + 141136 [2151201][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 232, Cad 91, HR 151, Gear 11, Res 48, Current Pos 14138, Target Pos 14138 + 141137 [2152233][E](ERG_Mode): Watts previously processed. + 141138 [2152941][E](ERG_Mode): Proportional: -7.000000 + 141139 [2154348][E](ERG_Mode): Watts previously processed. + 141140 [2155055][E](PTable): Averaged Entry: watts=243.300003, cad=91.800003, targetPosition=1408.500000, (6)(8) + 141141 [2155056][E](PTData): Cleaned 256 readings + 141142 [2155066][E](PTData): Existing entry averaged (6)(8)(1414), readings(20) + 141143 [2155067][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141144 [2155081][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141145 [2155090][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141146 [2155092][E](PTable): New Entry Processed in 37 ms + 141147 [2155092][E](PTable): Power Buffer Reset + 141148 [2156462][E](ERG_Mode): Watts previously processed. + 141149 [2157211][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 234, Cad 94, HR 152, Gear 11, Res 47, Current Pos 14006, Target Pos 14035 + 141150 [2158583][E](ERG_Mode): Watts previously processed. + 141151 [2159290][E](ERG_Mode): Proportional: 54.000000 + 141152 [2159998][E](PTable): Using detected travel limits during homing + 141153 [2160704][E](ERG_Mode): Watts previously processed. + 141154 [2161414][E](PTable): Averaged Entry: watts=243.100006, cad=93.400002, targetPosition=1404.400024, (7)(8) + 141155 [2161415][E](PTData): Cleaned 256 readings + 141156 [2161425][E](PTData): Existing entry averaged (7)(8)(1367), readings(19) + 141157 [2161426][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141158 [2161440][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141159 [2161450][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141160 [2161451][E](PTable): New Entry Processed in 38 ms + 141161 [2161452][E](PTable): Power Buffer Reset + 141162 [2163223][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 263, Cad 94, HR 155, Gear 11, Res 47, Current Pos 14039, Target Pos 14039 + 141163 [2163535][E](ERG_Mode): Watts previously processed. + 141164 [2164945][E](ERG_Mode): Proportional: -108.000000 + 141165 [2166371][E](ERG_Mode): Watts previously processed. + 141166 [2167784][E](PTable): Averaged Entry: watts=256.700012, cad=95.900002, targetPosition=1395.400024, (7)(9) + 141167 [2167785][E](PTData): Cleaned 256 readings + 141168 [2167796][E](PTData): Existing entry averaged (7)(9)(1411), readings(10) + 141169 [2167797][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141170 [2167810][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141171 [2167820][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141172 [2167823][E](PTable): New Entry Processed in 39 ms + 141173 [2167823][E](PTable): Power Buffer Reset + 141174 [2168488][E](ERG_Mode): Watts previously processed. + 141175 [2169236][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 242, Cad 95, HR 157, Gear 11, Res 47, Current Pos 13831, Target Pos 13831 + 141176 [2170601][E](ERG_Mode): Watts previously processed. + 141177 [2171310][E](ERG_Mode): Proportional: -1.000000 + 141178 [2172723][E](ERG_Mode): Watts previously processed. + 141179 [2174137][E](PTable): Averaged Entry: watts=241.699997, cad=95.000000, targetPosition=1382.699951, (7)(8) + 141180 [2174138][E](PTData): Cleaned 256 readings + 141181 [2174149][E](PTData): Existing entry averaged (7)(8)(1367), readings(20) + 141182 [2174150][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141183 [2174163][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141184 [2174173][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141185 [2174174][E](PTable): New Entry Processed in 37 ms + 141186 [2174174][E](PTable): Power Buffer Reset + 141187 [2175250][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 261, Cad 95, HR 160, Gear 11, Res 46, Current Pos 13795, Target Pos 13795 + 141188 [2175551][E](ERG_Mode): Watts previously processed. + 141189 [2175921][E](FTMS_SERVER): 05 91 00 -> ERG Mode Target: 145 Current: 241 Incline: 137.949997. Responding: 80 05 01 + 141190 [2175928][E](DirConManager): Sending response message type 0x04 to client 0 + 141191 [2176256][E](ERG_Mode): SetPoint changed:175w Waiting:1136ms PowerTable Result: 12270 + 141192 [2178798][E](ERG_Mode): ERG wait expired, pos: 12270, tgt: 0 + 141193 [2178799][E](ERG_Mode): Proportional: -316.000000 + 141194 [2179507][E](ERG_Mode): Watts previously processed. + 141195 [2181263][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 186, Cad 98, HR 160, Gear 11, Res 40, Current Pos 11712, Target Pos 11708 + 141196 [2181630][E](ERG_Mode): Watts previously processed. + 141197 [2182337][E](PTable): Averaged Entry: watts=219.699997, cad=96.300003, targetPosition=1266.599976, (7)(7) + 141198 [2182338][E](PTData): Cleaned 256 readings + 141199 [2182349][E](PTData): Existing entry averaged (7)(7)(1293), readings(8) + 141200 [2182350][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141201 [2182363][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 3 ms + 141202 [2182372][E](PTData): Fit Valid: 1, N: 44, Quad: 1, Time: 2 ms + 141203 [2182374][E](PTable): New Entry Processed in 37 ms + 141204 [2182374][E](PTable): Power Buffer Reset + 141205 [2183749][E](ERG_Mode): Watts previously processed. + 141206 [2184459][E](ERG_Mode): Proportional: 2.000000 + 141207 [2186567][E](ERG_Mode): Watts previously processed. + 141208 [2187276][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 154, Cad 99, HR 160, Gear 11, Res 39, Current Pos 11597, Target Pos 11597 + 141209 [2188691][E](PTable): Averaged Entry: watts=147.800003, cad=98.199997, targetPosition=1159.500000, (8)(5) + 141210 [2188692][E](PTData): Cleaned 256 readings + 141211 [2188703][E](PTData): New entry recorded (8)(5)(1159) + 141212 [2188703][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141213 [2188717][E](PTData): Fit Valid: 1, N: 45, Quad: 1, Time: 3 ms + 141214 [2188726][E](PTData): Fit Valid: 1, N: 45, Quad: 1, Time: 2 ms + 141215 [2188728][E](PTable): New Entry Processed in 37 ms + 141216 [2188728][E](PTable): Power Buffer Reset + 141217 [2189393][E](ERG_Mode): Watts previously processed. + 141218 [2190103][E](ERG_Mode): Proportional: 30.000000 + 141219 [2191516][E](ERG_Mode): Watts previously processed. + 141220 [2193292][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 130, Cad 96, HR 160, Gear 11, Res 39, Current Pos 11739, Target Pos 11739 + 141221 [2193638][E](ERG_Mode): Watts previously processed. + 141222 [2195050][E](PTable): Averaged Entry: watts=133.199997, cad=96.699997, targetPosition=1167.599976, (7)(4) + 141223 [2195051][E](PTData): Cleaned 255 readings + 141224 [2195061][E](PTData): Existing entry averaged (7)(4)(1115), readings(4) + 141225 [2195062][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141226 [2195076][E](PTData): Fit Valid: 1, N: 45, Quad: 1, Time: 3 ms + 141227 [2195085][E](PTData): Fit Valid: 1, N: 45, Quad: 1, Time: 3 ms + 141228 [2195086][E](PTable): New Entry Processed in 37 ms + 141229 [2195087][E](PTable): Power Buffer Reset + 141230 [2195759][E](ERG_Mode): Proportional: 8.000000 + 141231 [2196466][E](ERG_Mode): Watts previously processed. + 141232 [2197879][E](PTable): Using detected travel limits during homing + 141233 [2198586][E](ERG_Mode): Watts previously processed. + 141234 [2199300][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 141, Cad 96, HR 159, Gear 11, Res 40, Current Pos 11839, Target Pos 11843 + 141235 [2201418][E](PTable): Averaged Entry: watts=146.300003, cad=95.400002, targetPosition=1183.099976, (7)(5) + 141236 [2201419][E](PTData): Cleaned 255 readings + 141237 [2201429][E](PTData): Existing entry averaged (7)(5)(1165), readings(13) + 141238 [2201430][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141239 [2201444][E](PTData): Fit Valid: 1, N: 45, Quad: 1, Time: 3 ms + 141240 [2201453][E](PTData): Fit Valid: 1, N: 45, Quad: 1, Time: 3 ms + 141241 [2201454][E](PTable): New Entry Processed in 37 ms + 141242 [2201592][E](PTable): Writing File: /PowerTable.txt + 141243 [2201828][E](PTable): Power table saved successfully with 574 readings + 141244 [2201829][E](PTable): Power Buffer Reset + 141245 [2201829][E](ERG_Mode): Watts previously processed. + 141246 [2202123][E](ERG_Mode): Proportional: 36.000000 + 141247 [2202830][E](ERG_Mode): Watts previously processed. + 141248 [2205312][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 138, Cad 94, HR 157, Gear 11, Res 40, Current Pos 11900, Target Pos 11900 + 141249 [2206364][E](ERG_Mode): Watts previously processed. + 141250 [2207781][E](PTable): Averaged Entry: watts=134.800003, cad=94.900002, targetPosition=1185.599976, (7)(4) + 141251 [2207782][E](PTData): Cleaned 255 readings + 141252 [2207792][E](PTData): Existing entry averaged (7)(4)(1126), readings(5) + 141253 [2207793][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141254 [2207807][E](PTData): Fit Valid: 1, N: 45, Quad: 1, Time: 3 ms + 141255 [2207816][E](PTData): Fit Valid: 1, N: 45, Quad: 1, Time: 3 ms + 141256 [2207818][E](PTable): New Entry Processed in 38 ms + 141257 [2207818][E](PTable): Power Buffer Reset + 141258 [2207829][E](ERG_Mode): Proportional: 63.000000 + 141259 [2208484][E](ERG_Mode): Watts previously processed. + 141260 [2210604][E](ERG_Mode): Watts previously processed. + 141261 [2211323][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 133, Cad 90, HR 154, Gear 11, Res 41, Current Pos 12057, Target Pos 12093 + 141262 [2212725][E](ERG_Mode): Watts previously processed. + 141263 [2213429][E](ERG_Mode): Proportional: 45.000000 + 141264 [2214137][E](PTable): Averaged Entry: watts=130.500000, cad=91.099998, targetPosition=1204.500000, (6)(4) + 141265 [2214138][E](PTData): Cleaned 255 readings + 141266 [2214148][E](PTData): New entry recorded (6)(4)(1204) + 141267 [2214149][E](PTData): Lower Right Found 6, 5, tp1192 + 141268 [2214162][E](PTData): Fit Valid: 1, N: 45, Quad: 1, Time: 3 ms + 141269 [2214163][E](PTable): New Entry Processed in 27 ms + 141270 [2214164][E](PTable): Power Buffer Reset + 141271 [2214845][E](ERG_Mode): Watts previously processed. + 141272 [2216258][E](ERG_Mode): Watts previously processed. + 141273 [2217337][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 139, Cad 87, HR 151, Gear 11, Res 41, Current Pos 12272, Target Pos 12272 + 141274 [2218372][E](ERG_Mode): Watts previously processed. + 141275 [2219081][E](ERG_Mode): Proportional: 48.000000 + 141276 [2220493][E](PTable): Averaged Entry: watts=129.399994, cad=87.099998, targetPosition=1227.900024, (5)(4) + 141277 [2220494][E](PTData): New entry recorded (5)(4)(1227) + 141278 [2220505][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141279 [2220505][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141280 [2220519][E](PTData): Fit Valid: 1, N: 46, Quad: 1, Time: 3 ms + 141281 [2220528][E](PTData): Fit Valid: 1, N: 46, Quad: 1, Time: 3 ms + 141282 [2220530][E](PTable): New Entry Processed in 38 ms + 141283 [2220530][E](PTable): Power Buffer Reset + 141284 [2220540][E](ERG_Mode): Watts previously processed. + 141285 [2222614][E](ERG_Mode): Watts previously processed. + 141286 [2223347][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 138, Cad 86, HR 149, Gear 11, Res 42, Current Pos 12414, Target Pos 12420 + 141287 [2224730][E](ERG_Mode): Watts previously processed. + 141288 [2225438][E](ERG_Mode): Proportional: 48.000000 + 141289 [2226842][E](PTable): Averaged Entry: watts=136.100006, cad=85.199997, targetPosition=1242.599976, (5)(5) + 141290 [2226843][E](PTData): Cleaned 254 readings + 141291 [2226853][E](PTData): New entry recorded (5)(5)(1242) + 141292 [2226854][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141293 [2226865][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141294 [2226868][E](PTData): Fit Valid: 1, N: 47, Quad: 1, Time: 3 ms + 141295 [2226888][E](PTData): Fit Valid: 1, N: 47, Quad: 1, Time: 3 ms + 141296 [2226889][E](PTable): New Entry Processed in 47 ms + 141297 [2226889][E](PTable): Power Buffer Reset + 141298 [2226900][E](ERG_Mode): Watts previously processed. + 141299 [2228955][E](ERG_Mode): Watts previously processed. + 141300 [2229361][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 125, Cad 81, HR 147, Gear 11, Res 43, Current Pos 12628, Target Pos 12628 + 141301 [2230361][E](ERG_Mode): Watts previously processed. + 141302 [2231071][E](ERG_Mode): Proportional: 45.000000 + 141303 [2232479][E](ERG_Mode): Watts previously processed. + 141304 [2233187][E](PTable): Averaged Entry: watts=128.100006, cad=80.500000, targetPosition=1264.500000, (4)(4) + 141305 [2233188][E](PTData): Cleaned 253 readings + 141306 [2233198][E](PTData): New entry recorded (4)(4)(1264) + 141307 [2233199][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141308 [2233210][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 141309 [2233210][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 3 + 141310 [2233224][E](PTData): Fit Valid: 1, N: 48, Quad: 1, Time: 3 ms + 141311 [2233234][E](PTData): Fit Valid: 1, N: 48, Quad: 1, Time: 3 ms + 141312 [2233235][E](PTable): New Entry Processed in 48 ms + 141313 [2233235][E](PTable): Power Buffer Reset + 141314 [2233891][E](PTable): Using detected travel limits during homing + 141315 [2234596][E](ERG_Mode): Watts previously processed. + 141316 [2235377][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 138, Cad 80, HR 146, Gear 11, Res 43, Current Pos 12845, Target Pos 12845 + 141317 [2236003][E](FTMS_SERVER): 05 f5 00 -> ERG Mode Target: 245 Current: 134 Incline: 128.449997. Responding: 80 05 01 + 141318 [2236008][E](DirConManager): Sending response message type 0x04 to client 0 + 141319 [2236031][E](ERG_Mode): SetPoint changed:215w Waiting:1270ms PowerTable Result: 14840 + 141320 [2238704][E](ERG_Mode): ERG wait expired, pos: 14840, tgt: 0 + 141321 [2238705][E](ERG_Mode): Proportional: 515.000000 + 141322 [2239416][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 141323 [2239416][E](PTable): Power Buffer Reset + 141324 [2241387][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 205, Cad 76, HR 143, Gear 11, Res 54, Current Pos 16100, Target Pos 16100 + 141325 [2241538][E](ERG_Mode): Watts previously processed. + 141326 [2243647][E](ERG_Mode): Watts previously processed. + 141327 [2244356][E](ERG_Mode): Proportional: -69.000000 + 141328 [2245759][E](PTable): Averaged Entry: watts=235.399994, cad=75.500000, targetPosition=1601.599976, (3)(8) + 141329 [2245760][E](PTData): Cleaned 252 readings + 141330 [2245770][E](PTData): New entry recorded (3)(8)(1601) + 141331 [2245771][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141332 [2245782][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141333 [2245785][E](PTData): Fit Valid: 1, N: 49, Quad: 1, Time: 3 ms + 141334 [2245805][E](PTData): Fit Valid: 1, N: 49, Quad: 1, Time: 3 ms + 141335 [2245806][E](PTable): New Entry Processed in 48 ms + 141336 [2245806][E](PTable): Power Buffer Reset + 141337 [2245817][E](ERG_Mode): Watts previously processed. + 141338 [2247396][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 248, Cad 74, HR 140, Gear 11, Res 54, Current Pos 15947, Target Pos 15947 + 141339 [2247871][E](ERG_Mode): Watts previously processed. + 141340 [2249990][E](ERG_Mode): Proportional: -8.000000 + 141341 [2251399][E](ERG_Mode): Watts previously processed. + 141342 [2252108][E](PTable): Averaged Entry: watts=246.300003, cad=73.900002, targetPosition=1594.800049, (3)(8) + 141343 [2252110][E](PTData): Cleaned 251 readings + 141344 [2252120][E](PTData): Existing entry averaged (3)(8)(1598), readings(2) + 141345 [2252121][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141346 [2252132][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141347 [2252146][E](PTData): Fit Valid: 1, N: 49, Quad: 1, Time: 4 ms + 141348 [2252155][E](PTData): Fit Valid: 1, N: 49, Quad: 1, Time: 3 ms + 141349 [2252157][E](PTable): New Entry Processed in 49 ms + 141350 [2252157][E](PTable): Power Buffer Reset + 141351 [2252810][E](ERG_Mode): Watts previously processed. + 141352 [2253408][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 238, Cad 73, HR 139, Gear 11, Res 54, Current Pos 15952, Target Pos 15952 + 141353 [2255639][E](ERG_Mode): Watts previously processed. + 141354 [2256349][E](ERG_Mode): Proportional: 9.000000 + 141355 [2257752][E](ERG_Mode): Watts previously processed. + 141356 [2258459][E](PTable): Averaged Entry: watts=242.399994, cad=72.900002, targetPosition=1597.699951, (2)(8) + 141357 [2258460][E](PTData): Cleaned 251 readings + 141358 [2258470][E](PTData): New entry recorded (2)(8)(1597) + 141359 [2258470][E](PTData): Greater Down Found 3, 8, tp1598 + 141360 [2258484][E](PTData): Fit Valid: 1, N: 49, Quad: 1, Time: 3 ms + 141361 [2258485][E](PTable): New Entry Processed in 26 ms + 141362 [2258486][E](PTable): Power Buffer Reset + 141363 [2259419][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 260, Cad 75, HR 139, Gear 11, Res 54, Current Pos 15915, Target Pos 15915 + 141364 [2259875][E](ERG_Mode): Watts previously processed. + 141365 [2261997][E](ERG_Mode): Watts previously processed. + 141366 [2262705][E](ERG_Mode): Proportional: -3.000000 + 141367 [2263412][E](ERG_Mode): Watts previously processed. + 141368 [2264825][E](PTable): Averaged Entry: watts=247.800003, cad=73.800003, targetPosition=1592.300049, (3)(8) + 141369 [2264826][E](PTData): Existing entry averaged (3)(8)(1596), readings(2) + 141370 [2264837][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141371 [2264838][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141372 [2264851][E](PTData): Fit Valid: 1, N: 49, Quad: 1, Time: 3 ms + 141373 [2264862][E](PTData): Fit Valid: 1, N: 49, Quad: 1, Time: 4 ms + 141374 [2264863][E](PTable): New Entry Processed in 38 ms + 141375 [2264864][E](PTable): Power Buffer Reset + 141376 [2265435][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 239, Cad 73, HR 140, Gear 11, Res 54, Current Pos 15929, Target Pos 15929 + 141377 [2265527][E](ERG_Mode): Watts previously processed. + 141378 [2267653][E](ERG_Mode): Watts previously processed. + 141379 [2268361][E](ERG_Mode): Proportional: 60.000000 + 141380 [2269769][E](ERG_Mode): Watts previously processed. + 141381 [2271180][E](PTable): Averaged Entry: watts=231.199997, cad=72.000000, targetPosition=1600.800049, (2)(8) + 141382 [2271181][E](PTData): Cleaned 251 readings + 141383 [2271191][E](PTData): New entry recorded (2)(8)(1600) + 141384 [2271192][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141385 [2271203][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141386 [2271207][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 4 ms + 141387 [2271217][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141388 [2271218][E](PTable): New Entry Processed in 39 ms + 141389 [2271218][E](PTable): Power Buffer Reset + 141390 [2271450][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 238, Cad 72, HR 140, Gear 11, Res 55, Current Pos 16155, Target Pos 16155 + 141391 [2271889][E](ERG_Mode): Watts previously processed. + 141392 [2271889][E](PTable): Using detected travel limits during homing + 141393 [2274001][E](ERG_Mode): Proportional: 4.000000 + 141394 [2275415][E](ERG_Mode): Watts previously processed. + 141395 [2277464][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 219, Cad 69, HR 141, Gear 11, Res 55, Current Pos 16335, Target Pos 16335 + 141396 [2277535][E](PTable): Averaged Entry: watts=234.000000, cad=71.500000, targetPosition=1618.400024, (2)(8) + 141397 [2277536][E](PTData): Cleaned 250 readings + 141398 [2277546][E](PTData): Existing entry averaged (2)(8)(1606), readings(2) + 141399 [2277547][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141400 [2277557][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141401 [2277571][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141402 [2277581][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141403 [2277582][E](PTable): New Entry Processed in 48 ms + 141404 [2277582][E](PTable): Power Buffer Reset + 141405 [2277593][E](ERG_Mode): Watts previously processed. + 141406 [2279649][E](ERG_Mode): Watts previously processed. + 141407 [2280356][E](ERG_Mode): Proportional: 45.000000 + 141408 [2281758][E](ERG_Mode): Watts previously processed. + 141409 [2283474][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 235, Cad 70, HR 143, Gear 11, Res 56, Current Pos 16605, Target Pos 16605 + 141410 [2283883][E](PTable): Averaged Entry: watts=228.899994, cad=68.900002, targetPosition=1647.000000, (2)(8) + 141411 [2283884][E](PTData): Cleaned 250 readings + 141412 [2283895][E](PTData): Existing entry averaged (2)(8)(1616), readings(3) + 141413 [2283896][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141414 [2283906][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141415 [2283920][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 4 ms + 141416 [2283929][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141417 [2283931][E](PTable): New Entry Processed in 48 ms + 141418 [2283931][E](PTable): Power Buffer Reset + 141419 [2285309][E](ERG_Mode): Watts previously processed. + 141420 [2286019][E](ERG_Mode): Proportional: 51.000000 + 141421 [2287425][E](ERG_Mode): Watts previously processed. + 141422 [2289490][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 258, Cad 68, HR 147, Gear 11, Res 57, Current Pos 16803, Target Pos 16803 + 141423 [2289542][E](ERG_Mode): Watts previously processed. + 141424 [2290244][E](PTable): Averaged Entry: watts=234.800003, cad=68.000000, targetPosition=1674.900024, (2)(8) + 141425 [2290245][E](PTData): Cleaned 250 readings + 141426 [2290255][E](PTData): Existing entry averaged (2)(8)(1627), readings(4) + 141427 [2290257][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141428 [2290267][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141429 [2290281][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 4 ms + 141430 [2290290][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141431 [2290292][E](PTable): New Entry Processed in 49 ms + 141432 [2290292][E](PTable): Power Buffer Reset + 141433 [2291650][E](ERG_Mode): Watts previously processed. + 141434 [2292358][E](ERG_Mode): Proportional: -30.000000 + 141435 [2293768][E](ERG_Mode): Watts previously processed. + 141436 [2295504][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 240, Cad 68, HR 150, Gear 11, Res 57, Current Pos 16793, Target Pos 16793 + 141437 [2296017][E](FTMS_SERVER): 05 91 00 -> ERG Mode Target: 145 Current: 228 Incline: 168.440002. Responding: 80 05 01 + 141438 [2296024][E](DirConManager): Sending response message type 0x04 to client 0 + 141439 [2296595][E](PTable): Averaged Entry: watts=246.600006, cad=68.599998, targetPosition=1681.199951, (2)(8) + 141440 [2296596][E](PTData): Cleaned 250 readings + 141441 [2296606][E](PTData): Existing entry averaged (2)(8)(1636), readings(5) + 141442 [2296607][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 141443 [2296621][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141444 [2296631][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141445 [2296632][E](PTable): New Entry Processed in 37 ms + 141446 [2296632][E](PTable): Power Buffer Reset + 141447 [2296643][E](ERG_Mode): SetPoint changed:175w Waiting:1198ms PowerTable Result: 15100 + 141448 [2299201][E](ERG_Mode): ERG wait expired, pos: 15100, tgt: 0 + 141449 [2299202][E](ERG_Mode): Proportional: -300.000000 + 141450 [2300607][E](ERG_Mode): Watts previously processed. + 141451 [2301515][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 176, Cad 68, HR 151, Gear 11, Res 49, Current Pos 14502, Target Pos 14471 + 141452 [2302727][E](ERG_Mode): Watts previously processed. + 141453 [2304843][E](PTable): Averaged Entry: watts=184.100006, cad=67.400002, targetPosition=1460.300049, (1)(6) + 141454 [2304844][E](PTData): Cleaned 250 readings + 141455 [2304854][E](PTData): New entry recorded (1)(6)(1460) + 141456 [2304854][E](PTData): Greater Down Found 2, 6, tp1477 + 141457 [2304868][E](PTData): Fit Valid: 1, N: 49, Quad: 1, Time: 3 ms + 141458 [2304869][E](PTable): New Entry Processed in 27 ms + 141459 [2304870][E](PTable): Power Buffer Reset + 141460 [2304880][E](ERG_Mode): Watts previously processed. + 141461 [2305554][E](ERG_Mode): Proportional: -72.000000 + 141462 [2307530][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 159, Cad 71, HR 151, Gear 11, Res 48, Current Pos 14162, Target Pos 14162 + 141463 [2308382][E](ERG_Mode): Watts previously processed. + 141464 [2309791][E](PTable): Using detected travel limits during homing + 141465 [2310499][E](ERG_Mode): Watts previously processed. + 141466 [2311208][E](PTable): Averaged Entry: watts=157.500000, cad=70.900002, targetPosition=1420.300049, (2)(5) + 141467 [2311209][E](PTData): Cleaned 1 readings + 141468 [2311219][E](PTData): New entry recorded (2)(5)(1420) + 141469 [2311220][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141470 [2311231][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141471 [2311234][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141472 [2311254][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141473 [2311255][E](PTable): New Entry Processed in 48 ms + 141474 [2311256][E](PTable): Power Buffer Reset + 141475 [2311266][E](ERG_Mode): Proportional: -63.000000 + 141476 [2312615][E](ERG_Mode): Watts previously processed. + 141477 [2313545][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 150, Cad 72, HR 152, Gear 11, Res 47, Current Pos 14019, Target Pos 14019 + 141478 [2314728][E](ERG_Mode): Watts previously processed. + 141479 [2316845][E](ERG_Mode): Watts previously processed. + 141480 [2317552][E](PTable): Averaged Entry: watts=150.899994, cad=71.000000, targetPosition=1402.800049, (2)(5) + 141481 [2317554][E](PTData): Cleaned 250 readings + 141482 [2317564][E](PTData): Existing entry averaged (2)(5)(1401), readings(2) + 141483 [2317565][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141484 [2317576][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141485 [2317589][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141486 [2317599][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141487 [2317600][E](PTable): New Entry Processed in 48 ms + 141488 [2317601][E](PTable): Power Buffer Reset + 141489 [2317611][E](ERG_Mode): Proportional: 5.000000 + 141490 [2318960][E](ERG_Mode): Watts previously processed. + 141491 [2319557][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 143, Cad 69, HR 154, Gear 11, Res 47, Current Pos 14035, Target Pos 14035 + 141492 [2321788][E](ERG_Mode): Watts previously processed. + 141493 [2323194][E](ERG_Mode): Proportional: 9.000000 + 141494 [2323912][E](PTable): Averaged Entry: watts=137.300003, cad=69.000000, targetPosition=1405.800049, (2)(5) + 141495 [2323914][E](PTData): Cleaned 250 readings + 141496 [2323925][E](PTData): Existing entry averaged (2)(5)(1394), readings(3) + 141497 [2323926][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141498 [2323936][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141499 [2323950][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 4 ms + 141500 [2323959][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141501 [2323961][E](PTable): New Entry Processed in 49 ms + 141502 [2323961][E](PTable): Power Buffer Reset + 141503 [2324622][E](ERG_Mode): Watts previously processed. + 141504 [2325573][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 156, Cad 69, HR 154, Gear 11, Res 48, Current Pos 14085, Target Pos 14085 + 141505 [2326747][E](ERG_Mode): Watts previously processed. + 141506 [2328865][E](ERG_Mode): Proportional: 0.000000 + 141507 [2329571][E](ERG_Mode): Watts previously processed. + 141508 [2330279][E](PTable): Averaged Entry: watts=151.800003, cad=71.400002, targetPosition=1402.699951, (2)(5) + 141509 [2330280][E](PTData): Cleaned 250 readings + 141510 [2330290][E](PTData): Existing entry averaged (2)(5)(1390), readings(4) + 141511 [2330293][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141512 [2330304][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141513 [2330308][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 4 ms + 141514 [2330317][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141515 [2330319][E](PTable): New Entry Processed in 41 ms + 141516 [2330319][E](PTable): Power Buffer Reset + 141517 [2331588][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 140, Cad 71, HR 153, Gear 11, Res 47, Current Pos 13970, Target Pos 13970 + 141518 [2331689][E](ERG_Mode): Watts previously processed. + 141519 [2333803][E](ERG_Mode): Watts previously processed. + 141520 [2334504][E](ERG_Mode): Proportional: 1.000000 + 141521 [2336636][E](PTable): Averaged Entry: watts=144.000000, cad=70.599998, targetPosition=1396.699951, (2)(5) + 141522 [2336638][E](PTData): Cleaned 250 readings + 141523 [2336649][E](PTData): Existing entry averaged (2)(5)(1386), readings(5) + 141524 [2336650][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141525 [2336660][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141526 [2336664][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 4 ms + 141527 [2336684][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 4 ms + 141528 [2336685][E](PTable): New Entry Processed in 49 ms + 141529 [2336685][E](PTable): Power Buffer Reset + 141530 [2336696][E](ERG_Mode): Watts previously processed. + 141531 [2337600][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 142, Cad 71, HR 151, Gear 11, Res 47, Current Pos 13972, Target Pos 13972 + 141532 [2338750][E](ERG_Mode): Watts previously processed. + 141533 [2340168][E](ERG_Mode): Proportional: -42.000000 + 141534 [2341575][E](ERG_Mode): Watts previously processed. + 141535 [2342984][E](PTable): Averaged Entry: watts=144.300003, cad=71.000000, targetPosition=1393.599976, (2)(5) + 141536 [2342985][E](PTData): Cleaned 250 readings + 141537 [2342996][E](PTData): Existing entry averaged (2)(5)(1383), readings(6) + 141538 [2342997][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141539 [2343007][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141540 [2343021][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141541 [2343031][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 4 ms + 141542 [2343032][E](PTable): New Entry Processed in 49 ms + 141543 [2343032][E](PTable): Power Buffer Reset + 141544 [2343613][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 145, Cad 70, HR 148, Gear 11, Res 47, Current Pos 13930, Target Pos 13930 + 141545 [2343694][E](ERG_Mode): Watts previously processed. + 141546 [2345812][E](ERG_Mode): Watts previously processed. + 141547 [2345812][E](PTable): Using detected travel limits during homing + 141548 [2346521][E](ERG_Mode): Proportional: -78.000000 + 141549 [2347934][E](ERG_Mode): Watts previously processed. + 141550 [2349349][E](PTable): Averaged Entry: watts=148.500000, cad=71.500000, targetPosition=1389.400024, (2)(5) + 141551 [2349350][E](PTData): Cleaned 250 readings + 141552 [2349360][E](PTData): Existing entry averaged (2)(5)(1381), readings(7) + 141553 [2349361][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141554 [2349372][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141555 [2349386][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 4 ms + 141556 [2349395][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141557 [2349396][E](PTable): New Entry Processed in 48 ms + 141558 [2349397][E](PTable): Power Buffer Reset + 141559 [2349628][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 154, Cad 73, HR 146, Gear 11, Res 47, Current Pos 13841, Target Pos 13841 + 141560 [2350059][E](ERG_Mode): Watts previously processed. + 141561 [2352173][E](ERG_Mode): Proportional: -6.000000 + 141562 [2353587][E](ERG_Mode): Watts previously processed. + 141563 [2355637][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 149, Cad 73, HR 142, Gear 11, Res 47, Current Pos 13811, Target Pos 13811 + 141564 [2355709][E](PTable): Averaged Entry: watts=150.699997, cad=73.000000, targetPosition=1382.400024, (3)(5) + 141565 [2355710][E](PTData): Cleaned 250 readings + 141566 [2355720][E](PTData): Existing entry averaged (3)(5)(1368), readings(2) + 141567 [2355721][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141568 [2355732][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141569 [2355745][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141570 [2355755][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141571 [2355756][E](PTable): New Entry Processed in 48 ms + 141572 [2355756][E](PTable): Power Buffer Reset + 141573 [2355767][E](ERG_Mode): Watts previously processed. + 141574 [2355904][E](FTMS_SERVER): 05 d7 00 -> ERG Mode Target: 215 Current: 149 Incline: 138.110001. Responding: 80 05 01 + 141575 [2355911][E](DirConManager): Sending response message type 0x04 to client 0 + 141576 [2356411][E](ERG_Mode): SetPoint changed:185w Waiting:971ms PowerTable Result: 14760 + 141577 [2358782][E](ERG_Mode): ERG wait expired, pos: 14760, tgt: 0 + 141578 [2358783][E](ERG_Mode): Proportional: 256.000000 + 141579 [2360902][E](ERG_Mode): Watts previously processed. + 141580 [2361651][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 194, Cad 74, HR 143, Gear 11, Res 51, Current Pos 15266, Target Pos 15325 + 141581 [2363022][E](ERG_Mode): Watts previously processed. + 141582 [2363731][E](PTable): Averaged Entry: watts=177.399994, cad=73.500000, targetPosition=1490.800049, (3)(6) + 141583 [2363732][E](PTData): Cleaned 250 readings + 141584 [2363743][E](PTData): Existing entry averaged (3)(6)(1470), readings(3) + 141585 [2363744][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141586 [2363754][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141587 [2363768][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 4 ms + 141588 [2363780][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 6 ms + 141589 [2363782][E](PTable): New Entry Processed in 51 ms + 141590 [2363782][E](PTable): Power Buffer Reset + 141591 [2363793][E](ERG_Mode): Proportional: 8.000000 + 141592 [2364437][E](ERG_Mode): Watts previously processed. + 141593 [2366556][E](ERG_Mode): Watts previously processed. + 141594 [2367668][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 208, Cad 74, HR 140, Gear 11, Res 52, Current Pos 15389, Target Pos 15389 + 141595 [2368679][E](ERG_Mode): Watts previously processed. + 141596 [2369386][E](ERG_Mode): Proportional: 6.000000 + 141597 [2370088][E](PTable): Averaged Entry: watts=210.100006, cad=73.599998, targetPosition=1538.000000, (3)(7) + 141598 [2370089][E](PTData): Cleaned 250 readings + 141599 [2370099][E](PTData): Existing entry averaged (3)(7)(1502), readings(2) + 141600 [2370100][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141601 [2370111][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141602 [2370126][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 5 ms + 141603 [2370135][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141604 [2370137][E](PTable): New Entry Processed in 50 ms + 141605 [2370137][E](PTable): Power Buffer Reset + 141606 [2370798][E](ERG_Mode): Watts previously processed. + 141607 [2372912][E](ERG_Mode): Watts previously processed. + 141608 [2373685][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 187, Cad 70, HR 140, Gear 11, Res 52, Current Pos 15517, Target Pos 15594 + 141609 [2375039][E](ERG_Mode): Proportional: 135.000000 + 141610 [2376442][E](PTable): Averaged Entry: watts=186.199997, cad=69.000000, targetPosition=1559.300049, (2)(6) + 141611 [2376443][E](PTData): Cleaned 250 readings + 141612 [2376453][E](PTData): New entry recorded (2)(6)(1559) + 141613 [2376454][E](PTData): Lower Right Found 2, 7, tp1556 + 141614 [2376467][E](PTData): Fit Valid: 1, N: 49, Quad: 1, Time: 3 ms + 141615 [2376469][E](PTable): New Entry Processed in 28 ms + 141616 [2376469][E](PTable): Power Buffer Reset + 141617 [2376479][E](ERG_Mode): Watts previously processed. + 141618 [2378565][E](ERG_Mode): Watts previously processed. + 141619 [2379694][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 181, Cad 63, HR 139, Gear 11, Res 55, Current Pos 16403, Target Pos 16403 + 141620 [2380683][E](ERG_Mode): Watts previously processed. + 141621 [2381390][E](ERG_Mode): Proportional: 87.000000 + 141622 [2382805][E](PTable): Averaged Entry: watts=184.100006, cad=63.200001, targetPosition=1634.500000, (1)(6) + 141623 [2382806][E](PTData): Cleaned 1 readings + 141624 [2382816][E](PTData): New entry recorded (1)(6)(1634) + 141625 [2382817][E](PTData): Lower Right Found 1, 7, tp1590 + 141626 [2382830][E](PTData): Fit Valid: 1, N: 49, Quad: 1, Time: 3 ms + 141627 [2382832][E](PTable): New Entry Processed in 28 ms + 141628 [2382832][E](PTable): Power Buffer Reset + 141629 [2382842][E](ERG_Mode): Watts previously processed. + 141630 [2383506][E](PTable): Using detected travel limits during homing + 141631 [2385617][E](ERG_Mode): Watts previously processed. + 141632 [2385711][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 191, Cad 62, HR 139, Gear 11, Res 57, Current Pos 16829, Target Pos 16829 + 141633 [2387026][E](ERG_Mode): Proportional: 81.000000 + 141634 [2387735][E](ERG_Mode): Watts previously processed. + 141635 [2389141][E](PTable): Averaged Entry: watts=191.000000, cad=61.000000, targetPosition=1683.199951, (0)(6) + 141636 [2389143][E](PTData): New entry recorded (0)(6)(1683) + 141637 [2389154][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141638 [2389154][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141639 [2389168][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141640 [2389178][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 4 ms + 141641 [2389179][E](PTable): New Entry Processed in 38 ms + 141642 [2389179][E](PTable): Power Buffer Reset + 141643 [2390565][E](ERG_Mode): Watts previously processed. + 141644 [2391726][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 197, Cad 60, HR 139, Gear 11, Res 58, Current Pos 17249, Target Pos 17249 + 141645 [2392675][E](ERG_Mode): Watts previously processed. + 141646 [2393382][E](ERG_Mode): Proportional: 51.000000 + 141647 [2394793][E](ERG_Mode): Watts previously processed. + 141648 [2395500][E](PTable): Averaged Entry: watts=195.100006, cad=58.500000, targetPosition=1727.300049, (0)(7) + 141649 [2395501][E](PTData): Cleaned 250 readings + 141650 [2395512][E](PTData): Existing entry averaged (0)(7)(1706), readings(4) + 141651 [2395512][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141652 [2395523][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141653 [2395537][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 4 ms + 141654 [2395546][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141655 [2395548][E](PTable): New Entry Processed in 49 ms + 141656 [2395548][E](PTable): Power Buffer Reset + 141657 [2396908][E](ERG_Mode): Watts previously processed. + 141658 [2397740][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 214, Cad 60, HR 139, Gear 11, Res 59, Current Pos 17491, Target Pos 17491 + 141659 [2399030][E](ERG_Mode): Proportional: 1.000000 + 141660 [2399737][E](ERG_Mode): Watts previously processed. + 141661 [2401849][E](PTable): Averaged Entry: watts=208.800003, cad=59.700001, targetPosition=1749.199951, (0)(7) + 141662 [2401850][E](PTData): Cleaned 250 readings + 141663 [2401860][E](PTData): Existing entry averaged (0)(7)(1713), readings(5) + 141664 [2401861][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141665 [2401872][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141666 [2401886][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 4 ms + 141667 [2401895][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141668 [2401896][E](PTable): New Entry Processed in 48 ms + 141669 [2401897][E](PTable): Power Buffer Reset + 141670 [2401907][E](ERG_Mode): Watts previously processed. + 141671 [2403749][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 207, Cad 59, HR 140, Gear 11, Res 59, Current Pos 17590, Target Pos 17590 + 141672 [2403960][E](ERG_Mode): Watts previously processed. + 141673 [2404662][E](ERG_Mode): Proportional: 8.000000 + 141674 [2406076][E](ERG_Mode): Watts previously processed. + 141675 [2408196][E](PTable): Averaged Entry: watts=208.500000, cad=58.900002, targetPosition=1758.800049, (0)(7) + 141676 [2408197][E](PTData): Cleaned 250 readings + 141677 [2408207][E](PTData): Existing entry averaged (0)(7)(1719), readings(6) + 141678 [2408208][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141679 [2408219][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141680 [2408232][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141681 [2408242][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141682 [2408243][E](PTable): New Entry Processed in 48 ms + 141683 [2408243][E](PTable): Power Buffer Reset + 141684 [2409599][E](ERG_Mode): Watts previously processed. + 141685 [2409760][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 218, Cad 60, HR 139, Gear 11, Res 60, Current Pos 17633, Target Pos 17633 + 141686 [2410308][E](ERG_Mode): Proportional: 4.000000 + 141687 [2411714][E](ERG_Mode): Watts previously processed. + 141688 [2413831][E](ERG_Mode): Watts previously processed. + 141689 [2414547][E](PTable): Averaged Entry: watts=208.500000, cad=58.900002, targetPosition=1765.800049, (0)(7) + 141690 [2414549][E](PTData): Cleaned 250 readings + 141691 [2414559][E](PTData): Existing entry averaged (0)(7)(1724), readings(7) + 141692 [2414560][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141693 [2414571][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141694 [2414585][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141695 [2414594][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141696 [2414595][E](PTable): New Entry Processed in 48 ms + 141697 [2414595][E](PTable): Power Buffer Reset + 141698 [2415770][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 196, Cad 57, HR 139, Gear 11, Res 60, Current Pos 17831, Target Pos 17831 + 141699 [2415961][E](ERG_Mode): Watts previously processed. + 141700 [2416025][E](FTMS_SERVER): 05 a0 00 -> ERG Mode Target: 160 Current: 196 Incline: 178.309998. Responding: 80 05 01 + 141701 [2416033][E](DirConManager): Sending response message type 0x04 to client 0 + 141702 [2416664][E](ERG_Mode): SetPoint changed:190w Waiting:980ms PowerTable Result: 16850 + 141703 [2419050][E](ERG_Mode): ERG wait expired, pos: 16850, tgt: 0 + 141704 [2419051][E](ERG_Mode): Proportional: -90.000000 + 141705 [2420478][E](ERG_Mode): Watts previously processed. + 141706 [2421188][E](PTable): Using detected travel limits during homing + 141707 [2421786][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 178, Cad 57, HR 140, Gear 11, Res 56, Current Pos 16664, Target Pos 16664 + 141708 [2422601][E](ERG_Mode): Watts previously processed. + 141709 [2424718][E](ERG_Mode): Watts previously processed. + 141710 [2425427][E](ERG_Mode): Proportional: -48.000000 + 141711 [2426832][E](ERG_Mode): Watts previously processed. + 141712 [2427540][E](PTable): Averaged Entry: watts=177.000000, cad=58.099998, targetPosition=1652.800049, (0)(6) + 141713 [2427541][E](PTData): Cleaned 251 readings + 141714 [2427551][E](PTData): Existing entry averaged (0)(6)(1672), readings(2) + 141715 [2427552][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141716 [2427563][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141717 [2427577][E](PTData): Fit Valid: 1, N: 49, Quad: 1, Time: 4 ms + 141718 [2427586][E](PTData): Fit Valid: 1, N: 49, Quad: 1, Time: 3 ms + 141719 [2427587][E](PTable): New Entry Processed in 47 ms + 141720 [2427588][E](PTable): Power Buffer Reset + 141721 [2427799][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 172, Cad 59, HR 140, Gear 11, Res 55, Current Pos 16368, Target Pos 16367 + 141722 [2428948][E](ERG_Mode): Watts previously processed. + 141723 [2431062][E](ERG_Mode): Proportional: -54.000000 + 141724 [2431770][E](ERG_Mode): Watts previously processed. + 141725 [2433816][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 147, Cad 56, HR 140, Gear 11, Res 55, Current Pos 16155, Target Pos 16155 + 141726 [2433888][E](ERG_Mode): Watts previously processed. + 141727 [2436716][E](ERG_Mode): Watts previously processed. + 141728 [2437423][E](ERG_Mode): Proportional: -2.000000 + 141729 [2438835][E](ERG_Mode): Watts previously processed. + 141730 [2439825][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 169, Cad 57, HR 140, Gear 11, Res 55, Current Pos 16156, Target Pos 16156 + 141731 [2441666][E](PTable): Averaged Entry: watts=173.899994, cad=59.500000, targetPosition=1622.300049, (0)(6) + 141732 [2441667][E](PTData): Cleaned 251 readings + 141733 [2441677][E](PTData): Existing entry averaged (0)(6)(1659), readings(3) + 141734 [2441678][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141735 [2441689][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141736 [2441702][E](PTData): Fit Valid: 1, N: 49, Quad: 1, Time: 3 ms + 141737 [2441712][E](PTData): Fit Valid: 1, N: 49, Quad: 1, Time: 3 ms + 141738 [2441713][E](PTable): New Entry Processed in 48 ms + 141739 [2441713][E](PTable): Power Buffer Reset + 141740 [2441724][E](ERG_Mode): Watts previously processed. + 141741 [2443070][E](ERG_Mode): Proportional: 2.000000 + 141742 [2443779][E](ERG_Mode): Watts previously processed. + 141743 [2445841][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 150, Cad 56, HR 141, Gear 11, Res 55, Current Pos 16184, Target Pos 16184 + 141744 [2445892][E](ERG_Mode): Watts previously processed. + 141745 [2448007][E](ERG_Mode): Watts previously processed. + 141746 [2448715][E](ERG_Mode): Proportional: 33.000000 + 141747 [2450842][E](ERG_Mode): Watts previously processed. + 141748 [2451854][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 156, Cad 57, HR 142, Gear 11, Res 55, Current Pos 16250, Target Pos 16250 + 141749 [2453667][E](ERG_Mode): Watts previously processed. + 141750 [2454369][E](ERG_Mode): Proportional: 2.000000 + 141751 [2455772][E](ERG_Mode): Watts previously processed. + 141752 [2457184][E](PTable): Using detected travel limits during homing + 141753 [2457869][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 158, Cad 57, HR 141, Gear 11, Res 55, Current Pos 16251, Target Pos 16251 + 141754 [2457891][E](ERG_Mode): Watts previously processed. + 141755 [2460010][E](ERG_Mode): Watts previously processed. + 141756 [2460712][E](ERG_Mode): Proportional: 39.000000 + 141757 [2462123][E](ERG_Mode): Watts previously processed. + 141758 [2463880][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 143, Cad 55, HR 138, Gear 11, Res 55, Current Pos 16429, Target Pos 16429 + 141759 [2465663][E](ERG_Mode): Watts previously processed. + 141760 [2466372][E](ERG_Mode): Proportional: 45.000000 + 141761 [2467774][E](ERG_Mode): Watts previously processed. + 141762 [2469893][E](ERG_Mode): Watts previously processed. + 141763 [2469893][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 159, Cad 55, HR 139, Gear 11, Res 56, Current Pos 16584, Target Pos 16584 + 141764 [2472001][E](ERG_Mode): Watts previously processed. + 141765 [2472709][E](ERG_Mode): Proportional: -7.000000 + 141766 [2474119][E](ERG_Mode): Watts previously processed. + 141767 [2475918][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 168, Cad 57, HR 137, Gear 11, Res 56, Current Pos 16535, Target Pos 16535 + 141768 [2476229][E](ERG_Mode): Watts previously processed. + 141769 [2477640][E](ERG_Mode): Watts previously processed. + 141770 [2478360][E](ERG_Mode): Proportional: 2.000000 + 141771 [2479766][E](ERG_Mode): Watts previously processed. + 141772 [2481892][E](ERG_Mode): Watts previously processed. + 141773 [2481934][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 158, Cad 55, HR 135, Gear 11, Res 56, Current Pos 16544, Target Pos 16544 + 141774 [2484009][E](ERG_Mode): Watts previously processed. + 141775 [2484720][E](ERG_Mode): Proportional: -1.000000 + 141776 [2486133][E](ERG_Mode): Watts previously processed. + 141777 [2487546][E](ERG_Mode): Watts previously processed. + 141778 [2487943][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 181, Cad 56, HR 133, Gear 11, Res 56, Current Pos 16545, Target Pos 16545 + 141779 [2489659][E](ERG_Mode): Watts previously processed. + 141780 [2490369][E](PTable): Averaged Entry: watts=166.500000, cad=58.799999, targetPosition=1626.400024, (0)(6) + 141781 [2490370][E](PTData): Cleaned 251 readings + 141782 [2490380][E](PTData): Existing entry averaged (0)(6)(1652), readings(4) + 141783 [2490381][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141784 [2490392][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141785 [2490405][E](PTData): Fit Valid: 1, N: 49, Quad: 1, Time: 3 ms + 141786 [2490415][E](PTData): Fit Valid: 1, N: 49, Quad: 1, Time: 3 ms + 141787 [2490416][E](PTable): New Entry Processed in 47 ms + 141788 [2490577][E](PTable): Writing File: /PowerTable.txt + 141789 [2490818][E](PTable): Power table saved successfully with 597 readings + 141790 [2490819][E](PTable): Power Buffer Reset + 141791 [2490819][E](ERG_Mode): Proportional: -45.000000 + 141792 [2491075][E](ERG_Mode): Watts previously processed. + 141793 [2493201][E](PTable): Using detected travel limits during homing + 141794 [2493908][E](ERG_Mode): Watts previously processed. + 141795 [2493960][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 154, Cad 56, HR 133, Gear 11, Res 55, Current Pos 16379, Target Pos 16379 + 141796 [2496029][E](ERG_Mode): Watts previously processed. + 141797 [2496737][E](ERG_Mode): Proportional: 5.000000 + 141798 [2498140][E](ERG_Mode): Watts previously processed. + 141799 [2499972][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 149, Cad 56, HR 132, Gear 11, Res 56, Current Pos 16467, Target Pos 16467 + 141800 [2500963][E](ERG_Mode): Watts previously processed. + 141801 [2502381][E](ERG_Mode): Proportional: -1.000000 + 141802 [2503791][E](ERG_Mode): Watts previously processed. + 141803 [2505907][E](ERG_Mode): Watts previously processed. + 141804 [2506003][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 152, Cad 55, HR 131, Gear 11, Res 56, Current Pos 16556, Target Pos 16556 + 141805 [2508020][E](ERG_Mode): Watts previously processed. + 141806 [2508730][E](ERG_Mode): Proportional: 4.000000 + 141807 [2510140][E](ERG_Mode): Watts previously processed. + 141808 [2512016][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 167, Cad 56, HR 132, Gear 11, Res 56, Current Pos 16568, Target Pos 16568 + 141809 [2513681][E](ERG_Mode): Watts previously processed. + 141810 [2514383][E](ERG_Mode): Proportional: 33.000000 + 141811 [2515793][E](ERG_Mode): Watts previously processed. + 141812 [2517910][E](ERG_Mode): Watts previously processed. + 141813 [2518027][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 160, Cad 56, HR 132, Gear 11, Res 56, Current Pos 16609, Target Pos 16609 + 141814 [2520029][E](ERG_Mode): Watts previously processed. + 141815 [2520738][E](ERG_Mode): Proportional: 3.000000 + 141816 [2522146][E](ERG_Mode): Watts previously processed. + 141817 [2524038][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 156, Cad 55, HR 131, Gear 11, Res 56, Current Pos 16622, Target Pos 16622 + 141818 [2524269][E](ERG_Mode): Watts previously processed. + 141819 [2525673][E](ERG_Mode): Watts previously processed. + 141820 [2526391][E](ERG_Mode): Proportional: -2.000000 + 141821 [2527795][E](ERG_Mode): Watts previously processed. + 141822 [2529212][E](PTable): Using detected travel limits during homing + 141823 [2529920][E](ERG_Mode): Watts previously processed. + 141824 [2530055][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 159, Cad 55, HR 131, Gear 11, Res 56, Current Pos 16611, Target Pos 16611 + 141825 [2532037][E](ERG_Mode): Watts previously processed. + 141826 [2532740][E](ERG_Mode): Proportional: 5.000000 + 141827 [2534152][E](ERG_Mode): Watts previously processed. + 141828 [2536070][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 158, Cad 55, HR 131, Gear 11, Res 56, Current Pos 16623, Target Pos 16623 + 141829 [2536981][E](ERG_Mode): Watts previously processed. + 141830 [2538403][E](ERG_Mode): Proportional: 0.000000 + 141831 [2539809][E](ERG_Mode): Watts previously processed. + 141832 [2541927][E](ERG_Mode): Watts previously processed. + 141833 [2542084][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 164, Cad 56, HR 131, Gear 11, Res 56, Current Pos 16606, Target Pos 16606 + 141834 [2544042][E](ERG_Mode): Watts previously processed. + 141835 [2544749][E](ERG_Mode): Proportional: 2.000000 + 141836 [2546159][E](ERG_Mode): Watts previously processed. + 141837 [2548098][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 160, Cad 55, HR 131, Gear 11, Res 56, Current Pos 16603, Target Pos 16603 + 141838 [2549693][E](ERG_Mode): Watts previously processed. + 141839 [2550401][E](ERG_Mode): Proportional: 3.000000 + 141840 [2551814][E](ERG_Mode): Watts previously processed. + 141841 [2553933][E](ERG_Mode): Watts previously processed. + 141842 [2554110][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 160, Cad 55, HR 131, Gear 11, Res 56, Current Pos 16618, Target Pos 16618 + 141843 [2556053][E](ERG_Mode): Watts previously processed. + 141844 [2556762][E](ERG_Mode): Proportional: 3.000000 + 141845 [2558173][E](ERG_Mode): Watts previously processed. + 141846 [2560118][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 168, Cad 57, HR 131, Gear 11, Res 56, Current Pos 16615, Target Pos 16615 + 141847 [2561699][E](ERG_Mode): Watts previously processed. + 141848 [2562401][E](ERG_Mode): Proportional: -4.000000 + 141849 [2563805][E](ERG_Mode): Watts previously processed. + 141850 [2565230][E](PTable): Using detected travel limits during homing + 141851 [2565935][E](ERG_Mode): Watts previously processed. + 141852 [2566133][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 159, Cad 55, HR 130, Gear 11, Res 56, Current Pos 16590, Target Pos 16590 + 141853 [2568054][E](ERG_Mode): Watts previously processed. + 141854 [2568758][E](ERG_Mode): Proportional: 30.000000 + 141855 [2570167][E](ERG_Mode): Watts previously processed. + 141856 [2572144][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 156, Cad 54, HR 129, Gear 11, Res 56, Current Pos 16647, Target Pos 16647 + 141857 [2573698][E](ERG_Mode): Watts previously processed. + 141858 [2574406][E](ERG_Mode): Proportional: -3.000000 + 141859 [2575819][E](ERG_Mode): Watts previously processed. + 141860 [2577936][E](ERG_Mode): Watts previously processed. + 141861 [2578153][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 158, Cad 55, HR 129, Gear 11, Res 56, Current Pos 16651, Target Pos 16651 + 141862 [2580065][E](ERG_Mode): Watts previously processed. + 141863 [2580775][E](ERG_Mode): Proportional: -2.000000 + 141864 [2582187][E](ERG_Mode): Watts previously processed. + 141865 [2584167][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 157, Cad 55, HR 129, Gear 11, Res 56, Current Pos 16662, Target Pos 16662 + 141866 [2585711][E](ERG_Mode): Watts previously processed. + 141867 [2586420][E](ERG_Mode): Proportional: -3.000000 + 141868 [2587832][E](ERG_Mode): Watts previously processed. + 141869 [2589947][E](ERG_Mode): Watts previously processed. + 141870 [2590182][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 154, Cad 55, HR 129, Gear 11, Res 56, Current Pos 16660, Target Pos 16660 + 141871 [2592055][E](ERG_Mode): Watts previously processed. + 141872 [2592757][E](ERG_Mode): Proportional: 9.000000 + 141873 [2594874][E](ERG_Mode): Watts previously processed. + 141874 [2596198][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 159, Cad 54, HR 129, Gear 11, Res 56, Current Pos 16726, Target Pos 16726 + 141875 [2596242][E](FTMS_SERVER): 11 00 00 76 ff 28 33 -> Sim Mode Incline -1.380000. Responding: 80 11 01 + 141876 [2596249][E](DirConManager): Sending response message type 0x04 to client 0 + 141877 [2597168][E](FTMS_SERVER): 11 00 00 66 ff 28 33 -> Sim Mode Incline -1.540000. Responding: 80 11 01 + 141878 [2597176][E](DirConManager): Sending response message type 0x04 to client 0 + 141879 [2598193][E](FTMS_SERVER): 11 00 00 59 ff 28 33 -> Sim Mode Incline -1.670000. Responding: 80 11 01 + 141880 [2598198][E](DirConManager): Sending response message type 0x04 to client 0 + 141881 [2599145][E](FTMS_SERVER): 11 00 00 4e ff 28 33 -> Sim Mode Incline -1.780000. Responding: 80 11 01 + 141882 [2599151][E](DirConManager): Sending response message type 0x04 to client 0 + 141883 [2600146][E](FTMS_SERVER): 11 00 00 46 ff 28 33 -> Sim Mode Incline -1.860000. Responding: 80 11 01 + 141884 [2600151][E](DirConManager): Sending response message type 0x04 to client 0 + 141885 [2600516][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 141886 [2600516][E](PTable): Power Buffer Reset + 141887 [2601170][E](FTMS_SERVER): 11 00 00 40 ff 28 33 -> Sim Mode Incline -1.920000. Responding: 80 11 01 + 141888 [2601175][E](DirConManager): Sending response message type 0x04 to client 0 + 141889 [2601218][E](PTable): Using detected travel limits during homing + 141890 [2602089][E](FTMS_SERVER): 11 00 00 3b ff 28 33 -> Sim Mode Incline -1.970000. Responding: 80 11 01 + 141891 [2602096][E](DirConManager): Sending response message type 0x04 to client 0 + 141892 [2602215][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 74, Cad 64, HR 129, Gear 11, Res 40, Current Pos 11834, Target Pos 11821 + 141893 [2603113][E](FTMS_SERVER): 11 00 00 37 ff 28 33 -> Sim Mode Incline -2.010000. Responding: 80 11 01 + 141894 [2603120][E](DirConManager): Sending response message type 0x04 to client 0 + 141895 [2604058][E](FTMS_SERVER): 11 00 00 34 ff 28 33 -> Sim Mode Incline -2.040000. Responding: 80 11 01 + 141896 [2604066][E](DirConManager): Sending response message type 0x04 to client 0 + 141897 [2605062][E](FTMS_SERVER): 11 00 00 32 ff 28 33 -> Sim Mode Incline -2.060000. Responding: 80 11 01 + 141898 [2605069][E](DirConManager): Sending response message type 0x04 to client 0 + 141899 [2605964][E](FTMS_SERVER): 11 00 00 31 ff 28 33 -> Sim Mode Incline -2.070000. Responding: 80 11 01 + 141900 [2605969][E](DirConManager): Sending response message type 0x04 to client 0 + 141901 [2606865][E](PTable): Averaged Entry: watts=84.000000, cad=65.099998, targetPosition=1180.500000, (1)(3) + 141902 [2606866][E](PTData): Cleaned 251 readings + 141903 [2606876][E](PTData): New entry recorded (1)(3)(1180) + 141904 [2606877][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141905 [2606888][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141906 [2606892][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 4 ms + 141907 [2606911][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141908 [2606913][E](PTable): New Entry Processed in 47 ms + 141909 [2606913][E](PTable): Power Buffer Reset + 141910 [2606997][E](FTMS_SERVER): 11 00 00 30 ff 28 33 -> Sim Mode Incline -2.080000. Responding: 80 11 01 + 141911 [2607002][E](DirConManager): Sending response message type 0x04 to client 0 + 141912 [2608226][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 75, Cad 70, HR 128, Gear 11, Res 40, Current Pos 11744, Target Pos 11744 + 141913 [2608749][E](FTMS_SERVER): 11 00 00 31 ff 28 33 -> Sim Mode Incline -2.070000. Responding: 80 11 01 + 141914 [2608756][E](DirConManager): Sending response message type 0x04 to client 0 + 141915 [2609657][E](FTMS_SERVER): 11 00 00 33 ff 28 33 -> Sim Mode Incline -2.050000. Responding: 80 11 01 + 141916 [2609664][E](DirConManager): Sending response message type 0x04 to client 0 + 141917 [2610577][E](FTMS_SERVER): 11 00 00 36 ff 28 33 -> Sim Mode Incline -2.020000. Responding: 80 11 01 + 141918 [2610584][E](DirConManager): Sending response message type 0x04 to client 0 + 141919 [2611596][E](FTMS_SERVER): 11 00 00 3b ff 28 33 -> Sim Mode Incline -1.970000. Responding: 80 11 01 + 141920 [2611604][E](DirConManager): Sending response message type 0x04 to client 0 + 141921 [2612635][E](FTMS_SERVER): 11 00 00 44 ff 28 33 -> Sim Mode Incline -1.880000. Responding: 80 11 01 + 141922 [2612642][E](DirConManager): Sending response message type 0x04 to client 0 + 141923 [2613220][E](PTable): Averaged Entry: watts=82.599998, cad=71.500000, targetPosition=1177.800049, (2)(3) + 141924 [2613222][E](PTData): Cleaned 250 readings + 141925 [2613232][E](PTData): New entry recorded (2)(3)(1177) + 141926 [2613233][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141927 [2613244][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141928 [2613247][E](PTData): Fit Valid: 1, N: 51, Quad: 1, Time: 3 ms + 141929 [2613267][E](PTData): Fit Valid: 1, N: 51, Quad: 1, Time: 3 ms + 141930 [2613268][E](PTable): New Entry Processed in 48 ms + 141931 [2613268][E](PTable): Power Buffer Reset + 141932 [2613563][E](FTMS_SERVER): 11 00 00 56 ff 28 33 -> Sim Mode Incline -1.700000. Responding: 80 11 01 + 141933 [2613570][E](DirConManager): Sending response message type 0x04 to client 0 + 141934 [2614249][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 85, Cad 72, HR 128, Gear 11, Res 40, Current Pos 12010, Target Pos 12010 + 141935 [2614473][E](FTMS_SERVER): 11 00 00 74 ff 28 33 -> Sim Mode Incline -1.400000. Responding: 80 11 01 + 141936 [2614480][E](DirConManager): Sending response message type 0x04 to client 0 + 141937 [2615380][E](FTMS_SERVER): 11 00 00 c0 ff 28 33 -> Sim Mode Incline -0.640000. Responding: 80 11 01 + 141938 [2615385][E](DirConManager): Sending response message type 0x04 to client 0 + 141939 [2616403][E](FTMS_SERVER): 11 00 00 b1 00 28 33 -> Sim Mode Incline 1.770000. Responding: 80 11 01 + 141940 [2616408][E](DirConManager): Sending response message type 0x04 to client 0 + 141941 [2617263][E](FTMS_SERVER): 11 00 00 aa 01 28 33 -> Sim Mode Incline 4.260000. Responding: 80 11 01 + 141942 [2617270][E](DirConManager): Sending response message type 0x04 to client 0 + 141943 [2618152][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 141944 [2618152][E](PTable): Power Buffer Reset + 141945 [2618266][E](FTMS_SERVER): 11 00 00 f6 01 28 33 -> Sim Mode Incline 5.020000. Responding: 80 11 01 + 141946 [2618273][E](DirConManager): Sending response message type 0x04 to client 0 + 141947 [2619178][E](FTMS_SERVER): 11 00 00 0b 02 28 33 -> Sim Mode Incline 5.230000. Responding: 80 11 01 + 141948 [2619187][E](DirConManager): Sending response message type 0x04 to client 0 + 141949 [2620102][E](FTMS_SERVER): 11 00 00 13 02 28 33 -> Sim Mode Incline 5.310000. Responding: 80 11 01 + 141950 [2620107][E](DirConManager): Sending response message type 0x04 to client 0 + 141951 [2620260][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 151, Cad 64, HR 126, Gear 11, Res 57, Current Pos 16898, Target Pos 16917 + 141952 [2621135][E](FTMS_SERVER): 11 00 00 15 02 28 33 -> Sim Mode Incline 5.330000. Responding: 80 11 01 + 141953 [2621140][E](DirConManager): Sending response message type 0x04 to client 0 + 141954 [2622156][E](FTMS_SERVER): 11 00 00 13 02 28 33 -> Sim Mode Incline 5.310000. Responding: 80 11 01 + 141955 [2622161][E](DirConManager): Sending response message type 0x04 to client 0 + 141956 [2623183][E](FTMS_SERVER): 11 00 00 10 02 28 33 -> Sim Mode Incline 5.280000. Responding: 80 11 01 + 141957 [2623188][E](DirConManager): Sending response message type 0x04 to client 0 + 141958 [2624103][E](FTMS_SERVER): 11 00 00 09 02 28 33 -> Sim Mode Incline 5.210000. Responding: 80 11 01 + 141959 [2624110][E](DirConManager): Sending response message type 0x04 to client 0 + 141960 [2624508][E](PTable): Averaged Entry: watts=155.800003, cad=63.299999, targetPosition=1684.400024, (1)(5) + 141961 [2624509][E](PTData): Cleaned 249 readings + 141962 [2624519][E](PTData): New entry recorded (1)(5)(1684) + 141963 [2624520][E](PTData): Lower Right Found 1, 7, tp1590 + 141964 [2624533][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141965 [2624535][E](PTable): New Entry Processed in 27 ms + 141966 [2624535][E](PTable): Power Buffer Reset + 141967 [2625129][E](FTMS_SERVER): 11 00 00 01 02 28 33 -> Sim Mode Incline 5.130000. Responding: 80 11 01 + 141968 [2625136][E](DirConManager): Sending response message type 0x04 to client 0 + 141969 [2626071][E](FTMS_SERVER): 11 00 00 f5 01 28 33 -> Sim Mode Incline 5.010000. Responding: 80 11 01 + 141970 [2626079][E](DirConManager): Sending response message type 0x04 to client 0 + 141971 [2626277][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 199, Cad 60, HR 124, Gear 11, Res 57, Current Pos 16733, Target Pos 16707 + 141972 [2627077][E](FTMS_SERVER): 11 00 00 e3 01 28 33 -> Sim Mode Incline 4.830000. Responding: 80 11 01 + 141973 [2627083][E](DirConManager): Sending response message type 0x04 to client 0 + 141974 [2627984][E](FTMS_SERVER): 11 00 00 cd 01 28 33 -> Sim Mode Incline 4.610000. Responding: 80 11 01 + 141975 [2627989][E](DirConManager): Sending response message type 0x04 to client 0 + 141976 [2628908][E](FTMS_SERVER): 11 00 00 af 01 28 33 -> Sim Mode Incline 4.310000. Responding: 80 11 01 + 141977 [2628913][E](DirConManager): Sending response message type 0x04 to client 0 + 141978 [2629940][E](FTMS_SERVER): 11 00 00 86 01 28 33 -> Sim Mode Incline 3.900000. Responding: 80 11 01 + 141979 [2629945][E](DirConManager): Sending response message type 0x04 to client 0 + 141980 [2630863][E](PTable): Averaged Entry: watts=187.199997, cad=60.000000, targetPosition=1650.300049, (0)(6) + 141981 [2630864][E](PTData): Cleaned 1 readings + 141982 [2630874][E](PTData): Existing entry averaged (0)(6)(1651), readings(5) + 141983 [2630875][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 141984 [2630886][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 141985 [2630900][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 4 ms + 141986 [2630909][E](PTData): Fit Valid: 1, N: 50, Quad: 1, Time: 3 ms + 141987 [2630910][E](PTable): New Entry Processed in 47 ms + 141988 [2630911][E](PTable): Power Buffer Reset + 141989 [2630965][E](FTMS_SERVER): 11 00 00 48 01 28 33 -> Sim Mode Incline 3.280000. Responding: 80 11 01 + 141990 [2630972][E](DirConManager): Sending response message type 0x04 to client 0 + 141991 [2631889][E](FTMS_SERVER): 11 00 00 f2 00 28 33 -> Sim Mode Incline 2.420000. Responding: 80 11 01 + 141992 [2631896][E](DirConManager): Sending response message type 0x04 to client 0 + 141993 [2632295][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 161, Cad 58, HR 125, Gear 11, Res 52, Current Pos 15251, Target Pos 14894 + 141994 [2632804][E](FTMS_SERVER): 11 00 00 bc 00 28 33 -> Sim Mode Incline 1.880000. Responding: 80 11 01 + 141995 [2632811][E](DirConManager): Sending response message type 0x04 to client 0 + 141996 [2633708][E](FTMS_SERVER): 11 00 00 96 00 28 33 -> Sim Mode Incline 1.500000. Responding: 80 11 01 + 141997 [2633713][E](DirConManager): Sending response message type 0x04 to client 0 + 141998 [2634732][E](FTMS_SERVER): 11 00 00 74 00 28 33 -> Sim Mode Incline 1.160000. Responding: 80 11 01 + 141999 [2634739][E](DirConManager): Sending response message type 0x04 to client 0 + 142000 [2635757][E](FTMS_SERVER): 11 00 00 51 00 28 33 -> Sim Mode Incline 0.810000. Responding: 80 11 01 + 142001 [2635762][E](DirConManager): Sending response message type 0x04 to client 0 + 142002 [2636797][E](FTMS_SERVER): 11 00 00 33 00 28 33 -> Sim Mode Incline 0.510000. Responding: 80 11 01 + 142003 [2636802][E](DirConManager): Sending response message type 0x04 to client 0 + 142004 [2637205][E](PTable): Averaged Entry: watts=145.600006, cad=58.900002, targetPosition=1453.800049, (0)(5) + 142005 [2637206][E](PTData): Cleaned 250 readings + 142006 [2637216][E](PTData): New entry recorded (0)(5)(1453) + 142007 [2637217][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142008 [2637228][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142009 [2637232][E](PTData): Fit Valid: 1, N: 51, Quad: 1, Time: 4 ms + 142010 [2637251][E](PTData): Fit Valid: 1, N: 51, Quad: 1, Time: 3 ms + 142011 [2637252][E](PTable): New Entry Processed in 47 ms + 142012 [2637253][E](PTable): Power Buffer Reset + 142013 [2637263][E](PTable): Using detected travel limits during homing + 142014 [2637725][E](FTMS_SERVER): 11 00 00 1a 00 28 33 -> Sim Mode Incline 0.260000. Responding: 80 11 01 + 142015 [2637732][E](DirConManager): Sending response message type 0x04 to client 0 + 142016 [2638309][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 127, Cad 61, HR 126, Gear 11, Res 46, Current Pos 13382, Target Pos 13382 + 142017 [2638749][E](FTMS_SERVER): 11 00 00 04 00 28 33 -> Sim Mode Incline 0.040000. Responding: 80 11 01 + 142018 [2638756][E](DirConManager): Sending response message type 0x04 to client 0 + 142019 [2639690][E](FTMS_SERVER): 11 00 00 f9 ff 28 33 -> Sim Mode Incline -0.070000. Responding: 80 11 01 + 142020 [2639697][E](DirConManager): Sending response message type 0x04 to client 0 + 142021 [2640694][E](FTMS_SERVER): 11 00 00 f0 ff 28 33 -> Sim Mode Incline -0.160000. Responding: 80 11 01 + 142022 [2640701][E](DirConManager): Sending response message type 0x04 to client 0 + 142023 [2641598][E](FTMS_SERVER): 11 00 00 e8 ff 28 33 -> Sim Mode Incline -0.240000. Responding: 80 11 01 + 142024 [2641603][E](DirConManager): Sending response message type 0x04 to client 0 + 142025 [2642530][E](FTMS_SERVER): 11 00 00 e2 ff 28 33 -> Sim Mode Incline -0.300000. Responding: 80 11 01 + 142026 [2642535][E](DirConManager): Sending response message type 0x04 to client 0 + 142027 [2643556][E](PTable): Averaged Entry: watts=112.300003, cad=63.099998, targetPosition=1319.800049, (1)(4) + 142028 [2643558][E](PTData): Cleaned 249 readings + 142029 [2643568][E](PTData): New entry recorded (1)(4)(1319) + 142030 [2643569][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142031 [2643580][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142032 [2643583][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 3 ms + 142033 [2643603][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 3 ms + 142034 [2643604][E](PTable): New Entry Processed in 48 ms + 142035 [2643605][E](PTable): Power Buffer Reset + 142036 [2643619][E](FTMS_SERVER): 11 00 00 dc ff 28 33 -> Sim Mode Incline -0.360000. Responding: 80 11 01 + 142037 [2643624][E](DirConManager): Sending response message type 0x04 to client 0 + 142038 [2644324][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 98, Cad 65, HR 127, Gear 11, Res 44, Current Pos 12948, Target Pos 12948 + 142039 [2644602][E](FTMS_SERVER): 11 00 00 d6 ff 28 33 -> Sim Mode Incline -0.420000. Responding: 80 11 01 + 142040 [2644607][E](DirConManager): Sending response message type 0x04 to client 0 + 142041 [2645505][E](FTMS_SERVER): 11 00 00 d0 ff 28 33 -> Sim Mode Incline -0.480000. Responding: 80 11 01 + 142042 [2645512][E](DirConManager): Sending response message type 0x04 to client 0 + 142043 [2646407][E](FTMS_SERVER): 11 00 00 cc ff 28 33 -> Sim Mode Incline -0.520000. Responding: 80 11 01 + 142044 [2646414][E](DirConManager): Sending response message type 0x04 to client 0 + 142045 [2647429][E](FTMS_SERVER): 11 00 00 c8 ff 28 33 -> Sim Mode Incline -0.560000. Responding: 80 11 01 + 142046 [2647436][E](DirConManager): Sending response message type 0x04 to client 0 + 142047 [2648397][E](FTMS_SERVER): 11 00 00 c3 ff 28 33 -> Sim Mode Incline -0.610000. Responding: 80 11 01 + 142048 [2648404][E](DirConManager): Sending response message type 0x04 to client 0 + 142049 [2649402][E](FTMS_SERVER): 11 00 00 bf ff 28 33 -> Sim Mode Incline -0.650000. Responding: 80 11 01 + 142050 [2649408][E](DirConManager): Sending response message type 0x04 to client 0 + 142051 [2649908][E](PTable): Averaged Entry: watts=99.199997, cad=65.300003, targetPosition=1284.400024, (1)(3) + 142052 [2649909][E](PTData): Cleaned 248 readings + 142053 [2649919][E](PTData): Existing entry averaged (1)(3)(1214), readings(2) + 142054 [2649920][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 142055 [2649934][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 3 ms + 142056 [2649944][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 3 ms + 142057 [2649945][E](PTable): New Entry Processed in 37 ms + 142058 [2649945][E](PTable): Power Buffer Reset + 142059 [2650345][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 99, Cad 65, HR 126, Gear 11, Res 43, Current Pos 12745, Target Pos 12745 + 142060 [2650409][E](FTMS_SERVER): 11 00 00 bc ff 28 33 -> Sim Mode Incline -0.680000. Responding: 80 11 01 + 142061 [2650414][E](DirConManager): Sending response message type 0x04 to client 0 + 142062 [2651327][E](FTMS_SERVER): 11 00 00 b9 ff 28 33 -> Sim Mode Incline -0.710000. Responding: 80 11 01 + 142063 [2651334][E](DirConManager): Sending response message type 0x04 to client 0 + 142064 [2652367][E](FTMS_SERVER): 11 00 00 b7 ff 28 33 -> Sim Mode Incline -0.730000. Responding: 80 11 01 + 142065 [2652374][E](DirConManager): Sending response message type 0x04 to client 0 + 142066 [2653306][E](FTMS_SERVER): 11 00 00 b5 ff 28 33 -> Sim Mode Incline -0.750000. Responding: 80 11 01 + 142067 [2653314][E](DirConManager): Sending response message type 0x04 to client 0 + 142068 [2655836][E](FTMS_SERVER): 11 00 00 a8 ff 28 33 -> Sim Mode Incline -0.880000. Responding: 80 11 01 + 142069 [2655844][E](DirConManager): Sending response message type 0x04 to client 0 + 142070 [2656264][E](PTable): Averaged Entry: watts=92.699997, cad=64.199997, targetPosition=1268.000000, (1)(3) + 142071 [2656265][E](PTData): Cleaned 248 readings + 142072 [2656275][E](PTData): Existing entry averaged (1)(3)(1227), readings(3) + 142073 [2656276][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 142074 [2656290][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 3 ms + 142075 [2656300][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 4 ms + 142076 [2656301][E](PTable): New Entry Processed in 38 ms + 142077 [2656301][E](PTable): Power Buffer Reset + 142078 [2656363][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 87, Cad 63, HR 125, Gear 11, Res 42, Current Pos 12584, Target Pos 12584 + 142079 [2656857][E](FTMS_SERVER): 11 00 00 97 ff 28 33 -> Sim Mode Incline -1.050000. Responding: 80 11 01 + 142080 [2656862][E](DirConManager): Sending response message type 0x04 to client 0 + 142081 [2657813][E](FTMS_SERVER): 11 00 00 85 ff 28 33 -> Sim Mode Incline -1.230000. Responding: 80 11 01 + 142082 [2657820][E](DirConManager): Sending response message type 0x04 to client 0 + 142083 [2658819][E](FTMS_SERVER): 11 00 00 76 ff 28 33 -> Sim Mode Incline -1.380000. Responding: 80 11 01 + 142084 [2658824][E](DirConManager): Sending response message type 0x04 to client 0 + 142085 [2659729][E](FTMS_SERVER): 11 00 00 6b ff 28 33 -> Sim Mode Incline -1.490000. Responding: 80 11 01 + 142086 [2659736][E](DirConManager): Sending response message type 0x04 to client 0 + 142087 [2660749][E](FTMS_SERVER): 11 00 00 66 ff 28 33 -> Sim Mode Incline -1.540000. Responding: 80 11 01 + 142088 [2660756][E](DirConManager): Sending response message type 0x04 to client 0 + 142089 [2661708][E](FTMS_SERVER): 11 00 00 65 ff 28 33 -> Sim Mode Incline -1.550000. Responding: 80 11 01 + 142090 [2661715][E](DirConManager): Sending response message type 0x04 to client 0 + 142091 [2662374][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 88, Cad 65, HR 123, Gear 11, Res 41, Current Pos 12115, Target Pos 12115 + 142092 [2662606][E](PTable): Averaged Entry: watts=86.599998, cad=63.299999, targetPosition=1228.800049, (1)(3) + 142093 [2662607][E](PTData): Cleaned 248 readings + 142094 [2662617][E](PTData): Existing entry averaged (1)(3)(1227), readings(4) + 142095 [2662618][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 142096 [2662632][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 3 ms + 142097 [2662642][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 4 ms + 142098 [2662643][E](PTable): New Entry Processed in 38 ms + 142099 [2662643][E](PTable): Power Buffer Reset + 142100 [2662718][E](FTMS_SERVER): 11 00 00 69 ff 28 33 -> Sim Mode Incline -1.510000. Responding: 80 11 01 + 142101 [2662725][E](DirConManager): Sending response message type 0x04 to client 0 + 142102 [2663616][E](FTMS_SERVER): 11 00 00 70 ff 28 33 -> Sim Mode Incline -1.440000. Responding: 80 11 01 + 142103 [2663623][E](DirConManager): Sending response message type 0x04 to client 0 + 142104 [2664541][E](FTMS_SERVER): 11 00 00 7a ff 28 33 -> Sim Mode Incline -1.340000. Responding: 80 11 01 + 142105 [2664546][E](DirConManager): Sending response message type 0x04 to client 0 + 142106 [2665460][E](FTMS_SERVER): 11 00 00 85 ff 28 33 -> Sim Mode Incline -1.230000. Responding: 80 11 01 + 142107 [2665467][E](DirConManager): Sending response message type 0x04 to client 0 + 142108 [2666410][E](FTMS_SERVER): 11 00 00 92 ff 28 33 -> Sim Mode Incline -1.100000. Responding: 80 11 01 + 142109 [2666417][E](DirConManager): Sending response message type 0x04 to client 0 + 142110 [2667410][E](FTMS_SERVER): 11 00 00 9f ff 28 33 -> Sim Mode Incline -0.970000. Responding: 80 11 01 + 142111 [2667417][E](DirConManager): Sending response message type 0x04 to client 0 + 142112 [2668328][E](FTMS_SERVER): 11 00 00 ad ff 28 33 -> Sim Mode Incline -0.830000. Responding: 80 11 01 + 142113 [2668335][E](DirConManager): Sending response message type 0x04 to client 0 + 142114 [2668388][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 78, Cad 63, HR 122, Gear 11, Res 42, Current Pos 12526, Target Pos 12619 + 142115 [2668956][E](PTable): Averaged Entry: watts=76.000000, cad=64.199997, targetPosition=1233.000000, (1)(3) + 142116 [2668957][E](PTData): Cleaned 248 readings + 142117 [2668967][E](PTData): Existing entry averaged (1)(3)(1228), readings(5) + 142118 [2668968][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 142119 [2668982][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 3 ms + 142120 [2668992][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 4 ms + 142121 [2668993][E](PTable): New Entry Processed in 37 ms + 142122 [2668993][E](PTable): Power Buffer Reset + 142123 [2669260][E](FTMS_SERVER): 11 00 00 b7 ff 28 33 -> Sim Mode Incline -0.730000. Responding: 80 11 01 + 142124 [2669265][E](DirConManager): Sending response message type 0x04 to client 0 + 142125 [2670266][E](FTMS_SERVER): 11 00 00 be ff 28 33 -> Sim Mode Incline -0.660000. Responding: 80 11 01 + 142126 [2670272][E](DirConManager): Sending response message type 0x04 to client 0 + 142127 [2671289][E](FTMS_SERVER): 11 00 00 c4 ff 28 33 -> Sim Mode Incline -0.600000. Responding: 80 11 01 + 142128 [2671294][E](DirConManager): Sending response message type 0x04 to client 0 + 142129 [2672331][E](FTMS_SERVER): 11 00 00 c7 ff 28 33 -> Sim Mode Incline -0.570000. Responding: 80 11 01 + 142130 [2672336][E](DirConManager): Sending response message type 0x04 to client 0 + 142131 [2673195][E](PTable): Using detected travel limits during homing + 142132 [2673239][E](FTMS_SERVER): 11 00 00 ca ff 28 33 -> Sim Mode Incline -0.540000. Responding: 80 11 01 + 142133 [2673246][E](DirConManager): Sending response message type 0x04 to client 0 + 142134 [2674280][E](FTMS_SERVER): 11 00 00 cb ff 28 33 -> Sim Mode Incline -0.530000. Responding: 80 11 01 + 142135 [2674287][E](DirConManager): Sending response message type 0x04 to client 0 + 142136 [2674396][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 85, Cad 61, HR 121, Gear 11, Res 43, Current Pos 12829, Target Pos 12829 + 142137 [2675302][E](PTable): Averaged Entry: watts=81.400002, cad=62.099998, targetPosition=1276.300049, (0)(3) + 142138 [2675303][E](PTData): Cleaned 248 readings + 142139 [2675313][E](PTData): New entry recorded (0)(3)(1276) + 142140 [2675314][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 142141 [2675328][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 3 ms + 142142 [2675338][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142143 [2675339][E](PTable): New Entry Processed in 38 ms + 142144 [2675339][E](PTable): Power Buffer Reset + 142145 [2676738][E](FTMS_SERVER): 11 00 00 ca ff 28 33 -> Sim Mode Incline -0.540000. Responding: 80 11 01 + 142146 [2676746][E](DirConManager): Sending response message type 0x04 to client 0 + 142147 [2677641][E](FTMS_SERVER): 11 00 00 c8 ff 28 33 -> Sim Mode Incline -0.560000. Responding: 80 11 01 + 142148 [2677647][E](DirConManager): Sending response message type 0x04 to client 0 + 142149 [2678665][E](FTMS_SERVER): 11 00 00 c5 ff 28 33 -> Sim Mode Incline -0.590000. Responding: 80 11 01 + 142150 [2678671][E](DirConManager): Sending response message type 0x04 to client 0 + 142151 [2679629][E](FTMS_SERVER): 11 00 00 c0 ff 28 33 -> Sim Mode Incline -0.640000. Responding: 80 11 01 + 142152 [2679634][E](DirConManager): Sending response message type 0x04 to client 0 + 142153 [2680406][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 88, Cad 60, HR 119, Gear 11, Res 43, Current Pos 12752, Target Pos 12752 + 142154 [2680621][E](FTMS_SERVER): 11 00 00 bb ff 28 33 -> Sim Mode Incline -0.690000. Responding: 80 11 01 + 142155 [2680628][E](DirConManager): Sending response message type 0x04 to client 0 + 142156 [2681533][E](FTMS_SERVER): 11 00 00 b3 ff 28 33 -> Sim Mode Incline -0.770000. Responding: 80 11 01 + 142157 [2681540][E](DirConManager): Sending response message type 0x04 to client 0 + 142158 [2681665][E](PTable): Averaged Entry: watts=85.000000, cad=60.799999, targetPosition=1277.900024, (0)(3) + 142159 [2681666][E](PTData): Cleaned 247 readings + 142160 [2681676][E](PTData): Existing entry averaged (0)(3)(1276), readings(2) + 142161 [2681677][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 142162 [2681691][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 3 ms + 142163 [2681701][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142164 [2681702][E](PTable): New Entry Processed in 37 ms + 142165 [2681702][E](PTable): Power Buffer Reset + 142166 [2682455][E](FTMS_SERVER): 11 00 00 aa ff 28 33 -> Sim Mode Incline -0.860000. Responding: 80 11 01 + 142167 [2682462][E](DirConManager): Sending response message type 0x04 to client 0 + 142168 [2683476][E](FTMS_SERVER): 11 00 00 9e ff 28 33 -> Sim Mode Incline -0.980000. Responding: 80 11 01 + 142169 [2683483][E](DirConManager): Sending response message type 0x04 to client 0 + 142170 [2684442][E](FTMS_SERVER): 11 00 00 8b ff 28 33 -> Sim Mode Incline -1.170000. Responding: 80 11 01 + 142171 [2684448][E](DirConManager): Sending response message type 0x04 to client 0 + 142172 [2685424][E](FTMS_SERVER): 11 00 00 71 ff 28 33 -> Sim Mode Incline -1.430000. Responding: 80 11 01 + 142173 [2685429][E](DirConManager): Sending response message type 0x04 to client 0 + 142174 [2686362][E](FTMS_SERVER): 11 00 00 48 ff 28 33 -> Sim Mode Incline -1.840000. Responding: 80 11 01 + 142175 [2686369][E](DirConManager): Sending response message type 0x04 to client 0 + 142176 [2686435][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 83, Cad 63, HR 117, Gear 11, Res 41, Current Pos 12191, Target Pos 11912 + 142177 [2687488][E](FTMS_SERVER): 11 00 00 1d ff 28 33 -> Sim Mode Incline -2.270000. Responding: 80 11 01 + 142178 [2687493][E](DirConManager): Sending response message type 0x04 to client 0 + 142179 [2688037][E](PTable): Averaged Entry: watts=82.900002, cad=62.400002, targetPosition=1231.199951, (0)(3) + 142180 [2688038][E](PTData): Cleaned 247 readings + 142181 [2688048][E](PTData): Existing entry averaged (0)(3)(1264), readings(3) + 142182 [2688049][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 142183 [2688063][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 3 ms + 142184 [2688073][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142185 [2688074][E](PTable): New Entry Processed in 37 ms + 142186 [2688075][E](PTable): Power Buffer Reset + 142187 [2688510][E](FTMS_SERVER): 11 00 00 f2 fe 28 33 -> Sim Mode Incline -2.700000. Responding: 80 11 01 + 142188 [2688517][E](DirConManager): Sending response message type 0x04 to client 0 + 142189 [2689437][E](FTMS_SERVER): 11 00 00 cc fe 28 33 -> Sim Mode Incline -3.080000. Responding: 80 11 01 + 142190 [2689444][E](DirConManager): Sending response message type 0x04 to client 0 + 142191 [2690338][E](FTMS_SERVER): 11 00 00 b6 fe 28 33 -> Sim Mode Incline -3.300000. Responding: 80 11 01 + 142192 [2690345][E](DirConManager): Sending response message type 0x04 to client 0 + 142193 [2691261][E](FTMS_SERVER): 11 00 00 b3 fe 28 33 -> Sim Mode Incline -3.330000. Responding: 80 11 01 + 142194 [2691268][E](DirConManager): Sending response message type 0x04 to client 0 + 142195 [2692284][E](FTMS_SERVER): 11 00 00 cf fe 28 33 -> Sim Mode Incline -3.050000. Responding: 80 11 01 + 142196 [2692289][E](DirConManager): Sending response message type 0x04 to client 0 + 142197 [2692444][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 82, Cad 69, HR 117, Gear 11, Res 37, Current Pos 10908, Target Pos 11065 + 142198 [2693307][E](FTMS_SERVER): 11 00 00 19 ff 28 33 -> Sim Mode Incline -2.310000. Responding: 80 11 01 + 142199 [2693312][E](DirConManager): Sending response message type 0x04 to client 0 + 142200 [2694349][E](FTMS_SERVER): 11 00 00 8c ff 28 33 -> Sim Mode Incline -1.160000. Responding: 80 11 01 + 142201 [2694354][E](DirConManager): Sending response message type 0x04 to client 0 + 142202 [2694428][E](PTable): Averaged Entry: watts=78.599998, cad=68.599998, targetPosition=1119.800049, (2)(3) + 142203 [2694430][E](PTData): Cleaned 247 readings + 142204 [2694440][E](PTData): Existing entry averaged (2)(3)(1157), readings(2) + 142205 [2694441][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 142206 [2694455][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142207 [2694465][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142208 [2694466][E](PTable): New Entry Processed in 39 ms + 142209 [2694466][E](PTable): Power Buffer Reset + 142210 [2695262][E](FTMS_SERVER): 11 00 00 3b 00 28 33 -> Sim Mode Incline 0.590000. Responding: 80 11 01 + 142211 [2695269][E](DirConManager): Sending response message type 0x04 to client 0 + 142212 [2696284][E](FTMS_SERVER): 11 00 00 f4 00 28 33 -> Sim Mode Incline 2.440000. Responding: 80 11 01 + 142213 [2696291][E](DirConManager): Sending response message type 0x04 to client 0 + 142214 [2697244][E](FTMS_SERVER): 11 00 00 51 01 28 33 -> Sim Mode Incline 3.370000. Responding: 80 11 01 + 142215 [2697251][E](DirConManager): Sending response message type 0x04 to client 0 + 142216 [2697263][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 142217 [2697263][E](PTable): Power Buffer Reset + 142218 [2698248][E](FTMS_SERVER): 11 00 00 2f 01 28 33 -> Sim Mode Incline 3.030000. Responding: 80 11 01 + 142219 [2698255][E](DirConManager): Sending response message type 0x04 to client 0 + 142220 [2698465][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 91, Cad 63, HR 116, Gear 11, Res 52, Current Pos 15489, Target Pos 15321 + 142221 [2699146][E](FTMS_SERVER): 11 00 00 a1 00 28 33 -> Sim Mode Incline 1.610000. Responding: 80 11 01 + 142222 [2699152][E](DirConManager): Sending response message type 0x04 to client 0 + 142223 [2700069][E](FTMS_SERVER): 11 00 00 eb ff 28 33 -> Sim Mode Incline -0.210000. Responding: 80 11 01 + 142224 [2700074][E](DirConManager): Sending response message type 0x04 to client 0 + 142225 [2701109][E](FTMS_SERVER): 11 00 00 7e ff 28 33 -> Sim Mode Incline -1.300000. Responding: 80 11 01 + 142226 [2701114][E](DirConManager): Sending response message type 0x04 to client 0 + 142227 [2701508][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 142228 [2701508][E](PTable): Power Buffer Reset + 142229 [2702123][E](FTMS_SERVER): 11 00 00 1f ff 28 33 -> Sim Mode Incline -2.250000. Responding: 80 11 01 + 142230 [2702128][E](DirConManager): Sending response message type 0x04 to client 0 + 142231 [2703163][E](FTMS_SERVER): 11 00 00 16 ff 28 33 -> Sim Mode Incline -2.340000. Responding: 80 11 01 + 142232 [2703168][E](DirConManager): Sending response message type 0x04 to client 0 + 142233 [2704081][E](FTMS_SERVER): 11 00 00 0f ff 28 33 -> Sim Mode Incline -2.410000. Responding: 80 11 01 + 142234 [2704088][E](DirConManager): Sending response message type 0x04 to client 0 + 142235 [2704481][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 96, Cad 70, HR 117, Gear 11, Res 39, Current Pos 11513, Target Pos 11513 + 142236 [2705089][E](FTMS_SERVER): 11 00 00 09 ff 28 33 -> Sim Mode Incline -2.470000. Responding: 80 11 01 + 142237 [2705096][E](DirConManager): Sending response message type 0x04 to client 0 + 142238 [2706044][E](FTMS_SERVER): 11 00 00 02 ff 28 33 -> Sim Mode Incline -2.540000. Responding: 80 11 01 + 142239 [2706051][E](DirConManager): Sending response message type 0x04 to client 0 + 142240 [2707046][E](FTMS_SERVER): 11 00 00 fb fe 28 33 -> Sim Mode Incline -2.610000. Responding: 80 11 01 + 142241 [2707053][E](DirConManager): Sending response message type 0x04 to client 0 + 142242 [2707859][E](PTable): Averaged Entry: watts=108.599998, cad=69.199997, targetPosition=1164.300049, (2)(4) + 142243 [2707860][E](PTData): Cleaned 247 readings + 142244 [2707870][E](PTData): New entry recorded (2)(4)(1164) + 142245 [2707870][E](PTData): Greater Down Found 4, 4, tp1207 + 142246 [2707884][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 3 ms + 142247 [2707886][E](PTable): New Entry Processed in 27 ms + 142248 [2707886][E](PTable): Power Buffer Reset + 142249 [2707962][E](FTMS_SERVER): 11 00 00 f2 fe 28 33 -> Sim Mode Incline -2.700000. Responding: 80 11 01 + 142250 [2707968][E](DirConManager): Sending response message type 0x04 to client 0 + 142251 [2708878][E](FTMS_SERVER): 11 00 00 e9 fe 28 33 -> Sim Mode Incline -2.790000. Responding: 80 11 01 + 142252 [2708885][E](DirConManager): Sending response message type 0x04 to client 0 + 142253 [2709270][E](PTable): Using detected travel limits during homing + 142254 [2709893][E](FTMS_SERVER): 11 00 00 de fe 28 33 -> Sim Mode Incline -2.900000. Responding: 80 11 01 + 142255 [2709901][E](DirConManager): Sending response message type 0x04 to client 0 + 142256 [2710489][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 65, Cad 70, HR 119, Gear 11, Res 38, Current Pos 11170, Target Pos 11170 + 142257 [2710856][E](FTMS_SERVER): 11 00 00 cf fe 28 33 -> Sim Mode Incline -3.050000. Responding: 80 11 01 + 142258 [2710863][E](DirConManager): Sending response message type 0x04 to client 0 + 142259 [2711858][E](FTMS_SERVER): 11 00 00 bb fe 28 33 -> Sim Mode Incline -3.250000. Responding: 80 11 01 + 142260 [2711866][E](DirConManager): Sending response message type 0x04 to client 0 + 142261 [2712761][E](FTMS_SERVER): 11 00 00 a4 fe 28 33 -> Sim Mode Incline -3.480000. Responding: 80 11 01 + 142262 [2712768][E](DirConManager): Sending response message type 0x04 to client 0 + 142263 [2713687][E](FTMS_SERVER): 11 00 00 84 fe 28 33 -> Sim Mode Incline -3.800000. Responding: 80 11 01 + 142264 [2713692][E](DirConManager): Sending response message type 0x04 to client 0 + 142265 [2714207][E](PTable): Averaged Entry: watts=65.900002, cad=70.300003, targetPosition=1105.300049, (2)(2) + 142266 [2714208][E](PTData): Cleaned 1 readings + 142267 [2714218][E](PTData): New entry recorded (2)(2)(1105) + 142268 [2714219][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142269 [2714230][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 2 + 142270 [2714230][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 3 + 142271 [2714244][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142272 [2714254][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142273 [2714255][E](PTable): New Entry Processed in 48 ms + 142274 [2714255][E](PTable): Power Buffer Reset + 142275 [2714718][E](FTMS_SERVER): 11 00 00 55 fe 28 33 -> Sim Mode Incline -4.270000. Responding: 80 11 01 + 142276 [2714723][E](DirConManager): Sending response message type 0x04 to client 0 + 142277 [2715737][E](FTMS_SERVER): 11 00 00 22 fe 28 33 -> Sim Mode Incline -4.780000. Responding: 80 11 01 + 142278 [2715742][E](DirConManager): Sending response message type 0x04 to client 0 + 142279 [2716506][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 66, Cad 71, HR 118, Gear 11, Res 33, Current Pos 9854, Target Pos 9854 + 142280 [2716813][E](FTMS_SERVER): 11 00 00 3d fe 28 33 -> Sim Mode Incline -4.510000. Responding: 80 11 01 + 142281 [2716818][E](DirConManager): Sending response message type 0x04 to client 0 + 142282 [2717682][E](FTMS_SERVER): 11 00 00 7c fe 28 33 -> Sim Mode Incline -3.880000. Responding: 80 11 01 + 142283 [2717689][E](DirConManager): Sending response message type 0x04 to client 0 + 142284 [2718709][E](FTMS_SERVER): 11 00 00 a8 fe 28 33 -> Sim Mode Incline -3.440000. Responding: 80 11 01 + 142285 [2718717][E](DirConManager): Sending response message type 0x04 to client 0 + 142286 [2719671][E](FTMS_SERVER): 11 00 00 cb fe 28 33 -> Sim Mode Incline -3.090000. Responding: 80 11 01 + 142287 [2719677][E](DirConManager): Sending response message type 0x04 to client 0 + 142288 [2720561][E](PTable): Averaged Entry: watts=61.799999, cad=72.500000, targetPosition=1040.599976, (2)(2) + 142289 [2720562][E](PTData): Cleaned 247 readings + 142290 [2720572][E](PTData): Existing entry averaged (2)(2)(1074), readings(2) + 142291 [2720573][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142292 [2720584][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142293 [2720598][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142294 [2720607][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 3 ms + 142295 [2720608][E](PTable): New Entry Processed in 47 ms + 142296 [2720609][E](PTable): Power Buffer Reset + 142297 [2720663][E](FTMS_SERVER): 11 00 00 e4 fe 28 33 -> Sim Mode Incline -2.840000. Responding: 80 11 01 + 142298 [2720670][E](DirConManager): Sending response message type 0x04 to client 0 + 142299 [2721574][E](FTMS_SERVER): 11 00 00 f5 fe 28 33 -> Sim Mode Incline -2.670000. Responding: 80 11 01 + 142300 [2721579][E](DirConManager): Sending response message type 0x04 to client 0 + 142301 [2722517][E](FTMS_SERVER): 11 00 00 02 ff 28 33 -> Sim Mode Incline -2.540000. Responding: 80 11 01 + 142302 [2722521][E](DirConManager): Sending response message type 0x04 to client 0 + 142303 [2722523][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 79, Cad 71, HR 115, Gear 11, Res 38, Current Pos 11331, Target Pos 11331 + 142304 [2723527][E](FTMS_SERVER): 11 00 00 0e ff 28 33 -> Sim Mode Incline -2.420000. Responding: 80 11 01 + 142305 [2723534][E](DirConManager): Sending response message type 0x04 to client 0 + 142306 [2724477][E](FTMS_SERVER): 11 00 00 19 ff 28 33 -> Sim Mode Incline -2.310000. Responding: 80 11 01 + 142307 [2724484][E](DirConManager): Sending response message type 0x04 to client 0 + 142308 [2725478][E](FTMS_SERVER): 11 00 00 22 ff 28 33 -> Sim Mode Incline -2.220000. Responding: 80 11 01 + 142309 [2725485][E](DirConManager): Sending response message type 0x04 to client 0 + 142310 [2726380][E](FTMS_SERVER): 11 00 00 2a ff 28 33 -> Sim Mode Incline -2.140000. Responding: 80 11 01 + 142311 [2726388][E](DirConManager): Sending response message type 0x04 to client 0 + 142312 [2726916][E](PTable): Averaged Entry: watts=68.199997, cad=72.800003, targetPosition=1145.300049, (2)(2) + 142313 [2726917][E](PTData): Cleaned 247 readings + 142314 [2726927][E](PTData): Existing entry averaged (2)(2)(1091), readings(3) + 142315 [2726928][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142316 [2726939][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142317 [2726953][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142318 [2726962][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 3 ms + 142319 [2726964][E](PTable): New Entry Processed in 49 ms + 142320 [2726964][E](PTable): Power Buffer Reset + 142321 [2727412][E](FTMS_SERVER): 11 00 00 32 ff 28 33 -> Sim Mode Incline -2.060000. Responding: 80 11 01 + 142322 [2727419][E](DirConManager): Sending response message type 0x04 to client 0 + 142323 [2728370][E](FTMS_SERVER): 11 00 00 3b ff 28 33 -> Sim Mode Incline -1.970000. Responding: 80 11 01 + 142324 [2728376][E](DirConManager): Sending response message type 0x04 to client 0 + 142325 [2728551][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 81, Cad 73, HR 115, Gear 11, Res 40, Current Pos 11803, Target Pos 11821 + 142326 [2729375][E](FTMS_SERVER): 11 00 00 45 ff 28 33 -> Sim Mode Incline -1.870000. Responding: 80 11 01 + 142327 [2729380][E](DirConManager): Sending response message type 0x04 to client 0 + 142328 [2730292][E](FTMS_SERVER): 11 00 00 53 ff 28 33 -> Sim Mode Incline -1.730000. Responding: 80 11 01 + 142329 [2730299][E](DirConManager): Sending response message type 0x04 to client 0 + 142330 [2731313][E](FTMS_SERVER): 11 00 00 60 ff 28 33 -> Sim Mode Incline -1.600000. Responding: 80 11 01 + 142331 [2731320][E](DirConManager): Sending response message type 0x04 to client 0 + 142332 [2732323][E](FTMS_SERVER): 11 00 00 6c ff 28 33 -> Sim Mode Incline -1.480000. Responding: 80 11 01 + 142333 [2732331][E](DirConManager): Sending response message type 0x04 to client 0 + 142334 [2733263][E](PTable): Averaged Entry: watts=82.800003, cad=72.000000, targetPosition=1192.400024, (2)(3) + 142335 [2733264][E](PTData): Cleaned 247 readings + 142336 [2733274][E](PTData): Existing entry averaged (2)(3)(1165), readings(3) + 142337 [2733276][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142338 [2733286][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142339 [2733300][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142340 [2733310][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142341 [2733311][E](PTable): New Entry Processed in 49 ms + 142342 [2733496][E](PTable): Writing File: /PowerTable.txt + 142343 [2734115][E](PTable): Power table saved successfully with 612 readings + 142344 [2734116][E](PTable): Power Buffer Reset + 142345 [2734120][E](FTMS_SERVER): 11 00 00 75 ff 28 33 -> Sim Mode Incline -1.390000. Responding: 80 11 01 + 142346 [2734137][E](DirConManager): Sending response message type 0x04 to client 0 + 142347 [2734564][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 80, Cad 69, HR 116, Gear 11, Res 41, Current Pos 12227, Target Pos 12227 + 142348 [2735084][E](FTMS_SERVER): 11 00 00 84 ff 28 33 -> Sim Mode Incline -1.240000. Responding: 80 11 01 + 142349 [2735092][E](DirConManager): Sending response message type 0x04 to client 0 + 142350 [2736007][E](FTMS_SERVER): 11 00 00 8a ff 28 33 -> Sim Mode Incline -1.180000. Responding: 80 11 01 + 142351 [2736014][E](DirConManager): Sending response message type 0x04 to client 0 + 142352 [2737033][E](FTMS_SERVER): 11 00 00 8f ff 28 33 -> Sim Mode Incline -1.130000. Responding: 80 11 01 + 142353 [2737040][E](DirConManager): Sending response message type 0x04 to client 0 + 142354 [2737975][E](FTMS_SERVER): 11 00 00 95 ff 28 33 -> Sim Mode Incline -1.070000. Responding: 80 11 01 + 142355 [2737982][E](DirConManager): Sending response message type 0x04 to client 0 + 142356 [2738898][E](FTMS_SERVER): 11 00 00 9a ff 28 33 -> Sim Mode Incline -1.020000. Responding: 80 11 01 + 142357 [2738903][E](DirConManager): Sending response message type 0x04 to client 0 + 142358 [2739806][E](PTable): Averaged Entry: watts=97.500000, cad=69.900002, targetPosition=1234.199951, (2)(3) + 142359 [2739807][E](PTData): Cleaned 247 readings + 142360 [2739818][E](PTData): Existing entry averaged (2)(3)(1178), readings(4) + 142361 [2739819][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142362 [2739829][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142363 [2739843][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142364 [2739853][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142365 [2739854][E](PTable): New Entry Processed in 48 ms + 142366 [2739854][E](PTable): Power Buffer Reset + 142367 [2739868][E](FTMS_SERVER): 11 00 00 9f ff 28 33 -> Sim Mode Incline -0.970000. Responding: 80 11 01 + 142368 [2739876][E](DirConManager): Sending response message type 0x04 to client 0 + 142369 [2740574][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 85, Cad 68, HR 115, Gear 11, Res 42, Current Pos 12521, Target Pos 12521 + 142370 [2740937][E](FTMS_SERVER): 11 00 00 a3 ff 28 33 -> Sim Mode Incline -0.930000. Responding: 80 11 01 + 142371 [2740945][E](DirConManager): Sending response message type 0x04 to client 0 + 142372 [2741879][E](FTMS_SERVER): 11 00 00 a8 ff 28 33 -> Sim Mode Incline -0.880000. Responding: 80 11 01 + 142373 [2741886][E](DirConManager): Sending response message type 0x04 to client 0 + 142374 [2742879][E](FTMS_SERVER): 11 00 00 ac ff 28 33 -> Sim Mode Incline -0.840000. Responding: 80 11 01 + 142375 [2742886][E](DirConManager): Sending response message type 0x04 to client 0 + 142376 [2743801][E](FTMS_SERVER): 11 00 00 b0 ff 28 33 -> Sim Mode Incline -0.800000. Responding: 80 11 01 + 142377 [2743808][E](DirConManager): Sending response message type 0x04 to client 0 + 142378 [2744726][E](FTMS_SERVER): 11 00 00 b5 ff 28 33 -> Sim Mode Incline -0.750000. Responding: 80 11 01 + 142379 [2744731][E](DirConManager): Sending response message type 0x04 to client 0 + 142380 [2745463][E](PTable): Using detected travel limits during homing + 142381 [2745740][E](FTMS_SERVER): 11 00 00 b9 ff 28 33 -> Sim Mode Incline -0.710000. Responding: 80 11 01 + 142382 [2745745][E](DirConManager): Sending response message type 0x04 to client 0 + 142383 [2746170][E](PTable): Averaged Entry: watts=88.900002, cad=66.599998, targetPosition=1259.699951, (1)(3) + 142384 [2746171][E](PTData): Cleaned 247 readings + 142385 [2746181][E](PTData): Existing entry averaged (1)(3)(1232), readings(6) + 142386 [2746182][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142387 [2746193][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142388 [2746207][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142389 [2746216][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 3 ms + 142390 [2746217][E](PTable): New Entry Processed in 47 ms + 142391 [2746218][E](PTable): Power Buffer Reset + 142392 [2746582][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 90, Cad 66, HR 115, Gear 11, Res 43, Current Pos 12703, Target Pos 12703 + 142393 [2746686][E](FTMS_SERVER): 11 00 00 be ff 28 33 -> Sim Mode Incline -0.660000. Responding: 80 11 01 + 142394 [2746693][E](DirConManager): Sending response message type 0x04 to client 0 + 142395 [2747801][E](FTMS_SERVER): 11 00 00 c8 ff 28 33 -> Sim Mode Incline -0.560000. Responding: 80 11 01 + 142396 [2747809][E](DirConManager): Sending response message type 0x04 to client 0 + 142397 [2748703][E](FTMS_SERVER): 11 00 00 d5 ff 28 33 -> Sim Mode Incline -0.430000. Responding: 80 11 01 + 142398 [2748711][E](DirConManager): Sending response message type 0x04 to client 0 + 142399 [2749627][E](FTMS_SERVER): 11 00 00 e1 ff 28 33 -> Sim Mode Incline -0.310000. Responding: 80 11 01 + 142400 [2749634][E](DirConManager): Sending response message type 0x04 to client 0 + 142401 [2750591][E](FTMS_SERVER): 11 00 00 ed ff 28 33 -> Sim Mode Incline -0.190000. Responding: 80 11 01 + 142402 [2750598][E](DirConManager): Sending response message type 0x04 to client 0 + 142403 [2751598][E](FTMS_SERVER): 11 00 00 f8 ff 28 33 -> Sim Mode Incline -0.080000. Responding: 80 11 01 + 142404 [2751606][E](DirConManager): Sending response message type 0x04 to client 0 + 142405 [2752535][E](PTable): Averaged Entry: watts=92.099998, cad=65.599998, targetPosition=1290.900024, (1)(3) + 142406 [2752537][E](PTData): Cleaned 247 readings + 142407 [2752548][E](PTData): Existing entry averaged (1)(3)(1239), readings(7) + 142408 [2752549][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142409 [2752559][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142410 [2752573][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142411 [2752583][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142412 [2752584][E](PTable): New Entry Processed in 49 ms + 142413 [2752584][E](PTable): Power Buffer Reset + 142414 [2752596][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 87, Cad 65, HR 116, Gear 11, Res 44, Current Pos 13144, Target Pos 13144 + 142415 [2752621][E](FTMS_SERVER): 11 00 00 02 00 28 33 -> Sim Mode Incline 0.020000. Responding: 80 11 01 + 142416 [2752625][E](DirConManager): Sending response message type 0x04 to client 0 + 142417 [2753525][E](FTMS_SERVER): 11 00 00 14 00 28 33 -> Sim Mode Incline 0.200000. Responding: 80 11 01 + 142418 [2753532][E](DirConManager): Sending response message type 0x04 to client 0 + 142419 [2754565][E](FTMS_SERVER): 11 00 00 20 00 28 33 -> Sim Mode Incline 0.320000. Responding: 80 11 01 + 142420 [2754572][E](DirConManager): Sending response message type 0x04 to client 0 + 142421 [2755505][E](FTMS_SERVER): 11 00 00 2b 00 28 33 -> Sim Mode Incline 0.430000. Responding: 80 11 01 + 142422 [2755511][E](DirConManager): Sending response message type 0x04 to client 0 + 142423 [2756507][E](FTMS_SERVER): 11 00 00 32 00 28 33 -> Sim Mode Incline 0.500000. Responding: 80 11 01 + 142424 [2756514][E](DirConManager): Sending response message type 0x04 to client 0 + 142425 [2757413][E](FTMS_SERVER): 11 00 00 36 00 28 33 -> Sim Mode Incline 0.540000. Responding: 80 11 01 + 142426 [2757420][E](DirConManager): Sending response message type 0x04 to client 0 + 142427 [2758613][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 114, Cad 64, HR 117, Gear 11, Res 46, Current Pos 13578, Target Pos 13578 + 142428 [2758888][E](PTable): Averaged Entry: watts=104.400002, cad=64.699997, targetPosition=1342.699951, (1)(3) + 142429 [2758889][E](PTData): Cleaned 247 readings + 142430 [2758899][E](PTData): Existing entry averaged (1)(3)(1250), readings(8) + 142431 [2758901][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 142432 [2758915][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142433 [2758924][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 3 ms + 142434 [2758925][E](PTable): New Entry Processed in 37 ms + 142435 [2758926][E](PTable): Power Buffer Reset + 142436 [2759160][E](FTMS_SERVER): 11 00 00 35 00 28 33 -> Sim Mode Incline 0.530000. Responding: 80 11 01 + 142437 [2759168][E](DirConManager): Sending response message type 0x04 to client 0 + 142438 [2760099][E](FTMS_SERVER): 11 00 00 31 00 28 33 -> Sim Mode Incline 0.490000. Responding: 80 11 01 + 142439 [2760107][E](DirConManager): Sending response message type 0x04 to client 0 + 142440 [2761003][E](FTMS_SERVER): 11 00 00 2b 00 28 33 -> Sim Mode Incline 0.430000. Responding: 80 11 01 + 142441 [2761008][E](DirConManager): Sending response message type 0x04 to client 0 + 142442 [2761934][E](FTMS_SERVER): 11 00 00 24 00 28 33 -> Sim Mode Incline 0.360000. Responding: 80 11 01 + 142443 [2761939][E](DirConManager): Sending response message type 0x04 to client 0 + 142444 [2762962][E](FTMS_SERVER): 11 00 00 1b 00 28 33 -> Sim Mode Incline 0.270000. Responding: 80 11 01 + 142445 [2762969][E](DirConManager): Sending response message type 0x04 to client 0 + 142446 [2763920][E](FTMS_SERVER): 11 00 00 0f 00 28 33 -> Sim Mode Incline 0.150000. Responding: 80 11 01 + 142447 [2763926][E](DirConManager): Sending response message type 0x04 to client 0 + 142448 [2764626][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 110, Cad 63, HR 115, Gear 11, Res 45, Current Pos 13305, Target Pos 13305 + 142449 [2764922][E](FTMS_SERVER): 11 00 00 01 00 28 33 -> Sim Mode Incline 0.010000. Responding: 80 11 01 + 142450 [2764929][E](DirConManager): Sending response message type 0x04 to client 0 + 142451 [2765230][E](PTable): Averaged Entry: watts=104.400002, cad=63.000000, targetPosition=1344.800049, (1)(3) + 142452 [2765231][E](PTData): Cleaned 247 readings + 142453 [2765241][E](PTData): Existing entry averaged (1)(3)(1259), readings(9) + 142454 [2765242][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 142455 [2765256][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 3 ms + 142456 [2765266][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 3 ms + 142457 [2765267][E](PTable): New Entry Processed in 37 ms + 142458 [2765268][E](PTable): Power Buffer Reset + 142459 [2765912][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 142460 [2765920][E](DirConManager): Sending response message type 0x04 to client 0 + 142461 [2770641][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 101, Cad 66, HR 114, Gear 11, Res 44, Current Pos 13200, Target Pos 13200 + 142462 [2771583][E](PTable): Averaged Entry: watts=109.500000, cad=65.800003, targetPosition=1320.000000, (1)(4) + 142463 [2771585][E](PTData): Cleaned 247 readings + 142464 [2771595][E](PTData): Existing entry averaged (1)(4)(1319), readings(2) + 142465 [2771596][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 142466 [2771610][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 3 ms + 142467 [2771620][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142468 [2771621][E](PTable): New Entry Processed in 38 ms + 142469 [2771621][E](PTable): Power Buffer Reset + 142470 [2776651][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 99, Cad 65, HR 115, Gear 11, Res 44, Current Pos 13200, Target Pos 13200 + 142471 [2777931][E](PTable): Averaged Entry: watts=103.800003, cad=65.400002, targetPosition=1320.000000, (1)(3) + 142472 [2777932][E](PTData): Cleaned 247 readings + 142473 [2777942][E](PTData): Existing entry averaged (1)(3)(1264), readings(10) + 142474 [2777943][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 142475 [2777957][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 3 ms + 142476 [2777967][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 3 ms + 142477 [2777968][E](PTable): New Entry Processed in 38 ms + 142478 [2777968][E](PTable): Power Buffer Reset + 142479 [2781452][E](PTable): Using detected travel limits during homing + 142480 [2782660][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 104, Cad 65, HR 115, Gear 11, Res 44, Current Pos 13200, Target Pos 13200 + 142481 [2784277][E](PTable): Averaged Entry: watts=103.300003, cad=64.800003, targetPosition=1320.000000, (1)(3) + 142482 [2784278][E](PTData): Cleaned 248 readings + 142483 [2784289][E](PTData): Existing entry averaged (1)(3)(1268), readings(11) + 142484 [2784290][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142485 [2784300][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142486 [2784314][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 3 ms + 142487 [2784324][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 4 ms + 142488 [2784325][E](PTable): New Entry Processed in 49 ms + 142489 [2784325][E](PTable): Power Buffer Reset + 142490 [2788668][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 96, Cad 63, HR 116, Gear 11, Res 44, Current Pos 13200, Target Pos 13200 + 142491 [2790202][E](FTMS_SERVER): 11 00 00 c7 ff 28 33 -> Sim Mode Incline -0.570000. Responding: 80 11 01 + 142492 [2790209][E](DirConManager): Sending response message type 0x04 to client 0 + 142493 [2790628][E](PTable): Averaged Entry: watts=99.199997, cad=63.599998, targetPosition=1317.500000, (1)(3) + 142494 [2790629][E](PTData): Cleaned 248 readings + 142495 [2790640][E](PTData): Existing entry averaged (1)(3)(1269), readings(12) + 142496 [2790641][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142497 [2790651][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142498 [2790665][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 4 ms + 142499 [2790675][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 3 ms + 142500 [2790676][E](PTable): New Entry Processed in 48 ms + 142501 [2790676][E](PTable): Power Buffer Reset + 142502 [2791240][E](FTMS_SERVER): 11 00 00 ab ff 28 33 -> Sim Mode Incline -0.850000. Responding: 80 11 01 + 142503 [2791247][E](DirConManager): Sending response message type 0x04 to client 0 + 142504 [2792340][E](FTMS_SERVER): 11 00 00 90 ff 28 33 -> Sim Mode Incline -1.120000. Responding: 80 11 01 + 142505 [2792345][E](DirConManager): Sending response message type 0x04 to client 0 + 142506 [2793376][E](FTMS_SERVER): 11 00 00 76 ff 28 33 -> Sim Mode Incline -1.380000. Responding: 80 11 01 + 142507 [2793380][E](DirConManager): Sending response message type 0x04 to client 0 + 142508 [2793909][E](Main): Shift -1 pos 10 tgt 11034 min 0 max 29356 r_min -2000 r_max 2000 + 142509 [2794396][E](FTMS_SERVER): 11 00 00 5d ff 28 33 -> Sim Mode Incline -1.630000. Responding: 80 11 01 + 142510 [2794403][E](DirConManager): Sending response message type 0x04 to client 0 + 142511 [2794680][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 108, Cad 68, HR 117, Gear 10, Res 40, Current Pos 11337, Target Pos 10859 + 142512 [2794771][E](Main): Shift -1 pos 9 tgt 9659 min 0 max 29356 r_min -2000 r_max 2000 + 142513 [2795342][E](FTMS_SERVER): 11 00 00 47 ff 28 33 -> Sim Mode Incline -1.850000. Responding: 80 11 01 + 142514 [2795349][E](DirConManager): Sending response message type 0x04 to client 0 + 142515 [2795558][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 142516 [2795559][E](PTable): Power Buffer Reset + 142517 [2796350][E](FTMS_SERVER): 11 00 00 34 ff 28 33 -> Sim Mode Incline -2.040000. Responding: 80 11 01 + 142518 [2796357][E](DirConManager): Sending response message type 0x04 to client 0 + 142519 [2797351][E](FTMS_SERVER): 11 00 00 2a ff 28 33 -> Sim Mode Incline -2.140000. Responding: 80 11 01 + 142520 [2797357][E](DirConManager): Sending response message type 0x04 to client 0 + 142521 [2798366][E](FTMS_SERVER): 11 00 00 30 ff 28 33 -> Sim Mode Incline -2.080000. Responding: 80 11 01 + 142522 [2798373][E](DirConManager): Sending response message type 0x04 to client 0 + 142523 [2799391][E](FTMS_SERVER): 11 00 00 59 ff 28 33 -> Sim Mode Incline -1.670000. Responding: 80 11 01 + 142524 [2799398][E](DirConManager): Sending response message type 0x04 to client 0 + 142525 [2800353][E](FTMS_SERVER): 11 00 00 aa ff 28 33 -> Sim Mode Incline -0.860000. Responding: 80 11 01 + 142526 [2800360][E](DirConManager): Sending response message type 0x04 to client 0 + 142527 [2800697][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 44, Cad 79, HR 118, Gear 9, Res 33, Current Pos 9806, Target Pos 10198 + 142528 [2801351][E](FTMS_SERVER): 11 00 00 05 00 28 33 -> Sim Mode Incline 0.050000. Responding: 80 11 01 + 142529 [2801357][E](DirConManager): Sending response message type 0x04 to client 0 + 142530 [2801936][E](PTable): Averaged Entry: watts=59.700001, cad=78.199997, targetPosition=964.000000, (4)(2) + 142531 [2801937][E](PTData): Cleaned 248 readings + 142532 [2801948][E](PTData): Existing entry averaged (4)(2)(958), readings(3) + 142533 [2801949][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142534 [2801959][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142535 [2801963][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 3 ms + 142536 [2801983][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 4 ms + 142537 [2801984][E](PTable): New Entry Processed in 48 ms + 142538 [2801984][E](PTable): Power Buffer Reset + 142539 [2802279][E](FTMS_SERVER): 11 00 00 7f 00 28 33 -> Sim Mode Incline 1.270000. Responding: 80 11 01 + 142540 [2802284][E](DirConManager): Sending response message type 0x04 to client 0 + 142541 [2803301][E](FTMS_SERVER): 11 00 00 d1 00 28 33 -> Sim Mode Incline 2.090000. Responding: 80 11 01 + 142542 [2803306][E](DirConManager): Sending response message type 0x04 to client 0 + 142543 [2804250][E](FTMS_SERVER): 11 00 00 00 01 28 33 -> Sim Mode Incline 2.560000. Responding: 80 11 01 + 142544 [2804257][E](DirConManager): Sending response message type 0x04 to client 0 + 142545 [2805350][E](FTMS_SERVER): 11 00 00 1b 01 28 33 -> Sim Mode Incline 2.830000. Responding: 80 11 01 + 142546 [2805356][E](DirConManager): Sending response message type 0x04 to client 0 + 142547 [2806266][E](FTMS_SERVER): 11 00 00 2c 01 28 33 -> Sim Mode Incline 3.000000. Responding: 80 11 01 + 142548 [2806273][E](DirConManager): Sending response message type 0x04 to client 0 + 142549 [2806710][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 117, Cad 73, HR 117, Gear 9, Res 43, Current Pos 12900, Target Pos 12900 + 142550 [2807178][E](FTMS_SERVER): 11 00 00 36 01 28 33 -> Sim Mode Incline 3.100000. Responding: 80 11 01 + 142551 [2807185][E](DirConManager): Sending response message type 0x04 to client 0 + 142552 [2808209][E](FTMS_SERVER): 11 00 00 3e 01 28 33 -> Sim Mode Incline 3.180000. Responding: 80 11 01 + 142553 [2808217][E](DirConManager): Sending response message type 0x04 to client 0 + 142554 [2808291][E](PTable): Averaged Entry: watts=74.500000, cad=75.000000, targetPosition=1227.599976, (3)(2) + 142555 [2808293][E](PTData): Cleaned 248 readings + 142556 [2808303][E](PTData): Existing entry averaged (3)(2)(1026), readings(3) + 142557 [2808304][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142558 [2808315][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142559 [2808319][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 4 ms + 142560 [2808338][E](PTData): Fit Valid: 1, N: 52, Quad: 1, Time: 3 ms + 142561 [2808340][E](PTable): New Entry Processed in 49 ms + 142562 [2808340][E](PTable): Power Buffer Reset + 142563 [2809161][E](FTMS_SERVER): 11 00 00 44 01 28 33 -> Sim Mode Incline 3.240000. Responding: 80 11 01 + 142564 [2809167][E](DirConManager): Sending response message type 0x04 to client 0 + 142565 [2810162][E](FTMS_SERVER): 11 00 00 49 01 28 33 -> Sim Mode Incline 3.290000. Responding: 80 11 01 + 142566 [2810167][E](DirConManager): Sending response message type 0x04 to client 0 + 142567 [2811088][E](FTMS_SERVER): 11 00 00 4d 01 28 33 -> Sim Mode Incline 3.330000. Responding: 80 11 01 + 142568 [2811095][E](DirConManager): Sending response message type 0x04 to client 0 + 142569 [2812107][E](FTMS_SERVER): 11 00 00 50 01 28 33 -> Sim Mode Incline 3.360000. Responding: 80 11 01 + 142570 [2812114][E](DirConManager): Sending response message type 0x04 to client 0 + 142571 [2812724][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 123, Cad 73, HR 117, Gear 9, Res 44, Current Pos 13152, Target Pos 13152 + 142572 [2813069][E](FTMS_SERVER): 11 00 00 52 01 28 33 -> Sim Mode Incline 3.380000. Responding: 80 11 01 + 142573 [2813076][E](DirConManager): Sending response message type 0x04 to client 0 + 142574 [2814058][E](FTMS_SERVER): 11 00 00 54 01 28 33 -> Sim Mode Incline 3.400000. Responding: 80 11 01 + 142575 [2814065][E](DirConManager): Sending response message type 0x04 to client 0 + 142576 [2814646][E](PTable): Averaged Entry: watts=123.000000, cad=73.199997, targetPosition=1310.800049, (3)(4) + 142577 [2814648][E](PTData): Cleaned 248 readings + 142578 [2814658][E](PTData): New entry recorded (3)(4)(1310) + 142579 [2814659][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142580 [2814670][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142581 [2814674][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 4 ms + 142582 [2814693][E](PTData): Fit Valid: 1, N: 53, Quad: 1, Time: 3 ms + 142583 [2814695][E](PTable): New Entry Processed in 49 ms + 142584 [2814695][E](PTable): Power Buffer Reset + 142585 [2814969][E](FTMS_SERVER): 11 00 00 55 01 28 33 -> Sim Mode Incline 3.410000. Responding: 80 11 01 + 142586 [2814974][E](DirConManager): Sending response message type 0x04 to client 0 + 142587 [2815892][E](FTMS_SERVER): 11 00 00 56 01 28 33 -> Sim Mode Incline 3.420000. Responding: 80 11 01 + 142588 [2815897][E](DirConManager): Sending response message type 0x04 to client 0 + 142589 [2816914][E](FTMS_SERVER): 11 00 00 57 01 28 33 -> Sim Mode Incline 3.430000. Responding: 80 11 01 + 142590 [2816918][E](DirConManager): Sending response message type 0x04 to client 0 + 142591 [2817479][E](PTable): Using detected travel limits during homing + 142592 [2817947][E](FTMS_SERVER): 11 00 00 58 01 28 33 -> Sim Mode Incline 3.440000. Responding: 80 11 01 + 142593 [2817952][E](DirConManager): Sending response message type 0x04 to client 0 + 142594 [2818732][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 134, Cad 75, HR 116, Gear 9, Res 44, Current Pos 13208, Target Pos 13208 + 142595 [2819683][E](FTMS_SERVER): 11 00 00 59 01 28 33 -> Sim Mode Incline 3.450000. Responding: 80 11 01 + 142596 [2819688][E](DirConManager): Sending response message type 0x04 to client 0 + 142597 [2821008][E](PTable): Averaged Entry: watts=138.399994, cad=74.199997, targetPosition=1319.599976, (3)(5) + 142598 [2821009][E](PTData): Cleaned 247 readings + 142599 [2821019][E](PTData): New entry recorded (3)(5)(1319) + 142600 [2821020][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142601 [2821031][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142602 [2821035][E](PTData): Fit Valid: 1, N: 54, Quad: 1, Time: 4 ms + 142603 [2821054][E](PTData): Fit Valid: 1, N: 54, Quad: 1, Time: 3 ms + 142604 [2821056][E](PTable): New Entry Processed in 49 ms + 142605 [2821056][E](PTable): Power Buffer Reset + 142606 [2821423][E](FTMS_SERVER): 11 00 00 58 01 28 33 -> Sim Mode Incline 3.440000. Responding: 80 11 01 + 142607 [2821430][E](DirConManager): Sending response message type 0x04 to client 0 + 142608 [2823888][E](FTMS_SERVER): 11 00 00 57 01 28 33 -> Sim Mode Incline 3.430000. Responding: 80 11 01 + 142609 [2823893][E](DirConManager): Sending response message type 0x04 to client 0 + 142610 [2824745][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 128, Cad 72, HR 115, Gear 9, Res 44, Current Pos 13201, Target Pos 13201 + 142611 [2824790][E](FTMS_SERVER): 11 00 00 56 01 28 33 -> Sim Mode Incline 3.420000. Responding: 80 11 01 + 142612 [2824795][E](DirConManager): Sending response message type 0x04 to client 0 + 142613 [2825719][E](FTMS_SERVER): 11 00 00 55 01 28 33 -> Sim Mode Incline 3.410000. Responding: 80 11 01 + 142614 [2825726][E](DirConManager): Sending response message type 0x04 to client 0 + 142615 [2826672][E](FTMS_SERVER): 11 00 00 54 01 28 33 -> Sim Mode Incline 3.400000. Responding: 80 11 01 + 142616 [2826679][E](DirConManager): Sending response message type 0x04 to client 0 + 142617 [2827349][E](PTable): Averaged Entry: watts=130.199997, cad=72.800003, targetPosition=1319.300049, (2)(4) + 142618 [2827350][E](PTData): Cleaned 246 readings + 142619 [2827361][E](PTData): New entry recorded (2)(4)(1319) + 142620 [2827362][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142621 [2827372][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142622 [2827376][E](PTData): Fit Valid: 1, N: 55, Quad: 1, Time: 4 ms + 142623 [2827396][E](PTData): Fit Valid: 1, N: 55, Quad: 1, Time: 4 ms + 142624 [2827397][E](PTable): New Entry Processed in 49 ms + 142625 [2827397][E](PTable): Power Buffer Reset + 142626 [2827673][E](FTMS_SERVER): 11 00 00 52 01 28 33 -> Sim Mode Incline 3.380000. Responding: 80 11 01 + 142627 [2827680][E](DirConManager): Sending response message type 0x04 to client 0 + 142628 [2828581][E](FTMS_SERVER): 11 00 00 51 01 28 33 -> Sim Mode Incline 3.370000. Responding: 80 11 01 + 142629 [2828588][E](DirConManager): Sending response message type 0x04 to client 0 + 142630 [2829505][E](FTMS_SERVER): 11 00 00 4f 01 28 33 -> Sim Mode Incline 3.350000. Responding: 80 11 01 + 142631 [2829510][E](DirConManager): Sending response message type 0x04 to client 0 + 142632 [2830534][E](FTMS_SERVER): 11 00 00 4c 01 28 33 -> Sim Mode Incline 3.320000. Responding: 80 11 01 + 142633 [2830538][E](DirConManager): Sending response message type 0x04 to client 0 + 142634 [2830763][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 127, Cad 71, HR 117, Gear 9, Res 44, Current Pos 13124, Target Pos 13124 + 142635 [2831556][E](FTMS_SERVER): 11 00 00 49 01 28 33 -> Sim Mode Incline 3.290000. Responding: 80 11 01 + 142636 [2831561][E](DirConManager): Sending response message type 0x04 to client 0 + 142637 [2832587][E](FTMS_SERVER): 11 00 00 44 01 28 33 -> Sim Mode Incline 3.240000. Responding: 80 11 01 + 142638 [2832592][E](DirConManager): Sending response message type 0x04 to client 0 + 142639 [2833497][E](FTMS_SERVER): 11 00 00 3f 01 28 33 -> Sim Mode Incline 3.190000. Responding: 80 11 01 + 142640 [2833504][E](DirConManager): Sending response message type 0x04 to client 0 + 142641 [2833710][E](PTable): Averaged Entry: watts=125.500000, cad=70.900002, targetPosition=1311.900024, (2)(4) + 142642 [2833711][E](PTData): Cleaned 246 readings + 142643 [2833721][E](PTData): New entry recorded (2)(4)(1311) + 142644 [2833722][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142645 [2833733][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142646 [2833737][E](PTData): Fit Valid: 1, N: 55, Quad: 1, Time: 4 ms + 142647 [2833757][E](PTData): Fit Valid: 1, N: 55, Quad: 1, Time: 4 ms + 142648 [2833758][E](PTable): New Entry Processed in 48 ms + 142649 [2833758][E](PTable): Power Buffer Reset + 142650 [2834422][E](FTMS_SERVER): 11 00 00 3a 01 28 33 -> Sim Mode Incline 3.140000. Responding: 80 11 01 + 142651 [2834429][E](DirConManager): Sending response message type 0x04 to client 0 + 142652 [2835393][E](FTMS_SERVER): 11 00 00 33 01 28 33 -> Sim Mode Incline 3.070000. Responding: 80 11 01 + 142653 [2835401][E](DirConManager): Sending response message type 0x04 to client 0 + 142654 [2836374][E](FTMS_SERVER): 11 00 00 2a 01 28 33 -> Sim Mode Incline 2.980000. Responding: 80 11 01 + 142655 [2836381][E](DirConManager): Sending response message type 0x04 to client 0 + 142656 [2836778][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 120, Cad 71, HR 118, Gear 9, Res 43, Current Pos 12886, Target Pos 12886 + 142657 [2837399][E](FTMS_SERVER): 11 00 00 1d 01 28 33 -> Sim Mode Incline 2.850000. Responding: 80 11 01 + 142658 [2837404][E](DirConManager): Sending response message type 0x04 to client 0 + 142659 [2838326][E](FTMS_SERVER): 11 00 00 0e 01 28 33 -> Sim Mode Incline 2.700000. Responding: 80 11 01 + 142660 [2838333][E](DirConManager): Sending response message type 0x04 to client 0 + 142661 [2839347][E](FTMS_SERVER): 11 00 00 f8 00 28 33 -> Sim Mode Incline 2.480000. Responding: 80 11 01 + 142662 [2839354][E](DirConManager): Sending response message type 0x04 to client 0 + 142663 [2840075][E](PTable): Averaged Entry: watts=121.099998, cad=71.099998, targetPosition=1284.800049, (2)(4) + 142664 [2840076][E](PTData): Cleaned 245 readings + 142665 [2840086][E](PTData): Existing entry averaged (2)(4)(1302), readings(2) + 142666 [2840087][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142667 [2840098][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142668 [2840112][E](PTData): Fit Valid: 1, N: 55, Quad: 1, Time: 4 ms + 142669 [2840122][E](PTData): Fit Valid: 1, N: 55, Quad: 1, Time: 4 ms + 142670 [2840123][E](PTable): New Entry Processed in 48 ms + 142671 [2840123][E](PTable): Power Buffer Reset + 142672 [2840279][E](FTMS_SERVER): 11 00 00 de 00 28 33 -> Sim Mode Incline 2.220000. Responding: 80 11 01 + 142673 [2840285][E](DirConManager): Sending response message type 0x04 to client 0 + 142674 [2841177][E](FTMS_SERVER): 11 00 00 c4 00 28 33 -> Sim Mode Incline 1.960000. Responding: 80 11 01 + 142675 [2841184][E](DirConManager): Sending response message type 0x04 to client 0 + 142676 [2842103][E](FTMS_SERVER): 11 00 00 a7 00 28 33 -> Sim Mode Incline 1.670000. Responding: 80 11 01 + 142677 [2842108][E](DirConManager): Sending response message type 0x04 to client 0 + 142678 [2842788][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 107, Cad 72, HR 118, Gear 9, Res 40, Current Pos 11969, Target Pos 11969 + 142679 [2843032][E](FTMS_SERVER): 11 00 00 88 00 28 33 -> Sim Mode Incline 1.360000. Responding: 80 11 01 + 142680 [2843039][E](DirConManager): Sending response message type 0x04 to client 0 + 142681 [2843994][E](FTMS_SERVER): 11 00 00 66 00 28 33 -> Sim Mode Incline 1.020000. Responding: 80 11 01 + 142682 [2844001][E](DirConManager): Sending response message type 0x04 to client 0 + 142683 [2844995][E](FTMS_SERVER): 11 00 00 3e 00 28 33 -> Sim Mode Incline 0.620000. Responding: 80 11 01 + 142684 [2845002][E](DirConManager): Sending response message type 0x04 to client 0 + 142685 [2845994][E](FTMS_SERVER): 11 00 00 17 00 28 33 -> Sim Mode Incline 0.230000. Responding: 80 11 01 + 142686 [2846001][E](DirConManager): Sending response message type 0x04 to client 0 + 142687 [2846433][E](PTable): Averaged Entry: watts=105.500000, cad=72.099998, targetPosition=1181.199951, (2)(4) + 142688 [2846435][E](PTData): Cleaned 245 readings + 142689 [2846445][E](PTData): Existing entry averaged (2)(4)(1271), readings(3) + 142690 [2846446][E](PTData): Greater Down Found 3, 4, tp1288 + 142691 [2846460][E](PTData): Fit Valid: 1, N: 54, Quad: 1, Time: 4 ms + 142692 [2846461][E](PTable): New Entry Processed in 29 ms + 142693 [2846461][E](PTable): Power Buffer Reset + 142694 [2846925][E](FTMS_SERVER): 11 00 00 fb ff 28 33 -> Sim Mode Incline -0.050000. Responding: 80 11 01 + 142695 [2846932][E](DirConManager): Sending response message type 0x04 to client 0 + 142696 [2847930][E](FTMS_SERVER): 11 00 00 ec ff 28 33 -> Sim Mode Incline -0.200000. Responding: 80 11 01 + 142697 [2847937][E](DirConManager): Sending response message type 0x04 to client 0 + 142698 [2848809][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 66, Cad 77, HR 118, Gear 9, Res 36, Current Pos 10660, Target Pos 10660 + 142699 [2848894][E](FTMS_SERVER): 11 00 00 de ff 28 33 -> Sim Mode Incline -0.340000. Responding: 80 11 01 + 142700 [2848900][E](DirConManager): Sending response message type 0x04 to client 0 + 142701 [2849899][E](FTMS_SERVER): 11 00 00 d5 ff 28 33 -> Sim Mode Incline -0.430000. Responding: 80 11 01 + 142702 [2849904][E](DirConManager): Sending response message type 0x04 to client 0 + 142703 [2850808][E](FTMS_SERVER): 11 00 00 ce ff 28 33 -> Sim Mode Incline -0.500000. Responding: 80 11 01 + 142704 [2850815][E](DirConManager): Sending response message type 0x04 to client 0 + 142705 [2851729][E](FTMS_SERVER): 11 00 00 ca ff 28 33 -> Sim Mode Incline -0.540000. Responding: 80 11 01 + 142706 [2851736][E](DirConManager): Sending response message type 0x04 to client 0 + 142707 [2852781][E](PTable): Averaged Entry: watts=74.400002, cad=75.900002, targetPosition=1060.900024, (3)(2) + 142708 [2852782][E](PTData): Cleaned 1 readings + 142709 [2852792][E](PTData): Existing entry averaged (3)(2)(1032), readings(4) + 142710 [2852793][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142711 [2852804][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142712 [2852818][E](PTData): Fit Valid: 1, N: 54, Quad: 1, Time: 4 ms + 142713 [2852827][E](PTData): Fit Valid: 1, N: 54, Quad: 1, Time: 3 ms + 142714 [2852829][E](PTable): New Entry Processed in 49 ms + 142715 [2852829][E](PTable): Power Buffer Reset + 142716 [2853404][E](FTMS_SERVER): 11 00 00 cb ff 28 33 -> Sim Mode Incline -0.530000. Responding: 80 11 01 + 142717 [2853411][E](DirConManager): Sending response message type 0x04 to client 0 + 142718 [2853484][E](PTable): Using detected travel limits during homing + 142719 [2854387][E](FTMS_SERVER): 11 00 00 d0 ff 28 33 -> Sim Mode Incline -0.480000. Responding: 80 11 01 + 142720 [2854395][E](DirConManager): Sending response message type 0x04 to client 0 + 142721 [2854825][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 63, Cad 77, HR 118, Gear 9, Res 35, Current Pos 10464, Target Pos 10464 + 142722 [2855313][E](FTMS_SERVER): 11 00 00 d8 ff 28 33 -> Sim Mode Incline -0.400000. Responding: 80 11 01 + 142723 [2855320][E](DirConManager): Sending response message type 0x04 to client 0 + 142724 [2856236][E](FTMS_SERVER): 11 00 00 e3 ff 28 33 -> Sim Mode Incline -0.290000. Responding: 80 11 01 + 142725 [2856243][E](DirConManager): Sending response message type 0x04 to client 0 + 142726 [2857260][E](FTMS_SERVER): 11 00 00 f1 ff 28 33 -> Sim Mode Incline -0.150000. Responding: 80 11 01 + 142727 [2857265][E](DirConManager): Sending response message type 0x04 to client 0 + 142728 [2858290][E](FTMS_SERVER): 11 00 00 0a 00 28 33 -> Sim Mode Incline 0.100000. Responding: 80 11 01 + 142729 [2858295][E](DirConManager): Sending response message type 0x04 to client 0 + 142730 [2859143][E](PTable): Averaged Entry: watts=72.599998, cad=77.400002, targetPosition=1056.300049, (3)(2) + 142731 [2859144][E](PTData): Cleaned 246 readings + 142732 [2859154][E](PTData): Existing entry averaged (3)(2)(1036), readings(5) + 142733 [2859155][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142734 [2859166][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142735 [2859180][E](PTData): Fit Valid: 1, N: 54, Quad: 1, Time: 4 ms + 142736 [2859189][E](PTData): Fit Valid: 1, N: 54, Quad: 1, Time: 3 ms + 142737 [2859191][E](PTable): New Entry Processed in 48 ms + 142738 [2859191][E](PTable): Power Buffer Reset + 142739 [2859306][E](FTMS_SERVER): 11 00 00 3f 00 28 33 -> Sim Mode Incline 0.630000. Responding: 80 11 01 + 142740 [2859311][E](DirConManager): Sending response message type 0x04 to client 0 + 142741 [2860331][E](FTMS_SERVER): 11 00 00 7c 00 28 33 -> Sim Mode Incline 1.240000. Responding: 80 11 01 + 142742 [2860336][E](DirConManager): Sending response message type 0x04 to client 0 + 142743 [2860848][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 70, Cad 81, HR 118, Gear 9, Res 39, Current Pos 11582, Target Pos 11668 + 142744 [2861353][E](FTMS_SERVER): 11 00 00 c0 00 28 33 -> Sim Mode Incline 1.920000. Responding: 80 11 01 + 142745 [2861360][E](DirConManager): Sending response message type 0x04 to client 0 + 142746 [2862310][E](FTMS_SERVER): 11 00 00 00 01 28 33 -> Sim Mode Incline 2.560000. Responding: 80 11 01 + 142747 [2862318][E](DirConManager): Sending response message type 0x04 to client 0 + 142748 [2863312][E](FTMS_SERVER): 11 00 00 37 01 28 33 -> Sim Mode Incline 3.110000. Responding: 80 11 01 + 142749 [2863319][E](DirConManager): Sending response message type 0x04 to client 0 + 142750 [2864214][E](FTMS_SERVER): 11 00 00 63 01 28 33 -> Sim Mode Incline 3.550000. Responding: 80 11 01 + 142751 [2864221][E](DirConManager): Sending response message type 0x04 to client 0 + 142752 [2865137][E](FTMS_SERVER): 11 00 00 87 01 28 33 -> Sim Mode Incline 3.910000. Responding: 80 11 01 + 142753 [2865143][E](DirConManager): Sending response message type 0x04 to client 0 + 142754 [2865517][E](PTable): Averaged Entry: watts=87.800003, cad=79.300003, targetPosition=1221.400024, (4)(3) + 142755 [2865518][E](PTData): Cleaned 246 readings + 142756 [2865528][E](PTData): New entry recorded (4)(3)(1221) + 142757 [2865528][E](PTData): Lower Up Found 2, 3, tp1178 + 142758 [2865532][E](PTData): Fit Valid: 1, N: 54, Quad: 1, Time: 3 ms + 142759 [2865544][E](PTable): New Entry Processed in 28 ms + 142760 [2865544][E](PTable): Power Buffer Reset + 142761 [2866164][E](FTMS_SERVER): 11 00 00 a6 01 28 33 -> Sim Mode Incline 4.220000. Responding: 80 11 01 + 142762 [2866169][E](DirConManager): Sending response message type 0x04 to client 0 + 142763 [2866858][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 135, Cad 76, HR 117, Gear 9, Res 46, Current Pos 13754, Target Pos 13754 + 142764 [2867197][E](FTMS_SERVER): 11 00 00 c2 01 28 33 -> Sim Mode Incline 4.500000. Responding: 80 11 01 + 142765 [2867202][E](DirConManager): Sending response message type 0x04 to client 0 + 142766 [2868219][E](FTMS_SERVER): 11 00 00 d7 01 28 33 -> Sim Mode Incline 4.710000. Responding: 80 11 01 + 142767 [2868224][E](DirConManager): Sending response message type 0x04 to client 0 + 142768 [2869148][E](FTMS_SERVER): 11 00 00 e7 01 28 33 -> Sim Mode Incline 4.870000. Responding: 80 11 01 + 142769 [2869157][E](DirConManager): Sending response message type 0x04 to client 0 + 142770 [2870172][E](FTMS_SERVER): 11 00 00 f0 01 28 33 -> Sim Mode Incline 4.960000. Responding: 80 11 01 + 142771 [2870179][E](DirConManager): Sending response message type 0x04 to client 0 + 142772 [2871112][E](FTMS_SERVER): 11 00 00 f6 01 28 33 -> Sim Mode Incline 5.020000. Responding: 80 11 01 + 142773 [2871119][E](DirConManager): Sending response message type 0x04 to client 0 + 142774 [2871883][E](PTable): Averaged Entry: watts=145.100006, cad=74.699997, targetPosition=1398.800049, (3)(5) + 142775 [2871885][E](PTData): Existing entry averaged (3)(5)(1345), readings(2) + 142776 [2871896][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142777 [2871897][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142778 [2871911][E](PTData): Fit Valid: 1, N: 54, Quad: 1, Time: 4 ms + 142779 [2871920][E](PTData): Fit Valid: 1, N: 54, Quad: 1, Time: 3 ms + 142780 [2871922][E](PTable): New Entry Processed in 39 ms + 142781 [2871922][E](PTable): Power Buffer Reset + 142782 [2872118][E](FTMS_SERVER): 11 00 00 f7 01 28 33 -> Sim Mode Incline 5.030000. Responding: 80 11 01 + 142783 [2872125][E](DirConManager): Sending response message type 0x04 to client 0 + 142784 [2872873][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 162, Cad 73, HR 115, Gear 9, Res 48, Current Pos 14321, Target Pos 14321 + 142785 [2873020][E](FTMS_SERVER): 11 00 00 f5 01 28 33 -> Sim Mode Incline 5.010000. Responding: 80 11 01 + 142786 [2873025][E](DirConManager): Sending response message type 0x04 to client 0 + 142787 [2873960][E](FTMS_SERVER): 11 00 00 ef 01 28 33 -> Sim Mode Incline 4.950000. Responding: 80 11 01 + 142788 [2873965][E](DirConManager): Sending response message type 0x04 to client 0 + 142789 [2874970][E](FTMS_SERVER): 11 00 00 e7 01 28 33 -> Sim Mode Incline 4.870000. Responding: 80 11 01 + 142790 [2874977][E](DirConManager): Sending response message type 0x04 to client 0 + 142791 [2875910][E](FTMS_SERVER): 11 00 00 db 01 28 33 -> Sim Mode Incline 4.750000. Responding: 80 11 01 + 142792 [2875917][E](DirConManager): Sending response message type 0x04 to client 0 + 142793 [2876814][E](FTMS_SERVER): 11 00 00 cd 01 28 33 -> Sim Mode Incline 4.610000. Responding: 80 11 01 + 142794 [2876821][E](DirConManager): Sending response message type 0x04 to client 0 + 142795 [2877736][E](FTMS_SERVER): 11 00 00 bd 01 28 33 -> Sim Mode Incline 4.450000. Responding: 80 11 01 + 142796 [2877741][E](DirConManager): Sending response message type 0x04 to client 0 + 142797 [2878243][E](PTable): Averaged Entry: watts=166.199997, cad=73.000000, targetPosition=1418.900024, (3)(6) + 142798 [2878244][E](PTData): Cleaned 246 readings + 142799 [2878255][E](PTData): Existing entry averaged (3)(6)(1447), readings(4) + 142800 [2878256][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142801 [2878266][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142802 [2878280][E](PTData): Fit Valid: 1, N: 54, Quad: 1, Time: 4 ms + 142803 [2878290][E](PTData): Fit Valid: 1, N: 54, Quad: 1, Time: 4 ms + 142804 [2878291][E](PTable): New Entry Processed in 48 ms + 142805 [2878291][E](PTable): Power Buffer Reset + 142806 [2878766][E](FTMS_SERVER): 11 00 00 a9 01 28 33 -> Sim Mode Incline 4.250000. Responding: 80 11 01 + 142807 [2878772][E](DirConManager): Sending response message type 0x04 to client 0 + 142808 [2878885][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 162, Cad 74, HR 116, Gear 9, Res 47, Current Pos 13894, Target Pos 13775 + 142809 [2879731][E](FTMS_SERVER): 11 00 00 92 01 28 33 -> Sim Mode Incline 4.020000. Responding: 80 11 01 + 142810 [2879736][E](DirConManager): Sending response message type 0x04 to client 0 + 142811 [2880620][E](FTMS_SERVER): 11 00 00 79 01 28 33 -> Sim Mode Incline 3.770000. Responding: 80 11 01 + 142812 [2880627][E](DirConManager): Sending response message type 0x04 to client 0 + 142813 [2881522][E](FTMS_SERVER): 11 00 00 60 01 28 33 -> Sim Mode Incline 3.520000. Responding: 80 11 01 + 142814 [2881529][E](DirConManager): Sending response message type 0x04 to client 0 + 142815 [2882445][E](FTMS_SERVER): 11 00 00 40 01 28 33 -> Sim Mode Incline 3.200000. Responding: 80 11 01 + 142816 [2882450][E](DirConManager): Sending response message type 0x04 to client 0 + 142817 [2883472][E](FTMS_SERVER): 11 00 00 21 01 28 33 -> Sim Mode Incline 2.890000. Responding: 80 11 01 + 142818 [2883477][E](DirConManager): Sending response message type 0x04 to client 0 + 142819 [2884503][E](FTMS_SERVER): 11 00 00 fc 00 28 33 -> Sim Mode Incline 2.520000. Responding: 80 11 01 + 142820 [2884508][E](DirConManager): Sending response message type 0x04 to client 0 + 142821 [2884601][E](PTable): Averaged Entry: watts=151.199997, cad=73.800003, targetPosition=1338.199951, (3)(5) + 142822 [2884602][E](PTData): Cleaned 246 readings + 142823 [2884612][E](PTData): Existing entry averaged (3)(5)(1343), readings(3) + 142824 [2884613][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142825 [2884624][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142826 [2884638][E](PTData): Fit Valid: 1, N: 54, Quad: 1, Time: 4 ms + 142827 [2884647][E](PTData): Fit Valid: 1, N: 54, Quad: 1, Time: 3 ms + 142828 [2884649][E](PTable): New Entry Processed in 49 ms + 142829 [2884649][E](PTable): Power Buffer Reset + 142830 [2884901][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 123, Cad 71, HR 117, Gear 9, Res 43, Current Pos 12618, Target Pos 12564 + 142831 [2885515][E](FTMS_SERVER): 11 00 00 d4 00 28 33 -> Sim Mode Incline 2.120000. Responding: 80 11 01 + 142832 [2885520][E](DirConManager): Sending response message type 0x04 to client 0 + 142833 [2886436][E](FTMS_SERVER): 11 00 00 aa 00 28 33 -> Sim Mode Incline 1.700000. Responding: 80 11 01 + 142834 [2886444][E](DirConManager): Sending response message type 0x04 to client 0 + 142835 [2887472][E](FTMS_SERVER): 11 00 00 90 00 28 33 -> Sim Mode Incline 1.440000. Responding: 80 11 01 + 142836 [2887479][E](DirConManager): Sending response message type 0x04 to client 0 + 142837 [2888433][E](FTMS_SERVER): 11 00 00 7b 00 28 33 -> Sim Mode Incline 1.230000. Responding: 80 11 01 + 142838 [2888440][E](DirConManager): Sending response message type 0x04 to client 0 + 142839 [2889440][E](FTMS_SERVER): 11 00 00 6a 00 28 33 -> Sim Mode Incline 1.060000. Responding: 80 11 01 + 142840 [2889448][E](DirConManager): Sending response message type 0x04 to client 0 + 142841 [2889522][E](PTable): Using detected travel limits during homing + 142842 [2890441][E](FTMS_SERVER): 11 00 00 5a 00 28 33 -> Sim Mode Incline 0.900000. Responding: 80 11 01 + 142843 [2890448][E](DirConManager): Sending response message type 0x04 to client 0 + 142844 [2890916][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 87, Cad 73, HR 119, Gear 9, Res 39, Current Pos 11430, Target Pos 11430 + 142845 [2890937][E](PTable): Averaged Entry: watts=112.599998, cad=72.400002, targetPosition=1196.599976, (2)(4) + 142846 [2890938][E](PTData): Cleaned 246 readings + 142847 [2890949][E](PTData): Existing entry averaged (2)(4)(1275), readings(3) + 142848 [2890950][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142849 [2890960][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142850 [2890974][E](PTData): Fit Valid: 1, N: 54, Quad: 1, Time: 3 ms + 142851 [2890984][E](PTData): Fit Valid: 1, N: 54, Quad: 1, Time: 3 ms + 142852 [2890985][E](PTable): New Entry Processed in 48 ms + 142853 [2890986][E](PTable): Power Buffer Reset + 142854 [2891350][E](FTMS_SERVER): 11 00 00 4c 00 28 33 -> Sim Mode Incline 0.760000. Responding: 80 11 01 + 142855 [2891355][E](DirConManager): Sending response message type 0x04 to client 0 + 142856 [2892393][E](FTMS_SERVER): 11 00 00 40 00 28 33 -> Sim Mode Incline 0.640000. Responding: 80 11 01 + 142857 [2892398][E](DirConManager): Sending response message type 0x04 to client 0 + 142858 [2893326][E](FTMS_SERVER): 11 00 00 34 00 28 33 -> Sim Mode Incline 0.520000. Responding: 80 11 01 + 142859 [2893332][E](DirConManager): Sending response message type 0x04 to client 0 + 142860 [2894325][E](FTMS_SERVER): 11 00 00 29 00 28 33 -> Sim Mode Incline 0.410000. Responding: 80 11 01 + 142861 [2894332][E](DirConManager): Sending response message type 0x04 to client 0 + 142862 [2895257][E](FTMS_SERVER): 11 00 00 1e 00 28 33 -> Sim Mode Incline 0.300000. Responding: 80 11 01 + 142863 [2895264][E](DirConManager): Sending response message type 0x04 to client 0 + 142864 [2896177][E](FTMS_SERVER): 11 00 00 14 00 28 33 -> Sim Mode Incline 0.200000. Responding: 80 11 01 + 142865 [2896185][E](DirConManager): Sending response message type 0x04 to client 0 + 142866 [2896925][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 74, Cad 74, HR 121, Gear 9, Res 37, Current Pos 10940, Target Pos 10940 + 142867 [2897184][E](FTMS_SERVER): 11 00 00 0a 00 28 33 -> Sim Mode Incline 0.100000. Responding: 80 11 01 + 142868 [2897191][E](DirConManager): Sending response message type 0x04 to client 0 + 142869 [2897295][E](PTable): Averaged Entry: watts=81.199997, cad=73.599998, targetPosition=1114.900024, (3)(3) + 142870 [2897297][E](PTData): Cleaned 246 readings + 142871 [2897307][E](PTData): New entry recorded (3)(3)(1114) + 142872 [2897308][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142873 [2897319][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142874 [2897322][E](PTData): Fit Valid: 1, N: 55, Quad: 1, Time: 3 ms + 142875 [2897342][E](PTData): Fit Valid: 1, N: 55, Quad: 1, Time: 3 ms + 142876 [2897344][E](PTable): New Entry Processed in 49 ms + 142877 [2897344][E](PTable): Power Buffer Reset + 142878 [2898137][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 142879 [2898145][E](DirConManager): Sending response message type 0x04 to client 0 + 142880 [2899083][E](FTMS_SERVER): 11 00 00 fc ff 28 33 -> Sim Mode Incline -0.040000. Responding: 80 11 01 + 142881 [2899088][E](DirConManager): Sending response message type 0x04 to client 0 + 142882 [2899951][E](FTMS_SERVER): 11 00 00 f8 ff 28 33 -> Sim Mode Incline -0.080000. Responding: 80 11 01 + 142883 [2899958][E](DirConManager): Sending response message type 0x04 to client 0 + 142884 [2900993][E](FTMS_SERVER): 11 00 00 f3 ff 28 33 -> Sim Mode Incline -0.130000. Responding: 80 11 01 + 142885 [2901002][E](DirConManager): Sending response message type 0x04 to client 0 + 142886 [2901936][E](FTMS_SERVER): 11 00 00 ee ff 28 33 -> Sim Mode Incline -0.180000. Responding: 80 11 01 + 142887 [2901944][E](DirConManager): Sending response message type 0x04 to client 0 + 142888 [2902941][E](FTMS_SERVER): 11 00 00 e9 ff 28 33 -> Sim Mode Incline -0.230000. Responding: 80 11 01 + 142889 [2902948][E](DirConManager): Sending response message type 0x04 to client 0 + 142890 [2902949][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 28, Cad 69, HR 121, Gear 9, Res 36, Current Pos 10674, Target Pos 10674 + 142891 [2903644][E](PTable): Averaged Entry: watts=52.400002, cad=71.900002, targetPosition=1074.599976, (2)(2) + 142892 [2903645][E](PTData): Cleaned 245 readings + 142893 [2903655][E](PTData): Existing entry averaged (2)(2)(1076), readings(4) + 142894 [2903656][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 142895 [2903667][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 142896 [2903681][E](PTData): Fit Valid: 1, N: 55, Quad: 1, Time: 4 ms + 142897 [2903690][E](PTData): Fit Valid: 1, N: 55, Quad: 1, Time: 3 ms + 142898 [2903692][E](PTable): New Entry Processed in 49 ms + 142899 [2903692][E](PTable): Power Buffer Reset + 142900 [2903876][E](FTMS_SERVER): 11 00 00 e4 ff 28 33 -> Sim Mode Incline -0.280000. Responding: 80 11 01 + 142901 [2903883][E](DirConManager): Sending response message type 0x04 to client 0 + 142902 [2904785][E](FTMS_SERVER): 11 00 00 df ff 28 33 -> Sim Mode Incline -0.330000. Responding: 80 11 01 + 142903 [2904792][E](DirConManager): Sending response message type 0x04 to client 0 + 142904 [2905811][E](FTMS_SERVER): 11 00 00 da ff 28 33 -> Sim Mode Incline -0.380000. Responding: 80 11 01 + 142905 [2905819][E](DirConManager): Sending response message type 0x04 to client 0 + 142906 [2906922][E](FTMS_SERVER): 11 00 00 d4 ff 28 33 -> Sim Mode Incline -0.440000. Responding: 80 11 01 + 142907 [2906927][E](DirConManager): Sending response message type 0x04 to client 0 + 142908 [2907953][E](FTMS_SERVER): 11 00 00 cf ff 28 33 -> Sim Mode Incline -0.490000. Responding: 80 11 01 + 142909 [2907959][E](DirConManager): Sending response message type 0x04 to client 0 + 142910 [2908882][E](FTMS_SERVER): 11 00 00 cb ff 28 33 -> Sim Mode Incline -0.530000. Responding: 80 11 01 + 142911 [2908889][E](DirConManager): Sending response message type 0x04 to client 0 + 142912 [2908975][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 119, Gear 9, Res 35, Current Pos 10444, Target Pos 10429 + 142913 [2909896][E](FTMS_SERVER): 11 00 00 c8 ff 28 33 -> Sim Mode Incline -0.560000. Responding: 80 11 01 + 142914 [2909904][E](DirConManager): Sending response message type 0x04 to client 0 + 142915 [2910842][E](FTMS_SERVER): 11 00 00 c5 ff 28 33 -> Sim Mode Incline -0.590000. Responding: 80 11 01 + 142916 [2910850][E](DirConManager): Sending response message type 0x04 to client 0 + 142917 [2911843][E](FTMS_SERVER): 11 00 00 c3 ff 28 33 -> Sim Mode Incline -0.610000. Responding: 80 11 01 + 142918 [2911851][E](DirConManager): Sending response message type 0x04 to client 0 + 142919 [2912768][E](FTMS_SERVER): 11 00 00 c1 ff 28 33 -> Sim Mode Incline -0.630000. Responding: 80 11 01 + 142920 [2912775][E](DirConManager): Sending response message type 0x04 to client 0 + 142921 [2913677][E](FTMS_SERVER): 11 00 00 c0 ff 28 33 -> Sim Mode Incline -0.640000. Responding: 80 11 01 + 142922 [2913684][E](DirConManager): Sending response message type 0x04 to client 0 + 142923 [2914983][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 119, Gear 9, Res 35, Current Pos 10352, Target Pos 10352 + 142924 [2915352][E](FTMS_SERVER): 11 00 00 bf ff 28 33 -> Sim Mode Incline -0.650000. Responding: 80 11 01 + 142925 [2915357][E](DirConManager): Sending response message type 0x04 to client 0 + 142926 [2920998][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 114, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142927 [2927006][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 108, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142928 [2933014][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 104, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142929 [2939026][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 100, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142930 [2945037][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 98, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142931 [2951051][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 96, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142932 [2957069][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 93, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142933 [2963083][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 93, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142934 [2969091][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 92, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142935 [2975102][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 92, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142936 [2981126][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 93, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142937 [2987140][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 92, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142938 [2993148][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 90, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142939 [2999160][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 89, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142940 [3005172][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 89, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142941 [3011184][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 89, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142942 [3017200][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 87, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142943 [3023216][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 87, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142944 [3029232][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 86, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142945 [3035246][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 85, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142946 [3041262][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 85, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142947 [3047270][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 87, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142948 [3053288][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 86, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142949 [3059300][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 92, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142950 [3065314][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 86, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142951 [3071329][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 86, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142952 [3077340][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 86, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142953 [3083353][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 90, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142954 [3089362][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 86, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142955 [3095373][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 90, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142956 [3101389][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 85, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142957 [3107406][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 84, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142958 [3113424][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 83, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142959 [3119433][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 88, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142960 [3125445][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 81, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142961 [3131457][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 84, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142962 [3137467][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 83, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142963 [3143475][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 83, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142964 [3149489][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 84, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142965 [3155505][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 86, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142966 [3161518][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 80, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142967 [3167534][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 82, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142968 [3173551][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 83, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142969 [3179567][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 84, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142970 [3185576][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 84, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142971 [3191590][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 82, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142972 [3197605][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 85, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142973 [3203620][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 83, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142974 [3207031][E](BLE_Client): Client e8:fe:6e:91:9f:16 Disconnected, reason = 531 + 142975 [3207032][E](BLE_Client): Detected 0x1818 Disconnect + 142976 [3207032][E](BLE_Client): Deregistered PM on Disconnect + 142977 [3207048][E](BLE_Client): Resetting Device: ASSIOMA17287L 16 + 142978 [3207251][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 142979 [3207251][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 142980 [3207915][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 142981 [3207916][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 142982 [3207927][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 142983 [3208033][E](BLE_Client): Found device ASSIOMA59350R d5 with services: 0x180f 6e400001-b5a3-f393-e0a9-e50e24dcca9e + 142984 [3208557][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 142985 [3209632][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 85, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142986 [3211283][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 142987 [3213326][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 142988 [3213326][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 142989 [3213380][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 142990 [3213380][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 142991 [3213397][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 142992 [3214099][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 142993 [3215640][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 88, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 142994 [3217366][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 142995 [3219430][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 142996 [3219430][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 142997 [3219625][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 142998 [3220943][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 142999 [3220943][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 143000 [3220954][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 143001 [3221653][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 91, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143002 [3223470][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143003 [3225516][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143004 [3225517][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143005 [3225562][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 143006 [3225563][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 143007 [3225574][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 143008 [3227662][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 85, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143009 [3228760][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143010 [3229547][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143011 [3231591][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143012 [3231591][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143013 [3232357][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143014 [3233239][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 143015 [3233240][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 143016 [3233250][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 143017 [3233679][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 83, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143018 [3235627][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143019 [3237676][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143020 [3237676][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143021 [3237723][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 143022 [3237724][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 143023 [3237735][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 143024 [3238455][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143025 [3239696][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 87, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143026 [3241710][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143027 [3243767][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143028 [3243767][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143029 [3243977][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143030 [3245015][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 143031 [3245016][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 143032 [3245029][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 143033 [3245707][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 82, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143034 [3247810][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143035 [3249844][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143036 [3249847][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143037 [3250764][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 143038 [3250764][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 143039 [3250775][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 143040 [3251720][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 83, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143041 [3251735][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143042 [3253876][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143043 [3255937][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143044 [3255937][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143045 [3256036][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 143046 [3256036][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 143047 [3256050][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 143048 [3257003][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143049 [3257729][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 85, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143050 [3259969][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143051 [3262022][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143052 [3262022][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143053 [3262533][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143054 [3263284][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 143055 [3263285][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 143056 [3263296][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 143057 [3263740][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 83, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143058 [3266052][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143059 [3268114][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143060 [3268115][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143061 [3268361][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143062 [3269752][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 85, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143063 [3272145][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143064 [3274191][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143065 [3274191][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143066 [3275287][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143067 [3275768][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143068 [3278225][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143069 [3280276][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143070 [3280276][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143071 [3280544][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143072 [3281781][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 88, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143073 [3284310][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143074 [3286356][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143075 [3286356][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143076 [3287793][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 79, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143077 [3289960][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143078 [3290386][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143079 [3292437][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143080 [3292437][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143081 [3293561][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143082 [3293810][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 78, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143083 [3296466][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143084 [3298528][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143085 [3298529][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143086 [3298552][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143087 [3299823][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 80, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143088 [3302560][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143089 [3304606][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143090 [3304606][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143091 [3305135][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143092 [3305835][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 84, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143093 [3308636][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143094 [3310686][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143095 [3310686][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143096 [3310942][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143097 [3311851][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 83, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143098 [3314723][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143099 [3316773][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143100 [3316773][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143101 [3317865][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 80, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143102 [3318138][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143103 [3320815][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143104 [3322858][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143105 [3322859][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143106 [3323126][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143107 [3323881][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 80, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143108 [3326890][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143109 [3328950][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143110 [3328950][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143111 [3329083][E](BLE_Client): Found device c8:27:52:ec:ec:1c with services: 0xfeaf + 143112 [3329897][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 82, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143113 [3330603][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143114 [3332986][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143115 [3335023][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143116 [3335023][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143117 [3335310][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143118 [3335908][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 83, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143119 [3339062][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143120 [3341106][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143121 [3341106][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143122 [3341671][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143123 [3341922][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 85, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143124 [3345141][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143125 [3347191][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143126 [3347191][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143127 [3347930][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 82, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143128 [3349143][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143129 [3351221][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143130 [3353280][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143131 [3353280][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143132 [3353567][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143133 [3353938][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 81, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143134 [3357310][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143135 [3359354][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143136 [3359354][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143137 [3359955][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 79, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143138 [3360203][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143139 [3363387][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143140 [3365437][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143141 [3365437][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143142 [3365965][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 83, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143143 [3366291][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143144 [3369146][E](BLE_Client): Found device c8:27:52:ec:ec:1c with services: 0xfeaf + 143145 [3369484][E](BLE_Client): Found Devices: {"device 0":{"name":"e8:fe:6e:91:9f:16","UUID":"0x1818"},"device 1":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 143146 [3371526][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143147 [3371526][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143148 [3371974][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 81, Gear 9, Res 35, Current Pos 10345, Target Pos 10345 + 143149 [3372099][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143150 [ 54][E](Main): Compiled Jan 4 202619:01:24 + 143151 [ 55][E](Main): Current Board Revision is: Revision Two + 143152 [ 57][E](Main): Mounting Filesystem + 143153 [ 60][E](Config): Reading File: /config.txt + 143154 [ 78][E](Config): Config File Loaded: /config.txt + 143155 [ 79][E](Config): Contents of file: /config.txt + 143156 [ 92][E](Config): Writing File: /config.txt + 143157 [ 143][E](Main): Using homing data from config file. + 143158 [ 214][E](HTTP_Server): Build version check. FS:'25.12.28-Marc_Roy-15-g808c554' CUR:'25.12.28-Marc_Roy-15-g808c554' + 143159 [ 214][E](HTTP_Server): Connecting to: NetwalkerLair + 143160 [ 1387][E](HTTP_Server): Waiting for connection to be established... + 143161 [ 2387][E](HTTP_Server): Waiting for connection to be established... + 143162 [ 2395][E](HTTP_Server): Connected to NetwalkerLair IP address: 192.168.1.180 + 143163 [ 2396][E](HTTP_Server): Open http://SmartPelo.local/ + 143164 [ 2407][E](DirConManager): Adding DirCon MDNS service: _wahoo-fitness-tnp.tcp on port 8081 + 143165 [ 5520][E](BLE_Server): MTU updated: 512 for connection ID: 0 + 143166 [ 5909][E](BLE_Server): MTU updated: 512 for connection ID: 0 + 143167 [ 6426][E](BLE_Server): MTU updated: 515 for connection ID: 0 + 143168 [ 6447][E](BLE_Server): Client ID: 0 Address: 44:84:36:db:d4:2a Subscribed to notifications for 0x2ad2 + 143169 [ 6469][E](Custom_C): Subscribe from 44:84:36:db:d4:2a + 143170 [ 8193][E](BLE_Server): MTU updated: 515 for connection ID: 0 + 143171 [ 10105][E](Main): PM Con 0, CAD con 0, HRM Con 0, W 0, Cad 0, HR 0, Gear 0, Res 0, Current Pos 0, Target Pos 0 + 143172 [ 10210][E](BLE_Client): Devices not connected: HRM PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143173 [ 10221][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143174 [ 10282][E](BLE_Client): Found device Polar OH1 B9B6D624 d6 with services: 0x180d 0xfeee + 143175 [ 10282][E](BLE_Client): Supported Device: Polar OH1 B9B6D624 d6 with service Heart Rate Service + 143176 [ 10293][E](BLE_Client): HRM Name Matched Polar OH1 B9B6D624 d6 + 143177 [ 10294][E](BLE_Client): Setting Device Polar OH1 B9B6D624 d6 + 143178 [ 10306][E](BLE_Client): Set Polar OH1 B9B6D624 d6 with no current connection. + 143179 [ 10309][E](BLE_Client): Polar OH1 B9B6D624 d6 assigned slot: 0 + 143180 [ 10322][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143181 [ 10324][E](BLE_Client): Stopping scan before connecting Polar OH1 B9B6D624 d6 on slot 0 ... + 143182 [ 10436][E](BLE_Client): Connecting Polar OH1 B9B6D624 d6 on slot 0 ... + 143183 [ 10437][E](BLE_Client): Initiating Server Connection + 143184 [ 10437][E](BLE_Client): Connecting slot 0 + 143185 [ 10448][E](BLE_Client): Getting service info for device: Polar OH1 B9B6D624 with 2 services + 143186 [ 10460][E](BLE_Client): Forming a connection to: Polar OH1 B9B6D624 d6 + 143187 [ 11468][E](BLE_Client): Connected, a0:9e:1a:b9:b6:d6 + 143188 [ 11470][E](BLE_Client): Connected to: Polar OH1 B9B6D624 d6 - a0:9e:1a:b9:b6:d6 RSSI -70 + 143189 [ 11471][E](BLE_Client): Setting Device Polar OH1 B9B6D624 d6 + 143190 [ 12610][E](BLE_Client): Registered HRM on Connect + 143191 [ 12611][E](BLE_Client): Device Connected + 143192 [ 12612][E](BLE_Client): We are now connected to Polar OH1 B9B6D624 d6 + 143193 [ 12724][E](BLE_Client): Post connecting: Polar OH1 B9B6D624 d6 , ConnID 1, PrimaryChar 0x2a37 + 143194 [ 13348][E](BLE_Client): Found Heart Rate Service + 143195 [ 13742][E](BLE_Client): Found 0x180d, 0x2a37 + 143196 [ 13967][E](BLE_Client): Subscribed to Heart Rate Service 0x2a37 handle: 40 + 143197 [ 15598][E](BLE_Client): a0:9e:1a:b9:b6:d6 Battery updated 90 + 143198 [ 16116][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 86, Gear 0, Res 0, Current Pos 0, Target Pos 0 + 143199 [ 16226][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143200 [ 16227][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143201 [ 17499][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143202 [ 20245][E](BLE_Client): Found Devices: null + 143203 [ 21086][E](DirConManager): New DirCon client connected from 192.168.1.106, assigned slot 0 + 143204 [ 21168][E](DirConMessage): Discover services response contains 0 UUIDs + 143205 [ 21169][E](DirConManager): Initialized service discovery with 4 services + 143206 [ 21180][E](DirConManager): Received service discovery request from client 0 + 143207 [ 21180][E](DirConManager): Responding with 4 service UUIDs + 143208 [ 21190][E](DirConManager): Sending response message type 0x01 to client 0 + 143209 [ 21191][E](DirConManager): Discover services response contains 4 UUIDs + 143210 [ 21201][E](DirConManager): Service 0: 0x1818 + 143211 [ 21201][E](DirConManager): Service 1: 0x1816 + 143212 [ 21212][E](DirConManager): Service 2: 0x180d + 143213 [ 21212][E](DirConManager): Service 3: 0x1826 + 143214 [ 21212][E](DirConMessage): Adding 4 service UUIDs to discovery response + 143215 [ 21223][E](DirConMessage): Adding service 0 UUID: 0x1818 + 143216 [ 21233][E](DirConMessage): Adding service 1 UUID: 0x1816 + 143217 [ 21233][E](DirConMessage): Adding service 2 UUID: 0x180d + 143218 [ 22128][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 92, Gear 0, Res 0, Current Pos 0, Target Pos 0 + 143219 [ 22307][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143220 [ 22308][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143221 [ 22767][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143222 [ 26326][E](BLE_Client): Found Devices: null + 143223 [ 28145][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 86, Gear 0, Res 0, Current Pos 0, Target Pos 0 + 143224 [ 28386][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143225 [ 28387][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143226 [ 30240][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143227 [ 32405][E](BLE_Client): Found Devices: null + 143228 [ 34158][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 88, Gear 0, Res 0, Current Pos 0, Target Pos 0 + 143229 [ 34465][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 143230 [ 34465][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 143231 [ 34650][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 143232 [ 34650][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 143233 [ 34661][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 143234 [ 34950][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 143235 [ 35400][E](BLE_Client): Found device ASSIOMA17287L 16 with services: 0x1818 0x180f 6e400001-b5a3-f393-e0a9-e50e24dcca9e + 143236 [ 35403][E](BLE_Client): Supported Device: ASSIOMA17287L 16 with service Cycling Power Service + 143237 [ 35413][E](BLE_Client): PM Name Matched ASSIOMA17287L 16 + 143238 [ 35424][E](BLE_Client): Slot 0 contains Polar OH1 B9B6D624 d6 + 143239 [ 35426][E](BLE_Client): Setting Device ASSIOMA17287L 16 + 143240 [ 35426][E](BLE_Client): Set ASSIOMA17287L 16 with no current connection. + 143241 [ 35437][E](BLE_Client): ASSIOMA17287L 16 assigned slot: 1 + 143242 [ 35488][E](BLE_Client): Stopping scan before connecting ASSIOMA17287L 16 on slot 1 ... + 143243 [ 35595][E](BLE_Client): Connecting ASSIOMA17287L 16 on slot 1 ... + 143244 [ 35596][E](BLE_Client): Initiating Server Connection + 143245 [ 35596][E](BLE_Client): doConnect on slot 0 not set + 143246 [ 35607][E](BLE_Client): Connecting slot 1 + 143247 [ 35607][E](BLE_Client): Getting service info for device: ASSIOMA17287L with 3 services + 143248 [ 36934][E](BLE_Client): Connected, e8:fe:6e:91:9f:16 + 143249 [ 36936][E](BLE_Client): Connected to: ASSIOMA17287L 16 - e8:fe:6e:91:9f:16 RSSI -67 + 143250 [ 36937][E](BLE_Client): Setting Device ASSIOMA17287L 16 + 143251 [ 37498][E](BLE_Client): Registered PM on Connect + 143252 [ 37499][E](BLE_Client): Device Connected + 143253 [ 37500][E](BLE_Client): We are now connected to ASSIOMA17287L 16 + 143254 [ 37612][E](BLE_Client): Post connecting: ASSIOMA17287L 16 , ConnID 2, PrimaryChar 0x2a63 + 143255 [ 37615][E](BLE_Client): Found Cycling Power Service + 143256 [ 38116][E](BLE_Client): Found 0x1818, 0x2a63 + 143257 [ 38340][E](BLE_Client): Subscribed to Cycling Power Service 0x2a63 handle: 22 + 143258 [ 38341][E](BLE_Client): Found 0x1818, 0x2a65 + 143259 [ 38341][E](BLE_Client): Found 0x1818, 0x2a66 + 143260 [ 38678][E](BLE_Client): Subscribed to Cycling Power Service 0x2a66 handle: 27 + 143261 [ 38678][E](BLE_Client): Found 0x1818, 0x2a5d + 143262 [ 40167][E](Main): PM Con 1, CAD con 0, HRM Con 1, W 56, Cad 0, HR 96, Gear 0, Res 0, Current Pos 0, Target Pos 0 + 143263 [ 40196][E](BLE_Client): Found Flywheel UART Service + 143264 [ 40761][E](BLE_Client): Found 6e400001-b5a3-f393-e0a9-e50e24dcca9e, 6e400003-b5a3-f393-e0a9-e50e24dcca9e + 143265 [ 41040][E](BLE_Client): Subscribed to Flywheel UART Service 6e400003-b5a3-f393-e0a9-e50e24dcca9e handle: 13 + 143266 [ 41041][E](BLE_Client): Found 6e400001-b5a3-f393-e0a9-e50e24dcca9e, 6e400004-b5a3-f393-e0a9-e50e24dcca9e + 143267 [ 41156][E](FTMS_SERVER): 11 00 00 be ff 28 33 -> Sim Mode Incline -0.660000. Responding: 80 11 01 + 143268 [ 41162][E](DirConManager): Sending response message type 0x04 to client 0 + 143269 [ 41323][E](BLE_Client): Subscribed to Flywheel UART Service 6e400004-b5a3-f393-e0a9-e50e24dcca9e handle: 16 + 143270 [ 41323][E](BLE_Client): Found 6e400001-b5a3-f393-e0a9-e50e24dcca9e, 6e400002-b5a3-f393-e0a9-e50e24dcca9e + 143271 [ 41887][E](BLE_Client): e8:fe:6e:91:9f:16 Battery updated 100 + 143272 [ 42071][E](FTMS_SERVER): 11 00 00 bb ff 28 33 -> Sim Mode Incline -0.690000. Responding: 80 11 01 + 143273 [ 42078][E](DirConManager): Sending response message type 0x04 to client 0 + 143274 [ 42980][E](FTMS_SERVER): 11 00 00 b7 ff 28 33 -> Sim Mode Incline -0.730000. Responding: 80 11 01 + 143275 [ 42988][E](DirConManager): Sending response message type 0x04 to client 0 + 143276 [ 43987][E](BLE_Client): Spin Down initiated via BLE Client task. + 143277 [ 43988][E](Main): Starting homing procedure... + 143278 [ 44006][E](FTMS_SERVER): 11 00 00 b2 ff 28 33 -> Sim Mode Incline -0.780000. Responding: 80 11 01 + 143279 [ 44013][E](DirConManager): Sending response message type 0x04 to client 0 + 143280 [ 44960][E](FTMS_SERVER): 11 00 00 ac ff 28 33 -> Sim Mode Incline -0.840000. Responding: 80 11 01 + 143281 [ 44968][E](DirConManager): Sending response message type 0x04 to client 0 + 143282 [ 45246][E](Main): Stepper power is now 720. read:703 + 143283 [ 45773][E](Main): Homing backward (min). Stable Threshold: 324, Sensitivity: 50 + 143284 [ 45783][E](Main): Homing... Current SG: 366, Baseline: 324, Target: < 274 + 143285 [ 45957][E](FTMS_SERVER): 11 00 00 a5 ff 28 33 -> Sim Mode Incline -0.910000. Responding: 80 11 01 + 143286 [ 45962][E](DirConManager): Sending response message type 0x04 to client 0 + 143287 [ 46177][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 52, Cad 70, HR 99, Gear 0, Res 0, Current Pos 0, Target Pos 0 + 143288 [ 46793][E](Main): Homing... Current SG: 344, Baseline: 324, Target: < 274 + 143289 [ 46873][E](FTMS_SERVER): 11 00 00 9d ff 28 33 -> Sim Mode Incline -0.990000. Responding: 80 11 01 + 143290 [ 46879][E](DirConManager): Sending response message type 0x04 to client 0 + 143291 [ 47802][E](Main): Homing... Current SG: 358, Baseline: 324, Target: < 274 + 143292 [ 47920][E](FTMS_SERVER): 11 00 00 94 ff 28 33 -> Sim Mode Incline -1.080000. Responding: 80 11 01 + 143293 [ 47926][E](DirConManager): Sending response message type 0x04 to client 0 + 143294 [ 48804][E](Main): Homing... Current SG: 346, Baseline: 324, Target: < 274 + 143295 [ 48920][E](FTMS_SERVER): 11 00 00 7e ff 28 33 -> Sim Mode Incline -1.300000. Responding: 80 11 01 + 143296 [ 48928][E](DirConManager): Sending response message type 0x04 to client 0 + 143297 [ 49814][E](Main): Homing... Current SG: 364, Baseline: 324, Target: < 274 + 143298 [ 49863][E](FTMS_SERVER): 11 00 00 67 ff 28 33 -> Sim Mode Incline -1.530000. Responding: 80 11 01 + 143299 [ 49870][E](DirConManager): Sending response message type 0x04 to client 0 + 143300 [ 50820][E](Main): Homing... Current SG: 358, Baseline: 324, Target: < 274 + 143301 [ 50863][E](FTMS_SERVER): 11 00 00 54 ff 28 33 -> Sim Mode Incline -1.720000. Responding: 80 11 01 + 143302 [ 50870][E](DirConManager): Sending response message type 0x04 to client 0 + 143303 [ 51799][E](FTMS_SERVER): 11 00 00 48 ff 28 33 -> Sim Mode Incline -1.840000. Responding: 80 11 01 + 143304 [ 51806][E](DirConManager): Sending response message type 0x04 to client 0 + 143305 [ 51830][E](Main): Homing... Current SG: 364, Baseline: 324, Target: < 274 + 143306 [ 52186][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 6, Cad 68, HR 102, Gear 0, Res 0, Current Pos 0, Target Pos 0 + 143307 [ 52821][E](FTMS_SERVER): 11 00 00 40 ff 28 33 -> Sim Mode Incline -1.920000. Responding: 80 11 01 + 143308 [ 52829][E](DirConManager): Sending response message type 0x04 to client 0 + 143309 [ 52835][E](Main): Homing... Current SG: 354, Baseline: 324, Target: < 274 + 143310 [ 53767][E](FTMS_SERVER): 11 00 00 3a ff 28 33 -> Sim Mode Incline -1.980000. Responding: 80 11 01 + 143311 [ 53774][E](DirConManager): Sending response message type 0x04 to client 0 + 143312 [ 53837][E](Main): Homing... Current SG: 364, Baseline: 324, Target: < 274 + 143313 [ 54011][E](Main): Stall detected! SG dropped to 248. Threshold: 274 + 143314 [ 54129][E](Main): StealthChop is now 1 + 143315 [ 54148][E](Main): Stepper power is now 900. read:703 + 143316 [ 54773][E](FTMS_SERVER): 11 00 00 37 ff 28 33 -> Sim Mode Incline -2.010000. Responding: 80 11 01 + 143317 [ 54778][E](DirConManager): Sending response message type 0x04 to client 0 + 143318 [ 55410][E](Main): Stepper power is now 720. read:703 + 143319 [ 55670][E](FTMS_SERVER): 11 00 00 36 ff 28 33 -> Sim Mode Incline -2.020000. Responding: 80 11 01 + 143320 [ 55678][E](DirConManager): Sending response message type 0x04 to client 0 + 143321 [ 55961][E](Main): Homing backward (min). Stable Threshold: 329, Sensitivity: 50 + 143322 [ 55971][E](Main): Homing... Current SG: 366, Baseline: 329, Target: < 279 + 143323 [ 56413][E](Main): Stall detected! SG dropped to 272. Threshold: 279 + 143324 [ 56532][E](Main): StealthChop is now 1 + 143325 [ 56551][E](Main): Stepper power is now 900. read:703 + 143326 [ 56605][E](FTMS_SERVER): 11 00 00 37 ff 28 33 -> Sim Mode Incline -2.010000. Responding: 80 11 01 + 143327 [ 56613][E](DirConManager): Sending response message type 0x04 to client 0 + 143328 [ 57638][E](FTMS_SERVER): 11 00 00 38 ff 28 33 -> Sim Mode Incline -2.000000. Responding: 80 11 01 + 143329 [ 57645][E](DirConManager): Sending response message type 0x04 to client 0 + 143330 [ 57795][E](Main): Min position found and set to 0. + 143331 [ 57814][E](Main): StealthChop is now 1 + 143332 [ 57833][E](Main): Stepper power is now 900. read:887 + 143333 [ 57834][E](Main): Homing procedure complete. + 143334 [ 57856][E](Main): Shift +8 pos 8 tgt 8200 min 0 max 29356 r_min -2000 r_max 2000 + 143335 [ 57859][E](PTable): Loading Power Table.... + 143336 [ 57883][E](PTable): Loading power table version 6, Size 612, Homed 1 + 143337 [ 57915][E](PTable): Loaded values directly + 143338 [ 58200][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 14, Cad 78, HR 104, Gear 8, Res 0, Current Pos 197, Target Pos 8200 + 143339 [ 58572][E](FTMS_SERVER): 11 00 00 3a ff 28 33 -> Sim Mode Incline -1.980000. Responding: 80 11 01 + 143340 [ 58580][E](DirConManager): Sending response message type 0x04 to client 0 + 143341 [ 59269][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 143342 [ 59270][E](PTable): Power Buffer Reset + 143343 [ 59572][E](FTMS_SERVER): 11 00 00 3e ff 28 33 -> Sim Mode Incline -1.940000. Responding: 80 11 01 + 143344 [ 59580][E](DirConManager): Sending response message type 0x04 to client 0 + 143345 [ 60492][E](FTMS_SERVER): 11 00 00 43 ff 28 33 -> Sim Mode Incline -1.890000. Responding: 80 11 01 + 143346 [ 60497][E](DirConManager): Sending response message type 0x04 to client 0 + 143347 [ 61536][E](FTMS_SERVER): 11 00 00 4a ff 28 33 -> Sim Mode Incline -1.820000. Responding: 80 11 01 + 143348 [ 61541][E](DirConManager): Sending response message type 0x04 to client 0 + 143349 [ 62536][E](FTMS_SERVER): 11 00 00 55 ff 28 33 -> Sim Mode Incline -1.710000. Responding: 80 11 01 + 143350 [ 62543][E](DirConManager): Sending response message type 0x04 to client 0 + 143351 [ 62671][E](Main): Shift +1 pos 9 tgt 9603 min 0 max 29356 r_min -2000 r_max 2000 + 143352 [ 62954][E](Main): Shift +1 pos 10 tgt 10803 min 0 max 29356 r_min -2000 r_max 2000 + 143353 [ 63259][E](Main): Shift +1 pos 11 tgt 12003 min 0 max 29356 r_min -2000 r_max 2000 + 143354 [ 63474][E](FTMS_SERVER): 11 00 00 66 ff 28 33 -> Sim Mode Incline -1.540000. Responding: 80 11 01 + 143355 [ 63482][E](DirConManager): Sending response message type 0x04 to client 0 + 143356 [ 63610][E](Main): Shift +1 pos 12 tgt 13322 min 0 max 29356 r_min -2000 r_max 2000 + 143357 [ 63927][E](Main): Shift +1 pos 13 tgt 14522 min 0 max 29356 r_min -2000 r_max 2000 + 143358 [ 64213][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 143359 [ 64214][E](PTable): Power Buffer Reset + 143360 [ 64215][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 118, Cad 88, HR 104, Gear 13, Res 39, Current Pos 12105, Target Pos 14522 + 143361 [ 64389][E](FTMS_SERVER): 11 00 00 7d ff 28 33 -> Sim Mode Incline -1.310000. Responding: 80 11 01 + 143362 [ 64397][E](DirConManager): Sending response message type 0x04 to client 0 + 143363 [ 64610][E](Main): Shift +1 pos 14 tgt 15883 min 0 max 29356 r_min -2000 r_max 2000 + 143364 [ 65307][E](FTMS_SERVER): 11 00 00 8f ff 28 33 -> Sim Mode Incline -1.130000. Responding: 80 11 01 + 143365 [ 65315][E](DirConManager): Sending response message type 0x04 to client 0 + 143366 [ 66234][E](FTMS_SERVER): 11 00 00 9c ff 28 33 -> Sim Mode Incline -1.000000. Responding: 80 11 01 + 143367 [ 66239][E](DirConManager): Sending response message type 0x04 to client 0 + 143368 [ 67256][E](FTMS_SERVER): 11 00 00 ab ff 28 33 -> Sim Mode Incline -0.850000. Responding: 80 11 01 + 143369 [ 67264][E](DirConManager): Sending response message type 0x04 to client 0 + 143370 [ 68178][E](FTMS_SERVER): 11 00 00 b7 ff 28 33 -> Sim Mode Incline -0.730000. Responding: 80 11 01 + 143371 [ 68186][E](DirConManager): Sending response message type 0x04 to client 0 + 143372 [ 69102][E](FTMS_SERVER): 11 00 00 c0 ff 28 33 -> Sim Mode Incline -0.640000. Responding: 80 11 01 + 143373 [ 69109][E](DirConManager): Sending response message type 0x04 to client 0 + 143374 [ 70008][E](FTMS_SERVER): 11 00 00 c7 ff 28 33 -> Sim Mode Incline -0.570000. Responding: 80 11 01 + 143375 [ 70014][E](DirConManager): Sending response message type 0x04 to client 0 + 143376 [ 70239][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 485, Cad 103, HR 104, Gear 14, Res 55, Current Pos 16400, Target Pos 16401 + 143377 [ 70581][E](PTable): Averaged Entry: watts=329.700012, cad=98.699997, targetPosition=1581.099976, (8)(11) + 143378 [ 70582][E](PTData): Cleaned 247 readings + 143379 [ 70592][E](PTData): New entry recorded (8)(11)(1581) + 143380 [ 70593][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 143381 [ 70604][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 143382 [ 70608][E](PTData): Fit Valid: 1, N: 54, Quad: 1, Time: 3 ms + 143383 [ 70625][E](PTable): New Entry Processed in 45 ms + 143384 [ 70626][E](PTable): Power Buffer Reset + 143385 [ 71038][E](FTMS_SERVER): 11 00 00 cc ff 28 33 -> Sim Mode Incline -0.520000. Responding: 80 11 01 + 143386 [ 71045][E](DirConManager): Sending response message type 0x04 to client 0 + 143387 [ 72064][E](FTMS_SERVER): 11 00 00 d0 ff 28 33 -> Sim Mode Incline -0.480000. Responding: 80 11 01 + 143388 [ 72070][E](DirConManager): Sending response message type 0x04 to client 0 + 143389 [ 73086][E](FTMS_SERVER): 11 00 00 d2 ff 28 33 -> Sim Mode Incline -0.460000. Responding: 80 11 01 + 143390 [ 73092][E](DirConManager): Sending response message type 0x04 to client 0 + 143391 [ 74023][E](FTMS_SERVER): 11 00 00 cf ff 28 33 -> Sim Mode Incline -0.490000. Responding: 80 11 01 + 143392 [ 74031][E](DirConManager): Sending response message type 0x04 to client 0 + 143393 [ 75036][E](FTMS_SERVER): 11 00 00 d4 ff 28 33 -> Sim Mode Incline -0.440000. Responding: 80 11 01 + 143394 [ 75043][E](DirConManager): Sending response message type 0x04 to client 0 + 143395 [ 76168][E](FTMS_SERVER): 11 00 00 04 00 28 33 -> Sim Mode Incline 0.040000. Responding: 80 11 01 + 143396 [ 76172][E](DirConManager): Sending response message type 0x04 to client 0 + 143397 [ 76255][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 507, Cad 104, HR 107, Gear 14, Res 56, Current Pos 16505, Target Pos 16828 + 143398 [ 76945][E](PTable): Averaged Entry: watts=495.799988, cad=104.400002, targetPosition=1649.300049, (9)(17) + 143399 [ 76946][E](PTData): Cleaned 246 readings + 143400 [ 76956][E](PTData): New entry recorded (9)(17)(1649) + 143401 [ 76957][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 143402 [ 76968][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 143403 [ 76972][E](PTData): Fit Valid: 1, N: 55, Quad: 1, Time: 4 ms + 143404 [ 76989][E](PTable): New Entry Processed in 45 ms + 143405 [ 76989][E](PTable): Power Buffer Reset + 143406 [ 77195][E](FTMS_SERVER): 11 00 00 2b 00 28 33 -> Sim Mode Incline 0.430000. Responding: 80 11 01 + 143407 [ 77202][E](DirConManager): Sending response message type 0x04 to client 0 + 143408 [ 78103][E](FTMS_SERVER): 11 00 00 ff ff 28 33 -> Sim Mode Incline -0.010000. Responding: 80 11 01 + 143409 [ 78110][E](DirConManager): Sending response message type 0x04 to client 0 + 143410 [ 79036][E](FTMS_SERVER): 11 00 00 b8 ff 28 33 -> Sim Mode Incline -0.720000. Responding: 80 11 01 + 143411 [ 79044][E](DirConManager): Sending response message type 0x04 to client 0 + 143412 [ 79982][E](FTMS_SERVER): 11 00 00 50 ff 28 33 -> Sim Mode Incline -1.760000. Responding: 80 11 01 + 143413 [ 79990][E](DirConManager): Sending response message type 0x04 to client 0 + 143414 [ 80993][E](FTMS_SERVER): 11 00 00 2b ff 28 33 -> Sim Mode Incline -2.130000. Responding: 80 11 01 + 143415 [ 81000][E](DirConManager): Sending response message type 0x04 to client 0 + 143416 [ 81995][E](FTMS_SERVER): 11 00 00 26 ff 28 33 -> Sim Mode Incline -2.180000. Responding: 80 11 01 + 143417 [ 81999][E](DirConManager): Sending response message type 0x04 to client 0 + 143418 [ 82264][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 524, Cad 105, HR 112, Gear 14, Res 52, Current Pos 15274, Target Pos 15274 + 143419 [ 82916][E](FTMS_SERVER): 11 00 00 25 ff 28 33 -> Sim Mode Incline -2.190000. Responding: 80 11 01 + 143420 [ 82922][E](DirConManager): Sending response message type 0x04 to client 0 + 143421 [ 83957][E](FTMS_SERVER): 11 00 00 27 ff 28 33 -> Sim Mode Incline -2.170000. Responding: 80 11 01 + 143422 [ 83964][E](DirConManager): Sending response message type 0x04 to client 0 + 143423 [ 84887][E](FTMS_SERVER): 11 00 00 33 ff 28 33 -> Sim Mode Incline -2.050000. Responding: 80 11 01 + 143424 [ 84894][E](DirConManager): Sending response message type 0x04 to client 0 + 143425 [ 85792][E](FTMS_SERVER): 11 00 00 80 ff 28 33 -> Sim Mode Incline -1.280000. Responding: 80 11 01 + 143426 [ 85799][E](DirConManager): Sending response message type 0x04 to client 0 + 143427 [ 86716][E](FTMS_SERVER): 11 00 00 fc ff 28 33 -> Sim Mode Incline -0.040000. Responding: 80 11 01 + 143428 [ 86721][E](DirConManager): Sending response message type 0x04 to client 0 + 143429 [ 87633][E](FTMS_SERVER): 11 00 00 4d 00 28 33 -> Sim Mode Incline 0.770000. Responding: 80 11 01 + 143430 [ 87640][E](DirConManager): Sending response message type 0x04 to client 0 + 143431 [ 88281][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 382, Cad 103, HR 118, Gear 14, Res 58, Current Pos 17291, Target Pos 17339 + 143432 [ 88655][E](FTMS_SERVER): 11 00 00 75 00 28 33 -> Sim Mode Incline 1.170000. Responding: 80 11 01 + 143433 [ 88662][E](DirConManager): Sending response message type 0x04 to client 0 + 143434 [ 88961][E](PTable): Averaged Entry: watts=488.899994, cad=104.300003, targetPosition=1656.900024, (9)(16) + 143435 [ 88962][E](PTData): Cleaned 245 readings + 143436 [ 88972][E](PTData): New entry recorded (9)(16)(1656) + 143437 [ 88972][E](PTData): Lower Right Found 9, 17, tp1649 + 143438 [ 88984][E](PTable): New Entry Processed in 24 ms + 143439 [ 88984][E](PTable): Power Buffer Reset + 143440 [ 89596][E](FTMS_SERVER): 11 00 00 8d 00 28 33 -> Sim Mode Incline 1.410000. Responding: 80 11 01 + 143441 [ 89603][E](DirConManager): Sending response message type 0x04 to client 0 + 143442 [ 90508][E](FTMS_SERVER): 11 00 00 a8 00 28 33 -> Sim Mode Incline 1.680000. Responding: 80 11 01 + 143443 [ 90516][E](DirConManager): Sending response message type 0x04 to client 0 + 143444 [ 91414][E](FTMS_SERVER): 11 00 00 a0 00 28 33 -> Sim Mode Incline 1.600000. Responding: 80 11 01 + 143445 [ 91419][E](DirConManager): Sending response message type 0x04 to client 0 + 143446 [ 92447][E](FTMS_SERVER): 11 00 00 5c 00 28 33 -> Sim Mode Incline 0.920000. Responding: 80 11 01 + 143447 [ 92453][E](DirConManager): Sending response message type 0x04 to client 0 + 143448 [ 93251][E](Main): Shift +1 pos 15 tgt 18644 min 0 max 29356 r_min -2000 r_max 2000 + 143449 [ 93472][E](FTMS_SERVER): 11 00 00 42 00 28 33 -> Sim Mode Incline 0.660000. Responding: 80 11 01 + 143450 [ 93477][E](DirConManager): Sending response message type 0x04 to client 0 + 143451 [ 93899][E](PTable): Using detected travel limits during homing + 143452 [ 94298][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 413, Cad 81, HR 122, Gear 15, Res 61, Current Pos 18447, Target Pos 18462 + 143453 [ 94498][E](FTMS_SERVER): 11 00 00 1c 00 28 33 -> Sim Mode Incline 0.280000. Responding: 80 11 01 + 143454 [ 94503][E](DirConManager): Sending response message type 0x04 to client 0 + 143455 [ 95310][E](PTable): Averaged Entry: watts=402.799988, cad=88.400002, targetPosition=1789.699951, (6)(13) + 143456 [ 95312][E](PTData): Cleaned 1 readings + 143457 [ 95322][E](PTData): New entry recorded (6)(13)(1789) + 143458 [ 95323][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 143459 [ 95334][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 143460 [ 95337][E](PTData): Fit Valid: 1, N: 55, Quad: 1, Time: 3 ms + 143461 [ 95345][E](PTable): New Entry Processed in 35 ms + 143462 [ 95345][E](PTable): Power Buffer Reset + 143463 [ 95419][E](FTMS_SERVER): 11 00 00 f9 ff 28 33 -> Sim Mode Incline -0.070000. Responding: 80 11 01 + 143464 [ 95427][E](DirConManager): Sending response message type 0x04 to client 0 + 143465 [ 96340][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 143466 [ 96347][E](DirConManager): Sending response message type 0x04 to client 0 + 143467 [ 96918][E](Main): Shift +1 pos 16 tgt 19200 min 0 max 29356 r_min -2000 r_max 2000 + 143468 [ 97358][E](FTMS_SERVER): 11 00 00 1b 00 28 33 -> Sim Mode Incline 0.270000. Responding: 80 11 01 + 143469 [ 97365][E](DirConManager): Sending response message type 0x04 to client 0 + 143470 [ 98302][E](FTMS_SERVER): 11 00 00 f5 ff 28 33 -> Sim Mode Incline -0.110000. Responding: 80 11 01 + 143471 [ 98309][E](DirConManager): Sending response message type 0x04 to client 0 + 143472 [ 99314][E](FTMS_SERVER): 11 00 00 bb ff 28 33 -> Sim Mode Incline -0.690000. Responding: 80 11 01 + 143473 [ 99322][E](DirConManager): Sending response message type 0x04 to client 0 + 143474 [100231][E](FTMS_SERVER): 11 00 00 a1 ff 28 33 -> Sim Mode Incline -0.950000. Responding: 80 11 01 + 143475 [100236][E](DirConManager): Sending response message type 0x04 to client 0 + 143476 [100309][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 374, Cad 78, HR 120, Gear 16, Res 63, Current Pos 18707, Target Pos 18535 + 143477 [101261][E](FTMS_SERVER): 11 00 00 85 ff 28 33 -> Sim Mode Incline -1.230000. Responding: 80 11 01 + 143478 [101268][E](DirConManager): Sending response message type 0x04 to client 0 + 143479 [101451][E](Main): Shift +1 pos 17 tgt 19539 min 0 max 29356 r_min -2000 r_max 2000 + 143480 [101664][E](PTable): Averaged Entry: watts=400.000000, cad=79.900002, targetPosition=1854.699951, (4)(13) + 143481 [101665][E](PTData): Cleaned 245 readings + 143482 [101675][E](PTData): New entry recorded (4)(13)(1854) + 143483 [101676][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 143484 [101686][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 143485 [101690][E](PTData): Fit Valid: 1, N: 56, Quad: 1, Time: 3 ms + 143486 [101707][E](PTable): New Entry Processed in 44 ms + 143487 [101708][E](PTable): Power Buffer Reset + 143488 [102214][E](FTMS_SERVER): 11 00 00 98 ff 28 33 -> Sim Mode Incline -1.040000. Responding: 80 11 01 + 143489 [102221][E](DirConManager): Sending response message type 0x04 to client 0 + 143490 [103296][E](FTMS_SERVER): 11 00 00 7b ff 28 33 -> Sim Mode Incline -1.330000. Responding: 80 11 01 + 143491 [103303][E](DirConManager): Sending response message type 0x04 to client 0 + 143492 [105033][E](FTMS_SERVER): 11 00 00 84 ff 28 33 -> Sim Mode Incline -1.240000. Responding: 80 11 01 + 143493 [105039][E](DirConManager): Sending response message type 0x04 to client 0 + 143494 [106054][E](FTMS_SERVER): 11 00 00 82 ff 28 33 -> Sim Mode Incline -1.260000. Responding: 80 11 01 + 143495 [106064][E](DirConManager): Sending response message type 0x04 to client 0 + 143496 [106320][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 384, Cad 70, HR 118, Gear 17, Res 66, Current Pos 19518, Target Pos 19518 + 143497 [106921][E](FTMS_SERVER): 11 00 00 81 ff 28 33 -> Sim Mode Incline -1.270000. Responding: 80 11 01 + 143498 [106929][E](DirConManager): Sending response message type 0x04 to client 0 + 143499 [107911][E](FTMS_SERVER): 11 00 00 85 ff 28 33 -> Sim Mode Incline -1.230000. Responding: 80 11 01 + 143500 [107919][E](DirConManager): Sending response message type 0x04 to client 0 + 143501 [108024][E](PTable): Averaged Entry: watts=390.600006, cad=72.199997, targetPosition=1945.300049, (2)(13) + 143502 [108025][E](PTData): Cleaned 244 readings + 143503 [108035][E](PTData): New entry recorded (2)(13)(1945) + 143504 [108036][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 143505 [108047][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 143506 [108051][E](PTData): Fit Valid: 1, N: 57, Quad: 1, Time: 4 ms + 143507 [108068][E](PTable): New Entry Processed in 45 ms + 143508 [108068][E](PTable): Power Buffer Reset + 143509 [108826][E](FTMS_SERVER): 11 00 00 78 ff 28 33 -> Sim Mode Incline -1.360000. Responding: 80 11 01 + 143510 [108834][E](DirConManager): Sending response message type 0x04 to client 0 + 143511 [109751][E](FTMS_SERVER): 11 00 00 6d ff 28 33 -> Sim Mode Incline -1.470000. Responding: 80 11 01 + 143512 [109756][E](DirConManager): Sending response message type 0x04 to client 0 + 143513 [110779][E](FTMS_SERVER): 11 00 00 89 ff 28 33 -> Sim Mode Incline -1.190000. Responding: 80 11 01 + 143514 [110784][E](DirConManager): Sending response message type 0x04 to client 0 + 143515 [111789][E](FTMS_SERVER): 11 00 00 94 ff 28 33 -> Sim Mode Incline -1.080000. Responding: 80 11 01 + 143516 [111793][E](DirConManager): Sending response message type 0x04 to client 0 + 143517 [112331][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 355, Cad 67, HR 125, Gear 17, Res 66, Current Pos 19644, Target Pos 19644 + 143518 [112824][E](FTMS_SERVER): 11 00 00 a6 ff 28 33 -> Sim Mode Incline -0.900000. Responding: 80 11 01 + 143519 [112832][E](DirConManager): Sending response message type 0x04 to client 0 + 143520 [113742][E](FTMS_SERVER): 11 00 00 c4 ff 28 33 -> Sim Mode Incline -0.600000. Responding: 80 11 01 + 143521 [113750][E](DirConManager): Sending response message type 0x04 to client 0 + 143522 [114379][E](PTable): Averaged Entry: watts=361.299988, cad=67.699997, targetPosition=1958.599976, (1)(12) + 143523 [114381][E](PTData): Cleaned 243 readings + 143524 [114391][E](PTData): New entry recorded (1)(12)(1958) + 143525 [114392][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 143526 [114402][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 143527 [114406][E](PTData): Fit Valid: 1, N: 58, Quad: 1, Time: 3 ms + 143528 [114424][E](PTable): New Entry Processed in 45 ms + 143529 [114424][E](PTable): Power Buffer Reset + 143530 [114770][E](FTMS_SERVER): 11 00 00 d3 ff 28 33 -> Sim Mode Incline -0.450000. Responding: 80 11 01 + 143531 [114777][E](DirConManager): Sending response message type 0x04 to client 0 + 143532 [115728][E](FTMS_SERVER): 11 00 00 6c ff 28 33 -> Sim Mode Incline -1.480000. Responding: 80 11 01 + 143533 [115736][E](DirConManager): Sending response message type 0x04 to client 0 + 143534 [116725][E](FTMS_SERVER): 11 00 00 52 ff 28 33 -> Sim Mode Incline -1.740000. Responding: 80 11 01 + 143535 [116733][E](DirConManager): Sending response message type 0x04 to client 0 + 143536 [117636][E](FTMS_SERVER): 11 00 00 63 ff 28 33 -> Sim Mode Incline -1.570000. Responding: 80 11 01 + 143537 [117642][E](DirConManager): Sending response message type 0x04 to client 0 + 143538 [118349][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 379, Cad 66, HR 131, Gear 17, Res 65, Current Pos 19301, Target Pos 19301 + 143539 [119373][E](FTMS_SERVER): 11 00 00 6d ff 28 33 -> Sim Mode Incline -1.470000. Responding: 80 11 01 + 143540 [119380][E](DirConManager): Sending response message type 0x04 to client 0 + 143541 [120229][E](Main): Shift -1 pos 16 tgt 18171 min 0 max 29356 r_min -2000 r_max 2000 + 143542 [120337][E](FTMS_SERVER): 11 00 00 68 ff 28 33 -> Sim Mode Incline -1.520000. Responding: 80 11 01 + 143543 [120344][E](DirConManager): Sending response message type 0x04 to client 0 + 143544 [120735][E](PTable): Averaged Entry: watts=352.899994, cad=66.199997, targetPosition=1950.199951, (1)(12) + 143545 [120736][E](PTData): Cleaned 242 readings + 143546 [120746][E](PTData): Existing entry averaged (1)(12)(1955), readings(2) + 143547 [120747][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 143548 [120758][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 143549 [120772][E](PTData): Fit Valid: 1, N: 58, Quad: 1, Time: 4 ms + 143550 [120779][E](PTable): New Entry Processed in 45 ms + 143551 [120779][E](PTable): Power Buffer Reset + 143552 [121081][E](Main): Shift -1 pos 15 tgt 16936 min 0 max 29356 r_min -2000 r_max 2000 + 143553 [121337][E](FTMS_SERVER): 11 00 00 6b ff 28 33 -> Sim Mode Incline -1.490000. Responding: 80 11 01 + 143554 [121344][E](DirConManager): Sending response message type 0x04 to client 0 + 143555 [121993][E](Main): Shift -1 pos 14 tgt 15757 min 0 max 29356 r_min -2000 r_max 2000 + 143556 [122450][E](FTMS_SERVER): 11 00 00 6c ff 28 33 -> Sim Mode Incline -1.480000. Responding: 80 11 01 + 143557 [122457][E](DirConManager): Sending response message type 0x04 to client 0 + 143558 [123367][E](FTMS_SERVER): 11 00 00 65 ff 28 33 -> Sim Mode Incline -1.550000. Responding: 80 11 01 + 143559 [123372][E](DirConManager): Sending response message type 0x04 to client 0 + 143560 [124365][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 318, Cad 73, HR 132, Gear 14, Res 53, Current Pos 15715, Target Pos 15715 + 143561 [124389][E](FTMS_SERVER): 11 00 00 70 ff 28 33 -> Sim Mode Incline -1.440000. Responding: 80 11 01 + 143562 [124395][E](DirConManager): Sending response message type 0x04 to client 0 + 143563 [125035][E](Main): Shift -1 pos 13 tgt 14592 min 0 max 29356 r_min -2000 r_max 2000 + 143564 [125344][E](FTMS_SERVER): 11 00 00 a1 ff 28 33 -> Sim Mode Incline -0.950000. Responding: 80 11 01 + 143565 [125349][E](DirConManager): Sending response message type 0x04 to client 0 + 143566 [125674][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 143567 [125675][E](PTable): Power Buffer Reset + 143568 [126235][E](FTMS_SERVER): 11 00 00 dd ff 28 33 -> Sim Mode Incline -0.350000. Responding: 80 11 01 + 143569 [126242][E](DirConManager): Sending response message type 0x04 to client 0 + 143570 [127146][E](FTMS_SERVER): 11 00 00 20 00 28 33 -> Sim Mode Incline 0.320000. Responding: 80 11 01 + 143571 [127154][E](DirConManager): Sending response message type 0x04 to client 0 + 143572 [128170][E](FTMS_SERVER): 11 00 00 47 00 28 33 -> Sim Mode Incline 0.710000. Responding: 80 11 01 + 143573 [128177][E](DirConManager): Sending response message type 0x04 to client 0 + 143574 [129141][E](FTMS_SERVER): 11 00 00 49 00 28 33 -> Sim Mode Incline 0.730000. Responding: 80 11 01 + 143575 [129149][E](DirConManager): Sending response message type 0x04 to client 0 + 143576 [129901][E](PTable): Using detected travel limits during homing + 143577 [130138][E](FTMS_SERVER): 11 00 00 29 00 28 33 -> Sim Mode Incline 0.410000. Responding: 80 11 01 + 143578 [130145][E](DirConManager): Sending response message type 0x04 to client 0 + 143579 [130380][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 316, Cad 85, HR 133, Gear 13, Res 54, Current Pos 16025, Target Pos 15887 + 143580 [131140][E](FTMS_SERVER): 11 00 00 f3 ff 28 33 -> Sim Mode Incline -0.130000. Responding: 80 11 01 + 143581 [131145][E](DirConManager): Sending response message type 0x04 to client 0 + 143582 [132017][E](PTable): Averaged Entry: watts=294.299988, cad=83.500000, targetPosition=1564.599976, (5)(10) + 143583 [132018][E](PTData): Cleaned 242 readings + 143584 [132028][E](PTData): Existing entry averaged (5)(10)(1561), readings(4) + 143585 [132029][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 143586 [132040][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 143587 [132054][E](PTData): Fit Valid: 1, N: 58, Quad: 1, Time: 4 ms + 143588 [132061][E](PTable): New Entry Processed in 45 ms + 143589 [132061][E](PTable): Power Buffer Reset + 143590 [132086][E](FTMS_SERVER): 11 00 00 c1 ff 28 33 -> Sim Mode Incline -0.630000. Responding: 80 11 01 + 143591 [132094][E](DirConManager): Sending response message type 0x04 to client 0 + 143592 [133109][E](FTMS_SERVER): 11 00 00 a9 ff 28 33 -> Sim Mode Incline -0.870000. Responding: 80 11 01 + 143593 [133115][E](DirConManager): Sending response message type 0x04 to client 0 + 143594 [134037][E](FTMS_SERVER): 11 00 00 b2 ff 28 33 -> Sim Mode Incline -0.780000. Responding: 80 11 01 + 143595 [134044][E](DirConManager): Sending response message type 0x04 to client 0 + 143596 [134946][E](FTMS_SERVER): 11 00 00 c9 ff 28 33 -> Sim Mode Incline -0.550000. Responding: 80 11 01 + 143597 [134954][E](DirConManager): Sending response message type 0x04 to client 0 + 143598 [135851][E](FTMS_SERVER): 11 00 00 e1 ff 28 33 -> Sim Mode Incline -0.310000. Responding: 80 11 01 + 143599 [135857][E](DirConManager): Sending response message type 0x04 to client 0 + 143600 [136388][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 282, Cad 87, HR 135, Gear 13, Res 52, Current Pos 15383, Target Pos 15383 + 143601 [136781][E](FTMS_SERVER): 11 00 00 f2 ff 28 33 -> Sim Mode Incline -0.140000. Responding: 80 11 01 + 143602 [136788][E](DirConManager): Sending response message type 0x04 to client 0 + 143603 [137806][E](FTMS_SERVER): 11 00 00 f9 ff 28 33 -> Sim Mode Incline -0.070000. Responding: 80 11 01 + 143604 [137814][E](DirConManager): Sending response message type 0x04 to client 0 + 143605 [138384][E](PTable): Averaged Entry: watts=283.100006, cad=85.500000, targetPosition=1524.400024, (5)(9) + 143606 [138385][E](PTData): Cleaned 242 readings + 143607 [138395][E](PTData): Existing entry averaged (5)(9)(1488), readings(8) + 143608 [138396][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 143609 [138407][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 143610 [138411][E](PTData): Fit Valid: 1, N: 58, Quad: 1, Time: 4 ms + 143611 [138428][E](PTable): New Entry Processed in 45 ms + 143612 [138428][E](PTable): Power Buffer Reset + 143613 [138744][E](FTMS_SERVER): 11 00 00 fe ff 28 33 -> Sim Mode Incline -0.020000. Responding: 80 11 01 + 143614 [138751][E](DirConManager): Sending response message type 0x04 to client 0 + 143615 [139659][E](FTMS_SERVER): 11 00 00 01 00 28 33 -> Sim Mode Incline 0.010000. Responding: 80 11 01 + 143616 [139666][E](DirConManager): Sending response message type 0x04 to client 0 + 143617 [140567][E](FTMS_SERVER): 11 00 00 04 00 28 33 -> Sim Mode Incline 0.040000. Responding: 80 11 01 + 143618 [140573][E](DirConManager): Sending response message type 0x04 to client 0 + 143619 [141505][E](FTMS_SERVER): 11 00 00 07 00 28 33 -> Sim Mode Incline 0.070000. Responding: 80 11 01 + 143620 [141510][E](DirConManager): Sending response message type 0x04 to client 0 + 143621 [142396][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 322, Cad 84, HR 137, Gear 13, Res 53, Current Pos 15649, Target Pos 15649 + 143622 [142511][E](FTMS_SERVER): 11 00 00 08 00 28 33 -> Sim Mode Incline 0.080000. Responding: 80 11 01 + 143623 [142518][E](DirConManager): Sending response message type 0x04 to client 0 + 143624 [143459][E](FTMS_SERVER): 11 00 00 09 00 28 33 -> Sim Mode Incline 0.090000. Responding: 80 11 01 + 143625 [143467][E](DirConManager): Sending response message type 0x04 to client 0 + 143626 [144356][E](FTMS_SERVER): 11 00 00 08 00 28 33 -> Sim Mode Incline 0.080000. Responding: 80 11 01 + 143627 [144362][E](DirConManager): Sending response message type 0x04 to client 0 + 143628 [144734][E](PTable): Averaged Entry: watts=285.299988, cad=85.699997, targetPosition=1562.300049, (5)(10) + 143629 [144735][E](PTData): Cleaned 242 readings + 143630 [144745][E](PTData): Existing entry averaged (5)(10)(1561), readings(5) + 143631 [144746][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 143632 [144757][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 143633 [144771][E](PTData): Fit Valid: 1, N: 58, Quad: 1, Time: 4 ms + 143634 [144778][E](PTable): New Entry Processed in 45 ms + 143635 [144778][E](PTable): Power Buffer Reset + 143636 [145271][E](FTMS_SERVER): 11 00 00 07 00 28 33 -> Sim Mode Incline 0.070000. Responding: 80 11 01 + 143637 [145277][E](DirConManager): Sending response message type 0x04 to client 0 + 143638 [146195][E](FTMS_SERVER): 11 00 00 04 00 28 33 -> Sim Mode Incline 0.040000. Responding: 80 11 01 + 143639 [146200][E](DirConManager): Sending response message type 0x04 to client 0 + 143640 [147236][E](FTMS_SERVER): 11 00 00 01 00 28 33 -> Sim Mode Incline 0.010000. Responding: 80 11 01 + 143641 [147240][E](DirConManager): Sending response message type 0x04 to client 0 + 143642 [148262][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 143643 [148270][E](DirConManager): Sending response message type 0x04 to client 0 + 143644 [148412][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 326, Cad 89, HR 140, Gear 13, Res 53, Current Pos 15600, Target Pos 15600 + 143645 [151076][E](PTable): Averaged Entry: watts=306.799988, cad=87.000000, targetPosition=1561.400024, (5)(10) + 143646 [151078][E](PTData): Cleaned 242 readings + 143647 [151088][E](PTData): Existing entry averaged (5)(10)(1561), readings(6) + 143648 [151089][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 143649 [151099][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 143650 [151114][E](PTData): Fit Valid: 1, N: 58, Quad: 1, Time: 4 ms + 143651 [151121][E](PTable): New Entry Processed in 45 ms + 143652 [151121][E](PTable): Power Buffer Reset + 143653 [154428][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 320, Cad 89, HR 148, Gear 13, Res 53, Current Pos 15600, Target Pos 15600 + 143654 [157428][E](PTable): Averaged Entry: watts=331.200012, cad=89.400002, targetPosition=1560.000000, (6)(11) + 143655 [157429][E](PTData): Cleaned 242 readings + 143656 [157440][E](PTData): New entry recorded (6)(11)(1560) + 143657 [157440][E](PTData): Greater Down Found 8, 11, tp1581 + 143658 [157451][E](PTable): New Entry Processed in 24 ms + 143659 [157451][E](PTable): Power Buffer Reset + 143660 [160443][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 325, Cad 91, HR 159, Gear 13, Res 53, Current Pos 15600, Target Pos 15600 + 143661 [161184][E](FTMS_SERVER): 11 00 00 01 00 28 33 -> Sim Mode Incline 0.010000. Responding: 80 11 01 + 143662 [161191][E](DirConManager): Sending response message type 0x04 to client 0 + 143663 [162182][E](FTMS_SERVER): 11 00 00 02 00 28 33 -> Sim Mode Incline 0.020000. Responding: 80 11 01 + 143664 [162189][E](DirConManager): Sending response message type 0x04 to client 0 + 143665 [163769][E](PTable): Averaged Entry: watts=329.000000, cad=91.099998, targetPosition=1560.300049, (6)(11) + 143666 [163770][E](PTData): Cleaned 1 readings + 143667 [163780][E](PTData): New entry recorded (6)(11)(1560) + 143668 [163781][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 143669 [163795][E](PTData): Fit Valid: 1, N: 58, Quad: 1, Time: 4 ms + 143670 [163803][E](PTable): New Entry Processed in 35 ms + 143671 [163803][E](PTable): Power Buffer Reset + 143672 [163930][E](FTMS_SERVER): 11 00 00 03 00 28 33 -> Sim Mode Incline 0.030000. Responding: 80 11 01 + 143673 [163935][E](DirConManager): Sending response message type 0x04 to client 0 + 143674 [165892][E](PTable): Using detected travel limits during homing + 143675 [166381][E](FTMS_SERVER): 11 00 00 02 00 28 33 -> Sim Mode Incline 0.020000. Responding: 80 11 01 + 143676 [166388][E](DirConManager): Sending response message type 0x04 to client 0 + 143677 [166461][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 324, Cad 90, HR 165, Gear 13, Res 53, Current Pos 15614, Target Pos 15614 + 143678 [168146][E](FTMS_SERVER): 11 00 00 01 00 28 33 -> Sim Mode Incline 0.010000. Responding: 80 11 01 + 143679 [168152][E](DirConManager): Sending response message type 0x04 to client 0 + 143680 [169146][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 143681 [169151][E](DirConManager): Sending response message type 0x04 to client 0 + 143682 [170122][E](PTable): Averaged Entry: watts=332.200012, cad=91.099998, targetPosition=1561.099976, (6)(11) + 143683 [170124][E](PTData): Cleaned 242 readings + 143684 [170134][E](PTData): Existing entry averaged (6)(11)(1560), readings(2) + 143685 [170135][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 143686 [170149][E](PTData): Fit Valid: 1, N: 58, Quad: 1, Time: 4 ms + 143687 [170156][E](PTable): New Entry Processed in 34 ms + 143688 [170157][E](PTable): Power Buffer Reset + 143689 [171591][E](FTMS_SERVER): 11 00 00 ff ff 28 33 -> Sim Mode Incline -0.010000. Responding: 80 11 01 + 143690 [171599][E](DirConManager): Sending response message type 0x04 to client 0 + 143691 [172469][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 322, Cad 90, HR 167, Gear 13, Res 53, Current Pos 15593, Target Pos 15593 + 143692 [173339][E](FTMS_SERVER): 11 00 00 fe ff 28 33 -> Sim Mode Incline -0.020000. Responding: 80 11 01 + 143693 [173344][E](DirConManager): Sending response message type 0x04 to client 0 + 143694 [174992][E](FTMS_SERVER): 11 00 00 fd ff 28 33 -> Sim Mode Incline -0.030000. Responding: 80 11 01 + 143695 [175000][E](DirConManager): Sending response message type 0x04 to client 0 + 143696 [175909][E](FTMS_SERVER): 11 00 00 fb ff 28 33 -> Sim Mode Incline -0.050000. Responding: 80 11 01 + 143697 [175917][E](DirConManager): Sending response message type 0x04 to client 0 + 143698 [176482][E](PTable): Averaged Entry: watts=324.799988, cad=90.099998, targetPosition=1558.400024, (6)(11) + 143699 [176484][E](PTData): Cleaned 242 readings + 143700 [176494][E](PTData): Existing entry averaged (6)(11)(1559), readings(3) + 143701 [176495][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 143702 [176509][E](PTData): Fit Valid: 1, N: 58, Quad: 1, Time: 3 ms + 143703 [176516][E](PTable): New Entry Processed in 34 ms + 143704 [176517][E](PTable): Power Buffer Reset + 143705 [176821][E](FTMS_SERVER): 11 00 00 f9 ff 28 33 -> Sim Mode Incline -0.070000. Responding: 80 11 01 + 143706 [176828][E](DirConManager): Sending response message type 0x04 to client 0 + 143707 [177840][E](FTMS_SERVER): 11 00 00 f8 ff 28 33 -> Sim Mode Incline -0.080000. Responding: 80 11 01 + 143708 [177848][E](DirConManager): Sending response message type 0x04 to client 0 + 143709 [178485][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 333, Cad 90, HR 168, Gear 13, Res 52, Current Pos 15544, Target Pos 15544 + 143710 [178793][E](FTMS_SERVER): 11 00 00 f7 ff 28 33 -> Sim Mode Incline -0.090000. Responding: 80 11 01 + 143711 [178800][E](DirConManager): Sending response message type 0x04 to client 0 + 143712 [179810][E](FTMS_SERVER): 11 00 00 f6 ff 28 33 -> Sim Mode Incline -0.100000. Responding: 80 11 01 + 143713 [179817][E](DirConManager): Sending response message type 0x04 to client 0 + 143714 [180702][E](FTMS_SERVER): 11 00 00 f5 ff 28 33 -> Sim Mode Incline -0.110000. Responding: 80 11 01 + 143715 [180709][E](DirConManager): Sending response message type 0x04 to client 0 + 143716 [182834][E](PTable): Averaged Entry: watts=322.899994, cad=89.099998, targetPosition=1553.300049, (6)(11) + 143717 [182836][E](PTData): Cleaned 242 readings + 143718 [182846][E](PTData): Existing entry averaged (6)(11)(1557), readings(4) + 143719 [182847][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 143720 [182861][E](PTData): Fit Valid: 1, N: 58, Quad: 1, Time: 4 ms + 143721 [182868][E](PTable): New Entry Processed in 34 ms + 143722 [182869][E](PTable): Power Buffer Reset + 143723 [184501][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 372, Cad 95, HR 168, Gear 13, Res 52, Current Pos 15523, Target Pos 15523 + 143724 [185422][E](FTMS_SERVER): 11 00 00 f6 ff 28 33 -> Sim Mode Incline -0.100000. Responding: 80 11 01 + 143725 [185427][E](DirConManager): Sending response message type 0x04 to client 0 + 143726 [187106][E](FTMS_SERVER): 11 00 00 f7 ff 28 33 -> Sim Mode Incline -0.090000. Responding: 80 11 01 + 143727 [187112][E](DirConManager): Sending response message type 0x04 to client 0 + 143728 [188095][E](FTMS_SERVER): 11 00 00 f8 ff 28 33 -> Sim Mode Incline -0.080000. Responding: 80 11 01 + 143729 [188102][E](DirConManager): Sending response message type 0x04 to client 0 + 143730 [189015][E](FTMS_SERVER): 11 00 00 f9 ff 28 33 -> Sim Mode Incline -0.070000. Responding: 80 11 01 + 143731 [189021][E](DirConManager): Sending response message type 0x04 to client 0 + 143732 [189185][E](PTable): Averaged Entry: watts=378.700012, cad=96.800003, targetPosition=1552.900024, (7)(13) + 143733 [189186][E](PTData): Cleaned 242 readings + 143734 [189196][E](PTData): New entry recorded (7)(13)(1552) + 143735 [189197][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 143736 [189212][E](PTData): Fit Valid: 1, N: 59, Quad: 1, Time: 4 ms + 143737 [189219][E](PTable): New Entry Processed in 35 ms + 143738 [189219][E](PTable): Power Buffer Reset + 143739 [189923][E](FTMS_SERVER): 11 00 00 fa ff 28 33 -> Sim Mode Incline -0.060000. Responding: 80 11 01 + 143740 [189930][E](DirConManager): Sending response message type 0x04 to client 0 + 143741 [190515][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 381, Cad 101, HR 168, Gear 13, Res 52, Current Pos 15558, Target Pos 15558 + 143742 [190949][E](FTMS_SERVER): 11 00 00 fc ff 28 33 -> Sim Mode Incline -0.040000. Responding: 80 11 01 + 143743 [190956][E](DirConManager): Sending response message type 0x04 to client 0 + 143744 [191899][E](FTMS_SERVER): 11 00 00 fe ff 28 33 -> Sim Mode Incline -0.020000. Responding: 80 11 01 + 143745 [191907][E](DirConManager): Sending response message type 0x04 to client 0 + 143746 [192913][E](FTMS_SERVER): 11 00 00 01 00 28 33 -> Sim Mode Incline 0.010000. Responding: 80 11 01 + 143747 [192921][E](DirConManager): Sending response message type 0x04 to client 0 + 143748 [193924][E](FTMS_SERVER): 11 00 00 08 00 28 33 -> Sim Mode Incline 0.080000. Responding: 80 11 01 + 143749 [193932][E](DirConManager): Sending response message type 0x04 to client 0 + 143750 [194936][E](FTMS_SERVER): 11 00 00 0f 00 28 33 -> Sim Mode Incline 0.150000. Responding: 80 11 01 + 143751 [194944][E](DirConManager): Sending response message type 0x04 to client 0 + 143752 [195533][E](PTable): Averaged Entry: watts=369.200012, cad=98.400002, targetPosition=1559.800049, (8)(12) + 143753 [195534][E](PTData): Cleaned 241 readings + 143754 [195544][E](PTData): New entry recorded (8)(12)(1559) + 143755 [195545][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 143756 [195556][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 143757 [195560][E](PTData): Fit Valid: 1, N: 60, Quad: 1, Time: 4 ms + 143758 [195577][E](PTable): New Entry Processed in 45 ms + 143759 [195577][E](PTable): Power Buffer Reset + 143760 [195962][E](FTMS_SERVER): 11 00 00 1a 00 28 33 -> Sim Mode Incline 0.260000. Responding: 80 11 01 + 143761 [195969][E](DirConManager): Sending response message type 0x04 to client 0 + 143762 [196525][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 348, Cad 95, HR 169, Gear 13, Res 53, Current Pos 15782, Target Pos 15782 + 143763 [196904][E](FTMS_SERVER): 11 00 00 29 00 28 33 -> Sim Mode Incline 0.410000. Responding: 80 11 01 + 143764 [196911][E](DirConManager): Sending response message type 0x04 to client 0 + 143765 [197823][E](FTMS_SERVER): 11 00 00 36 00 28 33 -> Sim Mode Incline 0.540000. Responding: 80 11 01 + 143766 [197828][E](DirConManager): Sending response message type 0x04 to client 0 + 143767 [198729][E](FTMS_SERVER): 11 00 00 42 00 28 33 -> Sim Mode Incline 0.660000. Responding: 80 11 01 + 143768 [198737][E](DirConManager): Sending response message type 0x04 to client 0 + 143769 [199659][E](FTMS_SERVER): 11 00 00 4d 00 28 33 -> Sim Mode Incline 0.770000. Responding: 80 11 01 + 143770 [199666][E](DirConManager): Sending response message type 0x04 to client 0 + 143771 [200619][E](FTMS_SERVER): 11 00 00 57 00 28 33 -> Sim Mode Incline 0.870000. Responding: 80 11 01 + 143772 [200626][E](DirConManager): Sending response message type 0x04 to client 0 + 143773 [201612][E](FTMS_SERVER): 11 00 00 60 00 28 33 -> Sim Mode Incline 0.960000. Responding: 80 11 01 + 143774 [201620][E](DirConManager): Sending response message type 0x04 to client 0 + 143775 [201885][E](PTable): Averaged Entry: watts=363.799988, cad=94.900002, targetPosition=1599.099976, (7)(12) + 143776 [201886][E](PTData): Cleaned 240 readings + 143777 [201896][E](PTData): New entry recorded (7)(12)(1599) + 143778 [201897][E](PTData): Lower Right Found 7, 13, tp1552 + 143779 [201908][E](PTable): New Entry Processed in 24 ms + 143780 [201908][E](PTable): Power Buffer Reset + 143781 [201909][E](PTable): Using detected travel limits during homing + 143782 [202524][E](FTMS_SERVER): 11 00 00 66 00 28 33 -> Sim Mode Incline 1.020000. Responding: 80 11 01 + 143783 [202529][E](DirConManager): Sending response message type 0x04 to client 0 + 143784 [202541][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 326, Cad 89, HR 169, Gear 13, Res 55, Current Pos 16272, Target Pos 16314 + 143785 [203442][E](FTMS_SERVER): 11 00 00 69 00 28 33 -> Sim Mode Incline 1.050000. Responding: 80 11 01 + 143786 [203449][E](DirConManager): Sending response message type 0x04 to client 0 + 143787 [204374][E](FTMS_SERVER): 11 00 00 6a 00 28 33 -> Sim Mode Incline 1.060000. Responding: 80 11 01 + 143788 [204381][E](DirConManager): Sending response message type 0x04 to client 0 + 143789 [205326][E](FTMS_SERVER): 11 00 00 69 00 28 33 -> Sim Mode Incline 1.050000. Responding: 80 11 01 + 143790 [205333][E](DirConManager): Sending response message type 0x04 to client 0 + 143791 [206326][E](FTMS_SERVER): 11 00 00 63 00 28 33 -> Sim Mode Incline 0.990000. Responding: 80 11 01 + 143792 [206333][E](DirConManager): Sending response message type 0x04 to client 0 + 143793 [207234][E](FTMS_SERVER): 11 00 00 5c 00 28 33 -> Sim Mode Incline 0.920000. Responding: 80 11 01 + 143794 [207240][E](DirConManager): Sending response message type 0x04 to client 0 + 143795 [208150][E](FTMS_SERVER): 11 00 00 53 00 28 33 -> Sim Mode Incline 0.830000. Responding: 80 11 01 + 143796 [208157][E](DirConManager): Sending response message type 0x04 to client 0 + 143797 [208251][E](PTable): Averaged Entry: watts=322.200012, cad=86.300003, targetPosition=1629.500000, (5)(11) + 143798 [208252][E](PTData): Cleaned 1 readings + 143799 [208263][E](PTData): New entry recorded (5)(11)(1629) + 143800 [208263][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 143801 [208278][E](PTData): Fit Valid: 1, N: 60, Quad: 1, Time: 4 ms + 143802 [208285][E](PTable): New Entry Processed in 35 ms + 143803 [208285][E](PTable): Power Buffer Reset + 143804 [208558][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 329, Cad 83, HR 170, Gear 13, Res 55, Current Pos 16181, Target Pos 16181 + 143805 [209192][E](FTMS_SERVER): 11 00 00 48 00 28 33 -> Sim Mode Incline 0.720000. Responding: 80 11 01 + 143806 [209200][E](DirConManager): Sending response message type 0x04 to client 0 + 143807 [210135][E](FTMS_SERVER): 11 00 00 39 00 28 33 -> Sim Mode Incline 0.570000. Responding: 80 11 01 + 143808 [210142][E](DirConManager): Sending response message type 0x04 to client 0 + 143809 [211123][E](FTMS_SERVER): 11 00 00 29 00 28 33 -> Sim Mode Incline 0.410000. Responding: 80 11 01 + 143810 [211131][E](DirConManager): Sending response message type 0x04 to client 0 + 143811 [212036][E](FTMS_SERVER): 11 00 00 22 00 28 33 -> Sim Mode Incline 0.340000. Responding: 80 11 01 + 143812 [212042][E](DirConManager): Sending response message type 0x04 to client 0 + 143813 [212967][E](FTMS_SERVER): 11 00 00 1a 00 28 33 -> Sim Mode Incline 0.260000. Responding: 80 11 01 + 143814 [212972][E](DirConManager): Sending response message type 0x04 to client 0 + 143815 [213995][E](FTMS_SERVER): 11 00 00 13 00 28 33 -> Sim Mode Incline 0.190000. Responding: 80 11 01 + 143816 [213999][E](DirConManager): Sending response message type 0x04 to client 0 + 143817 [214572][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 344, Cad 88, HR 172, Gear 13, Res 53, Current Pos 15733, Target Pos 15733 + 143818 [214603][E](PTable): Averaged Entry: watts=325.899994, cad=84.800003, targetPosition=1594.699951, (5)(11) + 143819 [214605][E](PTData): Cleaned 240 readings + 143820 [214615][E](PTData): Existing entry averaged (5)(11)(1617), readings(2) + 143821 [214616][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 143822 [214630][E](PTData): Fit Valid: 1, N: 60, Quad: 1, Time: 4 ms + 143823 [214637][E](PTable): New Entry Processed in 34 ms + 143824 [214638][E](PTable): Power Buffer Reset + 143825 [215029][E](FTMS_SERVER): 11 00 00 0b 00 28 33 -> Sim Mode Incline 0.110000. Responding: 80 11 01 + 143826 [215034][E](DirConManager): Sending response message type 0x04 to client 0 + 143827 [216038][E](FTMS_SERVER): 11 00 00 03 00 28 33 -> Sim Mode Incline 0.030000. Responding: 80 11 01 + 143828 [216045][E](DirConManager): Sending response message type 0x04 to client 0 + 143829 [216966][E](FTMS_SERVER): 11 00 00 ff ff 28 33 -> Sim Mode Incline -0.010000. Responding: 80 11 01 + 143830 [216973][E](DirConManager): Sending response message type 0x04 to client 0 + 143831 [217989][E](FTMS_SERVER): 11 00 00 fd ff 28 33 -> Sim Mode Incline -0.030000. Responding: 80 11 01 + 143832 [217997][E](DirConManager): Sending response message type 0x04 to client 0 + 143833 [218946][E](FTMS_SERVER): 11 00 00 fc ff 28 33 -> Sim Mode Incline -0.040000. Responding: 80 11 01 + 143834 [218953][E](DirConManager): Sending response message type 0x04 to client 0 + 143835 [220584][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 300, Cad 89, HR 173, Gear 13, Res 53, Current Pos 15572, Target Pos 15572 + 143836 [220970][E](PTable): Averaged Entry: watts=334.299988, cad=90.300003, targetPosition=1560.699951, (6)(11) + 143837 [220972][E](PTData): Cleaned 240 readings + 143838 [220982][E](PTData): Existing entry averaged (6)(11)(1557), readings(5) + 143839 [220983][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 143840 [220998][E](PTData): Fit Valid: 1, N: 60, Quad: 1, Time: 4 ms + 143841 [221004][E](PTable): New Entry Processed in 34 ms + 143842 [221005][E](PTable): Power Buffer Reset + 143843 [222046][E](Main): Shift -1 pos 12 tgt 14372 min 0 max 29356 r_min -2000 r_max 2000 + 143844 [223652][E](FTMS_SERVER): 11 00 00 fd ff 28 33 -> Sim Mode Incline -0.030000. Responding: 80 11 01 + 143845 [223659][E](DirConManager): Sending response message type 0x04 to client 0 + 143846 [224639][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 143847 [224646][E](DirConManager): Sending response message type 0x04 to client 0 + 143848 [225789][E](Main): Shift -1 pos 11 tgt 13200 min 0 max 29356 r_min -2000 r_max 2000 + 143849 [226380][E](FTMS_SERVER): 11 00 00 ff ff 28 33 -> Sim Mode Incline -0.010000. Responding: 80 11 01 + 143850 [226388][E](DirConManager): Sending response message type 0x04 to client 0 + 143851 [226592][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 203, Cad 77, HR 171, Gear 11, Res 46, Current Pos 13497, Target Pos 13193 + 143852 [227309][E](PTable): Averaged Entry: watts=246.500000, cad=81.300003, targetPosition=1451.300049, (4)(8) + 143853 [227310][E](PTData): Cleaned 240 readings + 143854 [227320][E](PTData): Existing entry averaged (4)(8)(1515), readings(10) + 143855 [227321][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 143856 [227336][E](PTData): Fit Valid: 1, N: 60, Quad: 1, Time: 5 ms + 143857 [227343][E](PTable): New Entry Processed in 35 ms + 143858 [227343][E](PTable): Power Buffer Reset + 143859 [227407][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 143860 [227414][E](DirConManager): Sending response message type 0x04 to client 0 + 143861 [228346][E](FTMS_SERVER): 11 00 00 ff ff 28 33 -> Sim Mode Incline -0.010000. Responding: 80 11 01 + 143862 [228353][E](DirConManager): Sending response message type 0x04 to client 0 + 143863 [232608][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 166, Cad 78, HR 172, Gear 11, Res 44, Current Pos 13193, Target Pos 13193 + 143864 [233056][E](FTMS_SERVER): 11 00 00 fe ff 28 33 -> Sim Mode Incline -0.020000. Responding: 80 11 01 + 143865 [233064][E](DirConManager): Sending response message type 0x04 to client 0 + 143866 [233662][E](PTable): Averaged Entry: watts=156.100006, cad=76.199997, targetPosition=1319.099976, (3)(5) + 143867 [233663][E](PTData): Cleaned 240 readings + 143868 [233673][E](PTData): New entry recorded (3)(5)(1319) + 143869 [233674][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 143870 [233688][E](PTData): Fit Valid: 1, N: 61, Quad: 1, Time: 4 ms + 143871 [233695][E](PTable): New Entry Processed in 34 ms + 143872 [233696][E](PTable): Power Buffer Reset + 143873 [236416][E](FTMS_SERVER): 11 00 00 fd ff 28 33 -> Sim Mode Incline -0.030000. Responding: 80 11 01 + 143874 [236420][E](DirConManager): Sending response message type 0x04 to client 0 + 143875 [237454][E](FTMS_SERVER): 11 00 00 fc ff 28 33 -> Sim Mode Incline -0.040000. Responding: 80 11 01 + 143876 [237458][E](DirConManager): Sending response message type 0x04 to client 0 + 143877 [237893][E](PTable): Using detected travel limits during homing + 143878 [238626][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 174, Cad 81, HR 170, Gear 11, Res 44, Current Pos 13172, Target Pos 13172 + 143879 [239898][E](FTMS_SERVER): 11 00 00 fd ff 28 33 -> Sim Mode Incline -0.030000. Responding: 80 11 01 + 143880 [239905][E](DirConManager): Sending response message type 0x04 to client 0 + 143881 [240009][E](PTable): Averaged Entry: watts=155.899994, cad=80.199997, targetPosition=1317.500000, (4)(5) + 143882 [240010][E](PTData): Cleaned 239 readings + 143883 [240020][E](PTData): New entry recorded (4)(5)(1317) + 143884 [240021][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 143885 [240036][E](PTData): Fit Valid: 1, N: 62, Quad: 1, Time: 5 ms + 143886 [240043][E](PTable): New Entry Processed in 34 ms + 143887 [240170][E](PTable): Writing File: /PowerTable.txt + 143888 [240404][E](PTable): Power table saved successfully with 632 readings + 143889 [240405][E](PTable): Power Buffer Reset + 143890 [240928][E](FTMS_SERVER): 11 00 00 fe ff 28 33 -> Sim Mode Incline -0.020000. Responding: 80 11 01 + 143891 [240936][E](DirConManager): Sending response message type 0x04 to client 0 + 143892 [241866][E](FTMS_SERVER): 11 00 00 ff ff 28 33 -> Sim Mode Incline -0.010000. Responding: 80 11 01 + 143893 [241874][E](DirConManager): Sending response message type 0x04 to client 0 + 143894 [243579][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 143895 [243584][E](DirConManager): Sending response message type 0x04 to client 0 + 143896 [244636][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 165, Cad 82, HR 167, Gear 11, Res 44, Current Pos 13200, Target Pos 13200 + 143897 [246376][E](PTable): Averaged Entry: watts=155.899994, cad=81.300003, targetPosition=1318.900024, (4)(5) + 143898 [246377][E](PTData): Cleaned 238 readings + 143899 [246387][E](PTData): Existing entry averaged (4)(5)(1317), readings(2) + 143900 [246388][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 143901 [246403][E](PTData): Fit Valid: 1, N: 62, Quad: 1, Time: 4 ms + 143902 [246410][E](PTable): New Entry Processed in 35 ms + 143903 [246410][E](PTable): Power Buffer Reset + 143904 [250644][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 156, Cad 78, HR 167, Gear 11, Res 44, Current Pos 13200, Target Pos 13200 + 143905 [252706][E](PTable): Averaged Entry: watts=148.500000, cad=79.000000, targetPosition=1320.000000, (4)(5) + 143906 [252708][E](PTData): Cleaned 238 readings + 143907 [252718][E](PTData): Existing entry averaged (4)(5)(1317), readings(3) + 143908 [252719][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 143909 [252733][E](PTData): Fit Valid: 1, N: 62, Quad: 1, Time: 4 ms + 143910 [252740][E](PTable): New Entry Processed in 34 ms + 143911 [252741][E](PTable): Power Buffer Reset + 143912 [256652][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 171, Cad 82, HR 166, Gear 11, Res 44, Current Pos 13200, Target Pos 13200 + 143913 [259034][E](PTable): Averaged Entry: watts=165.399994, cad=81.699997, targetPosition=1320.000000, (4)(6) + 143914 [259036][E](PTData): Cleaned 238 readings + 143915 [259046][E](PTData): Existing entry averaged (4)(6)(1373), readings(12) + 143916 [259047][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 143917 [259061][E](PTData): Fit Valid: 1, N: 62, Quad: 1, Time: 4 ms + 143918 [259068][E](PTable): New Entry Processed in 35 ms + 143919 [259069][E](PTable): Power Buffer Reset + 143920 [262664][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 169, Cad 87, HR 163, Gear 11, Res 44, Current Pos 13200, Target Pos 13200 + 143921 [265358][E](PTable): Averaged Entry: watts=179.100006, cad=87.099998, targetPosition=1320.000000, (5)(6) + 143922 [265359][E](PTData): Cleaned 238 readings + 143923 [265369][E](PTData): Existing entry averaged (5)(6)(1329), readings(11) + 143924 [265370][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 143925 [265385][E](PTData): Fit Valid: 1, N: 62, Quad: 1, Time: 5 ms + 143926 [265392][E](PTable): New Entry Processed in 35 ms + 143927 [265392][E](PTable): Power Buffer Reset + 143928 [268676][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 180, Cad 87, HR 159, Gear 11, Res 44, Current Pos 13200, Target Pos 13200 + 143929 [271712][E](PTable): Averaged Entry: watts=179.300003, cad=87.099998, targetPosition=1320.000000, (5)(6) + 143930 [271713][E](PTData): Cleaned 238 readings + 143931 [271723][E](PTData): Existing entry averaged (5)(6)(1328), readings(12) + 143932 [271724][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 143933 [271739][E](PTData): Fit Valid: 1, N: 62, Quad: 1, Time: 5 ms + 143934 [271746][E](PTable): New Entry Processed in 35 ms + 143935 [271746][E](PTable): Power Buffer Reset + 143936 [273830][E](PTable): Using detected travel limits during homing + 143937 [274688][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 188, Cad 89, HR 157, Gear 11, Res 44, Current Pos 13200, Target Pos 13200 + 143938 [278064][E](PTable): Averaged Entry: watts=184.199997, cad=88.000000, targetPosition=1320.000000, (6)(6) + 143939 [278066][E](PTData): Cleaned 238 readings + 143940 [278076][E](PTData): Existing entry averaged (6)(6)(1267), readings(19) + 143941 [278077][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 143942 [278092][E](PTData): Fit Valid: 1, N: 62, Quad: 1, Time: 5 ms + 143943 [278098][E](PTable): New Entry Processed in 34 ms + 143944 [278099][E](PTable): Power Buffer Reset + 143945 [280704][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 162, Cad 84, HR 155, Gear 11, Res 44, Current Pos 13200, Target Pos 13200 + 143946 [281303][E](FTMS_SERVER): 11 00 00 f7 ff 28 33 -> Sim Mode Incline -0.090000. Responding: 80 11 01 + 143947 [281310][E](DirConManager): Sending response message type 0x04 to client 0 + 143948 [282304][E](FTMS_SERVER): 11 00 00 f0 ff 28 33 -> Sim Mode Incline -0.160000. Responding: 80 11 01 + 143949 [282310][E](DirConManager): Sending response message type 0x04 to client 0 + 143950 [283215][E](FTMS_SERVER): 11 00 00 ff ff 28 33 -> Sim Mode Incline -0.010000. Responding: 80 11 01 + 143951 [283223][E](DirConManager): Sending response message type 0x04 to client 0 + 143952 [284140][E](FTMS_SERVER): 11 00 00 96 00 28 33 -> Sim Mode Incline 1.500000. Responding: 80 11 01 + 143953 [284147][E](DirConManager): Sending response message type 0x04 to client 0 + 143954 [284410][E](PTable): Averaged Entry: watts=167.399994, cad=85.099998, targetPosition=1318.300049, (5)(6) + 143955 [284412][E](PTData): Cleaned 238 readings + 143956 [284422][E](PTData): Existing entry averaged (5)(6)(1327), readings(13) + 143957 [284423][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 143958 [284438][E](PTData): Fit Valid: 1, N: 62, Quad: 1, Time: 4 ms + 143959 [284446][E](PTable): New Entry Processed in 36 ms + 143960 [284447][E](PTable): Power Buffer Reset + 143961 [285159][E](FTMS_SERVER): 11 00 00 b9 00 28 33 -> Sim Mode Incline 1.850000. Responding: 80 11 01 + 143962 [285167][E](DirConManager): Sending response message type 0x04 to client 0 + 143963 [286109][E](FTMS_SERVER): 11 00 00 93 01 28 33 -> Sim Mode Incline 4.030000. Responding: 80 11 01 + 143964 [286118][E](DirConManager): Sending response message type 0x04 to client 0 + 143965 [286715][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 175, Cad 85, HR 154, Gear 11, Res 49, Current Pos 15043, Target Pos 16021 + 143966 [287104][E](FTMS_SERVER): 11 00 00 70 02 28 33 -> Sim Mode Incline 6.240000. Responding: 80 11 01 + 143967 [287111][E](DirConManager): Sending response message type 0x04 to client 0 + 143968 [287925][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 143969 [287926][E](PTable): Power Buffer Reset + 143970 [288034][E](FTMS_SERVER): 11 00 00 27 02 28 33 -> Sim Mode Incline 5.510000. Responding: 80 11 01 + 143971 [288039][E](DirConManager): Sending response message type 0x04 to client 0 + 143972 [288965][E](FTMS_SERVER): 11 00 00 0c 02 28 33 -> Sim Mode Incline 5.240000. Responding: 80 11 01 + 143973 [288969][E](DirConManager): Sending response message type 0x04 to client 0 + 143974 [289968][E](FTMS_SERVER): 11 00 00 fe 01 28 33 -> Sim Mode Incline 5.100000. Responding: 80 11 01 + 143975 [289976][E](DirConManager): Sending response message type 0x04 to client 0 + 143976 [290142][E](Main): Shift +1 pos 12 tgt 17970 min 0 max 29356 r_min -2000 r_max 2000 + 143977 [290657][E](Main): Shift +1 pos 13 tgt 19170 min 0 max 29356 r_min -2000 r_max 2000 + 143978 [290915][E](FTMS_SERVER): 11 00 00 f6 01 28 33 -> Sim Mode Incline 5.020000. Responding: 80 11 01 + 143979 [290923][E](DirConManager): Sending response message type 0x04 to client 0 + 143980 [291612][E](Main): Shift +1 pos 14 tgt 20314 min 0 max 29356 r_min -2000 r_max 2000 + 143981 [291818][E](FTMS_SERVER): 11 00 00 f1 01 28 33 -> Sim Mode Incline 4.970000. Responding: 80 11 01 + 143982 [291825][E](DirConManager): Sending response message type 0x04 to client 0 + 143983 [292728][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 298, Cad 77, HR 153, Gear 14, Res 69, Current Pos 20279, Target Pos 20279 + 143984 [292742][E](FTMS_SERVER): 11 00 00 da 01 28 33 -> Sim Mode Incline 4.740000. Responding: 80 11 01 + 143985 [292747][E](DirConManager): Sending response message type 0x04 to client 0 + 143986 [292859][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 143987 [292860][E](PTable): Power Buffer Reset + 143988 [293662][E](FTMS_SERVER): 11 00 00 be 01 28 33 -> Sim Mode Incline 4.460000. Responding: 80 11 01 + 143989 [293666][E](DirConManager): Sending response message type 0x04 to client 0 + 143990 [293839][E](Main): Shift +1 pos 15 tgt 21122 min 0 max 29356 r_min -2000 r_max 2000 + 143991 [294595][E](Main): Shift +1 pos 16 tgt 22322 min 0 max 29356 r_min -2000 r_max 2000 + 143992 [294693][E](FTMS_SERVER): 11 00 00 af 01 28 33 -> Sim Mode Incline 4.310000. Responding: 80 11 01 + 143993 [294699][E](DirConManager): Sending response message type 0x04 to client 0 + 143994 [295145][E](Main): Shift +1 pos 17 tgt 23417 min 0 max 29356 r_min -2000 r_max 2000 + 143995 [295685][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 143996 [295686][E](PTable): Power Buffer Reset + 143997 [295736][E](FTMS_SERVER): 11 00 00 a7 01 28 33 -> Sim Mode Incline 4.230000. Responding: 80 11 01 + 143998 [295741][E](DirConManager): Sending response message type 0x04 to client 0 + 143999 [296634][E](FTMS_SERVER): 11 00 00 a5 01 28 33 -> Sim Mode Incline 4.210000. Responding: 80 11 01 + 144000 [296640][E](DirConManager): Sending response message type 0x04 to client 0 + 144001 [297552][E](FTMS_SERVER): 11 00 00 a9 01 28 33 -> Sim Mode Incline 4.250000. Responding: 80 11 01 + 144002 [297560][E](DirConManager): Sending response message type 0x04 to client 0 + 144003 [298472][E](FTMS_SERVER): 11 00 00 b4 01 28 33 -> Sim Mode Incline 4.360000. Responding: 80 11 01 + 144004 [298479][E](DirConManager): Sending response message type 0x04 to client 0 + 144005 [298744][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 690, Cad 80, HR 154, Gear 17, Res 79, Current Pos 23449, Target Pos 23452 + 144006 [299435][E](FTMS_SERVER): 11 00 00 ce 01 28 33 -> Sim Mode Incline 4.620000. Responding: 80 11 01 + 144007 [299441][E](DirConManager): Sending response message type 0x04 to client 0 + 144008 [300435][E](FTMS_SERVER): 11 00 00 1b 02 28 33 -> Sim Mode Incline 5.390000. Responding: 80 11 01 + 144009 [300441][E](DirConManager): Sending response message type 0x04 to client 0 + 144010 [301353][E](FTMS_SERVER): 11 00 00 7d 01 28 33 -> Sim Mode Incline 3.810000. Responding: 80 11 01 + 144011 [301361][E](DirConManager): Sending response message type 0x04 to client 0 + 144012 [302042][E](PTable): Averaged Entry: watts=633.299988, cad=78.800003, targetPosition=2352.800049, (4)(21) + 144013 [302044][E](PTData): Cleaned 238 readings + 144014 [302054][E](PTData): New entry recorded (4)(21)(2352) + 144015 [302055][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144016 [302069][E](PTData): Fit Valid: 1, N: 63, Quad: 1, Time: 4 ms + 144017 [302076][E](PTable): New Entry Processed in 35 ms + 144018 [302077][E](PTable): Power Buffer Reset + 144019 [302261][E](FTMS_SERVER): 11 00 00 b0 00 28 33 -> Sim Mode Incline 1.760000. Responding: 80 11 01 + 144020 [302269][E](DirConManager): Sending response message type 0x04 to client 0 + 144021 [303278][E](FTMS_SERVER): 11 00 00 5e 00 28 33 -> Sim Mode Incline 0.940000. Responding: 80 11 01 + 144022 [303285][E](DirConManager): Sending response message type 0x04 to client 0 + 144023 [304235][E](Main): Shift -1 pos 16 tgt 19858 min 0 max 29356 r_min -2000 r_max 2000 + 144024 [304241][E](FTMS_SERVER): 11 00 00 35 00 28 33 -> Sim Mode Incline 0.530000. Responding: 80 11 01 + 144025 [304248][E](DirConManager): Sending response message type 0x04 to client 0 + 144026 [304759][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 589, Cad 78, HR 158, Gear 16, Res 71, Current Pos 20618, Target Pos 19571 + 144027 [305029][E](Main): Shift -1 pos 15 tgt 18371 min 0 max 29356 r_min -2000 r_max 2000 + 144028 [305237][E](FTMS_SERVER): 11 00 00 29 00 28 33 -> Sim Mode Incline 0.410000. Responding: 80 11 01 + 144029 [305242][E](DirConManager): Sending response message type 0x04 to client 0 + 144030 [305576][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 144031 [305577][E](PTable): Power Buffer Reset + 144032 [306085][E](Main): Shift -1 pos 14 tgt 17087 min 0 max 29356 r_min -2000 r_max 2000 + 144033 [306162][E](FTMS_SERVER): 11 00 00 36 00 28 33 -> Sim Mode Incline 0.540000. Responding: 80 11 01 + 144034 [306168][E](DirConManager): Sending response message type 0x04 to client 0 + 144035 [307176][E](Main): Shift -1 pos 13 tgt 15978 min 0 max 29356 r_min -2000 r_max 2000 + 144036 [307192][E](FTMS_SERVER): 11 00 00 1a 00 28 33 -> Sim Mode Incline 0.260000. Responding: 80 11 01 + 144037 [307198][E](DirConManager): Sending response message type 0x04 to client 0 + 144038 [308146][E](FTMS_SERVER): 11 00 00 07 00 28 33 -> Sim Mode Incline 0.070000. Responding: 80 11 01 + 144039 [308154][E](DirConManager): Sending response message type 0x04 to client 0 + 144040 [308637][E](Main): Shift -1 pos 12 tgt 14449 min 0 max 29356 r_min -2000 r_max 2000 + 144041 [309029][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 144042 [309036][E](DirConManager): Sending response message type 0x04 to client 0 + 144043 [309802][E](PTable): Using detected travel limits during homing + 144044 [309943][E](FTMS_SERVER): 11 00 00 fe ff 28 33 -> Sim Mode Incline -0.020000. Responding: 80 11 01 + 144045 [309948][E](DirConManager): Sending response message type 0x04 to client 0 + 144046 [310775][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 150, Cad 53, HR 157, Gear 12, Res 49, Current Pos 14386, Target Pos 14386 + 144047 [310860][E](FTMS_SERVER): 11 00 00 fc ff 28 33 -> Sim Mode Incline -0.040000. Responding: 80 11 01 + 144048 [310867][E](DirConManager): Sending response message type 0x04 to client 0 + 144049 [311885][E](FTMS_SERVER): 11 00 00 fb ff 28 33 -> Sim Mode Incline -0.050000. Responding: 80 11 01 + 144050 [311893][E](DirConManager): Sending response message type 0x04 to client 0 + 144051 [311928][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 144052 [311928][E](PTable): Power Buffer Reset + 144053 [314342][E](FTMS_SERVER): 11 00 00 fc ff 28 33 -> Sim Mode Incline -0.040000. Responding: 80 11 01 + 144054 [314350][E](DirConManager): Sending response message type 0x04 to client 0 + 144055 [315254][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 144056 [315261][E](DirConManager): Sending response message type 0x04 to client 0 + 144057 [316283][E](FTMS_SERVER): 11 00 00 02 00 28 33 -> Sim Mode Incline 0.020000. Responding: 80 11 01 + 144058 [316291][E](DirConManager): Sending response message type 0x04 to client 0 + 144059 [316789][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 159, Cad 68, HR 162, Gear 12, Res 49, Current Pos 14414, Target Pos 14414 + 144060 [317241][E](FTMS_SERVER): 11 00 00 04 00 28 33 -> Sim Mode Incline 0.040000. Responding: 80 11 01 + 144061 [317249][E](DirConManager): Sending response message type 0x04 to client 0 + 144062 [318268][E](PTable): Averaged Entry: watts=153.300003, cad=66.199997, targetPosition=1438.599976, (1)(5) + 144063 [318269][E](PTData): Cleaned 237 readings + 144064 [318279][E](PTData): New entry recorded (1)(5)(1438) + 144065 [318280][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144066 [318295][E](PTData): Fit Valid: 1, N: 64, Quad: 1, Time: 5 ms + 144067 [318302][E](PTable): New Entry Processed in 35 ms + 144068 [318302][E](PTable): Power Buffer Reset + 144069 [318948][E](FTMS_SERVER): 11 00 00 01 00 28 33 -> Sim Mode Incline 0.010000. Responding: 80 11 01 + 144070 [318955][E](DirConManager): Sending response message type 0x04 to client 0 + 144071 [319887][E](FTMS_SERVER): 11 00 00 fd ff 28 33 -> Sim Mode Incline -0.030000. Responding: 80 11 01 + 144072 [319892][E](DirConManager): Sending response message type 0x04 to client 0 + 144073 [320803][E](FTMS_SERVER): 11 00 00 f5 ff 28 33 -> Sim Mode Incline -0.110000. Responding: 80 11 01 + 144074 [320807][E](DirConManager): Sending response message type 0x04 to client 0 + 144075 [321830][E](FTMS_SERVER): 11 00 00 e9 ff 28 33 -> Sim Mode Incline -0.230000. Responding: 80 11 01 + 144076 [321834][E](DirConManager): Sending response message type 0x04 to client 0 + 144077 [322754][E](FTMS_SERVER): 11 00 00 e6 ff 28 33 -> Sim Mode Incline -0.260000. Responding: 80 11 01 + 144078 [322762][E](DirConManager): Sending response message type 0x04 to client 0 + 144079 [322805][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 140, Cad 67, HR 164, Gear 12, Res 48, Current Pos 14235, Target Pos 14218 + 144080 [323666][E](FTMS_SERVER): 11 00 00 ec ff 28 33 -> Sim Mode Incline -0.200000. Responding: 80 11 01 + 144081 [323674][E](DirConManager): Sending response message type 0x04 to client 0 + 144082 [324578][E](FTMS_SERVER): 11 00 00 f5 ff 28 33 -> Sim Mode Incline -0.110000. Responding: 80 11 01 + 144083 [324584][E](DirConManager): Sending response message type 0x04 to client 0 + 144084 [324616][E](PTable): Averaged Entry: watts=143.199997, cad=68.599998, targetPosition=1432.099976, (2)(5) + 144085 [324618][E](PTData): Cleaned 236 readings + 144086 [324628][E](PTData): Existing entry averaged (2)(5)(1372), readings(8) + 144087 [324629][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144088 [324644][E](PTData): Fit Valid: 1, N: 64, Quad: 1, Time: 5 ms + 144089 [324650][E](PTable): New Entry Processed in 34 ms + 144090 [324651][E](PTable): Power Buffer Reset + 144091 [325615][E](FTMS_SERVER): 11 00 00 15 00 28 33 -> Sim Mode Incline 0.210000. Responding: 80 11 01 + 144092 [325621][E](DirConManager): Sending response message type 0x04 to client 0 + 144093 [326554][E](FTMS_SERVER): 11 00 00 45 01 28 33 -> Sim Mode Incline 3.250000. Responding: 80 11 01 + 144094 [326560][E](DirConManager): Sending response message type 0x04 to client 0 + 144095 [327555][E](FTMS_SERVER): 11 00 00 ae 01 28 33 -> Sim Mode Incline 4.300000. Responding: 80 11 01 + 144096 [327562][E](DirConManager): Sending response message type 0x04 to client 0 + 144097 [328148][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 144098 [328149][E](PTable): Power Buffer Reset + 144099 [328473][E](FTMS_SERVER): 11 00 00 cd 01 28 33 -> Sim Mode Incline 4.610000. Responding: 80 11 01 + 144100 [328481][E](DirConManager): Sending response message type 0x04 to client 0 + 144101 [328822][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 164, Cad 66, HR 164, Gear 12, Res 59, Current Pos 17571, Target Pos 17627 + 144102 [329399][E](FTMS_SERVER): 11 00 00 d2 01 28 33 -> Sim Mode Incline 4.660000. Responding: 80 11 01 + 144103 [329406][E](DirConManager): Sending response message type 0x04 to client 0 + 144104 [330410][E](FTMS_SERVER): 11 00 00 ca 01 28 33 -> Sim Mode Incline 4.580000. Responding: 80 11 01 + 144105 [330417][E](DirConManager): Sending response message type 0x04 to client 0 + 144106 [331360][E](FTMS_SERVER): 11 00 00 b5 01 28 33 -> Sim Mode Incline 4.370000. Responding: 80 11 01 + 144107 [331368][E](DirConManager): Sending response message type 0x04 to client 0 + 144108 [332296][E](FTMS_SERVER): 11 00 00 94 01 28 33 -> Sim Mode Incline 4.040000. Responding: 80 11 01 + 144109 [332301][E](DirConManager): Sending response message type 0x04 to client 0 + 144110 [333186][E](FTMS_SERVER): 11 00 00 58 01 28 33 -> Sim Mode Incline 3.440000. Responding: 80 11 01 + 144111 [333194][E](DirConManager): Sending response message type 0x04 to client 0 + 144112 [334095][E](FTMS_SERVER): 11 00 00 ef 00 28 33 -> Sim Mode Incline 2.390000. Responding: 80 11 01 + 144113 [334102][E](DirConManager): Sending response message type 0x04 to client 0 + 144114 [334492][E](PTable): Averaged Entry: watts=194.600006, cad=63.200001, targetPosition=1736.300049, (1)(6) + 144115 [334493][E](PTData): Cleaned 236 readings + 144116 [334503][E](PTData): New entry recorded (1)(6)(1736) + 144117 [334504][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 144118 [334515][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 144119 [334519][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 144120 [334526][E](PTable): New Entry Processed in 35 ms + 144121 [334527][E](PTable): Power Buffer Reset + 144122 [334839][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 214, Cad 60, HR 164, Gear 12, Res 56, Current Pos 16166, Target Pos 16073 + 144123 [335063][E](FTMS_SERVER): 11 00 00 75 00 28 33 -> Sim Mode Incline 1.170000. Responding: 80 11 01 + 144124 [335070][E](DirConManager): Sending response message type 0x04 to client 0 + 144125 [336063][E](FTMS_SERVER): 11 00 00 f8 ff 28 33 -> Sim Mode Incline -0.080000. Responding: 80 11 01 + 144126 [336070][E](DirConManager): Sending response message type 0x04 to client 0 + 144127 [336985][E](FTMS_SERVER): 11 00 00 cc ff 28 33 -> Sim Mode Incline -0.520000. Responding: 80 11 01 + 144128 [336990][E](DirConManager): Sending response message type 0x04 to client 0 + 144129 [337894][E](FTMS_SERVER): 11 00 00 cb ff 28 33 -> Sim Mode Incline -0.530000. Responding: 80 11 01 + 144130 [337901][E](DirConManager): Sending response message type 0x04 to client 0 + 144131 [338916][E](FTMS_SERVER): 11 00 00 ef ff 28 33 -> Sim Mode Incline -0.170000. Responding: 80 11 01 + 144132 [338924][E](DirConManager): Sending response message type 0x04 to client 0 + 144133 [339886][E](FTMS_SERVER): 11 00 00 20 00 28 33 -> Sim Mode Incline 0.320000. Responding: 80 11 01 + 144134 [339892][E](DirConManager): Sending response message type 0x04 to client 0 + 144135 [340833][E](PTable): Averaged Entry: watts=174.899994, cad=63.000000, targetPosition=1476.400024, (1)(6) + 144136 [340834][E](PTData): Cleaned 236 readings + 144137 [340844][E](PTData): New entry recorded (1)(6)(1476) + 144138 [340845][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144139 [340860][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144140 [340867][E](PTable): New Entry Processed in 35 ms + 144141 [340868][E](PTable): Power Buffer Reset + 144142 [340872][E](FTMS_SERVER): 11 00 00 32 00 28 33 -> Sim Mode Incline 0.500000. Responding: 80 11 01 + 144143 [340889][E](DirConManager): Sending response message type 0x04 to client 0 + 144144 [340891][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 144, Cad 68, HR 162, Gear 12, Res 49, Current Pos 14624, Target Pos 14624 + 144145 [341780][E](FTMS_SERVER): 11 00 00 34 00 28 33 -> Sim Mode Incline 0.520000. Responding: 80 11 01 + 144146 [341786][E](DirConManager): Sending response message type 0x04 to client 0 + 144147 [342713][E](FTMS_SERVER): 11 00 00 30 00 28 33 -> Sim Mode Incline 0.480000. Responding: 80 11 01 + 144148 [342718][E](DirConManager): Sending response message type 0x04 to client 0 + 144149 [343740][E](FTMS_SERVER): 11 00 00 26 00 28 33 -> Sim Mode Incline 0.380000. Responding: 80 11 01 + 144150 [343745][E](DirConManager): Sending response message type 0x04 to client 0 + 144151 [344754][E](FTMS_SERVER): 11 00 00 12 00 28 33 -> Sim Mode Incline 0.180000. Responding: 80 11 01 + 144152 [344762][E](DirConManager): Sending response message type 0x04 to client 0 + 144153 [345679][E](FTMS_SERVER): 11 00 00 fa ff 28 33 -> Sim Mode Incline -0.060000. Responding: 80 11 01 + 144154 [345687][E](DirConManager): Sending response message type 0x04 to client 0 + 144155 [345771][E](PTable): Using detected travel limits during homing + 144156 [346592][E](FTMS_SERVER): 11 00 00 e2 ff 28 33 -> Sim Mode Incline -0.300000. Responding: 80 11 01 + 144157 [346599][E](DirConManager): Sending response message type 0x04 to client 0 + 144158 [346910][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 162, Cad 71, HR 160, Gear 12, Res 48, Current Pos 14226, Target Pos 14190 + 144159 [347181][E](PTable): Averaged Entry: watts=154.300003, cad=69.400002, targetPosition=1459.800049, (2)(5) + 144160 [347182][E](PTData): Cleaned 235 readings + 144161 [347192][E](PTData): Existing entry averaged (2)(5)(1380), readings(9) + 144162 [347193][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144163 [347208][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144164 [347215][E](PTable): New Entry Processed in 35 ms + 144165 [347215][E](PTable): Power Buffer Reset + 144166 [347619][E](FTMS_SERVER): 11 00 00 b1 ff 28 33 -> Sim Mode Incline -0.790000. Responding: 80 11 01 + 144167 [347627][E](DirConManager): Sending response message type 0x04 to client 0 + 144168 [348642][E](FTMS_SERVER): 11 00 00 3c ff 28 33 -> Sim Mode Incline -1.960000. Responding: 80 11 01 + 144169 [348650][E](DirConManager): Sending response message type 0x04 to client 0 + 144170 [349588][E](FTMS_SERVER): 11 00 00 07 ff 28 33 -> Sim Mode Incline -2.490000. Responding: 80 11 01 + 144171 [349595][E](DirConManager): Sending response message type 0x04 to client 0 + 144172 [350588][E](FTMS_SERVER): 11 00 00 fd fe 28 33 -> Sim Mode Incline -2.590000. Responding: 80 11 01 + 144173 [350593][E](DirConManager): Sending response message type 0x04 to client 0 + 144174 [351527][E](FTMS_SERVER): 11 00 00 fb fe 28 33 -> Sim Mode Incline -2.610000. Responding: 80 11 01 + 144175 [351535][E](DirConManager): Sending response message type 0x04 to client 0 + 144176 [352545][E](FTMS_SERVER): 11 00 00 01 ff 28 33 -> Sim Mode Incline -2.550000. Responding: 80 11 01 + 144177 [352554][E](DirConManager): Sending response message type 0x04 to client 0 + 144178 [352920][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 126, Cad 81, HR 158, Gear 12, Res 42, Current Pos 12615, Target Pos 12615 + 144179 [353498][E](FTMS_SERVER): 11 00 00 7b ff 28 33 -> Sim Mode Incline -1.330000. Responding: 80 11 01 + 144180 [353505][E](DirConManager): Sending response message type 0x04 to client 0 + 144181 [353537][E](PTable): Averaged Entry: watts=160.000000, cad=76.000000, targetPosition=1310.300049, (3)(5) + 144182 [353539][E](PTData): Cleaned 235 readings + 144183 [353549][E](PTData): Existing entry averaged (3)(5)(1316), readings(2) + 144184 [353549][E](PTData): Greater Down Found 4, 5, tp1317 + 144185 [353561][E](PTable): New Entry Processed in 24 ms + 144186 [353561][E](PTable): Power Buffer Reset + 144187 [354502][E](FTMS_SERVER): 11 00 00 e8 ff 28 33 -> Sim Mode Incline -0.240000. Responding: 80 11 01 + 144188 [354510][E](DirConManager): Sending response message type 0x04 to client 0 + 144189 [355281][E](Main): Shift +1 pos 13 tgt 15432 min 0 max 29356 r_min -2000 r_max 2000 + 144190 [355418][E](FTMS_SERVER): 11 00 00 1b 00 28 33 -> Sim Mode Incline 0.270000. Responding: 80 11 01 + 144191 [355426][E](DirConManager): Sending response message type 0x04 to client 0 + 144192 [356320][E](FTMS_SERVER): 11 00 00 3a 00 28 33 -> Sim Mode Incline 0.580000. Responding: 80 11 01 + 144193 [356326][E](DirConManager): Sending response message type 0x04 to client 0 + 144194 [356358][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 144195 [356359][E](PTable): Power Buffer Reset + 144196 [357342][E](FTMS_SERVER): 11 00 00 41 00 28 33 -> Sim Mode Incline 0.650000. Responding: 80 11 01 + 144197 [357346][E](DirConManager): Sending response message type 0x04 to client 0 + 144198 [357519][E](Main): Shift -1 pos 12 tgt 14855 min 0 max 29356 r_min -2000 r_max 2000 + 144199 [358382][E](FTMS_SERVER): 11 00 00 28 00 28 33 -> Sim Mode Incline 0.400000. Responding: 80 11 01 + 144200 [358388][E](DirConManager): Sending response message type 0x04 to client 0 + 144201 [358934][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 204, Cad 77, HR 156, Gear 12, Res 50, Current Pos 14681, Target Pos 14680 + 144202 [359402][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 144203 [359407][E](DirConManager): Sending response message type 0x04 to client 0 + 144204 [362716][E](PTable): Averaged Entry: watts=193.399994, cad=76.900002, targetPosition=1497.099976, (3)(6) + 144205 [362717][E](PTData): Existing entry averaged (3)(6)(1463), readings(4) + 144206 [362728][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144207 [362732][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 144208 [362750][E](PTable): New Entry Processed in 35 ms + 144209 [362750][E](PTable): Power Buffer Reset + 144210 [363305][E](FTMS_SERVER): 11 00 00 01 00 28 33 -> Sim Mode Incline 0.010000. Responding: 80 11 01 + 144211 [363312][E](DirConManager): Sending response message type 0x04 to client 0 + 144212 [364205][E](FTMS_SERVER): 11 00 00 02 00 28 33 -> Sim Mode Incline 0.020000. Responding: 80 11 01 + 144213 [364211][E](DirConManager): Sending response message type 0x04 to client 0 + 144214 [364950][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 168, Cad 75, HR 152, Gear 12, Res 49, Current Pos 14414, Target Pos 14414 + 144215 [365953][E](FTMS_SERVER): 11 00 00 01 00 28 33 -> Sim Mode Incline 0.010000. Responding: 80 11 01 + 144216 [365960][E](DirConManager): Sending response message type 0x04 to client 0 + 144217 [366906][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 144218 [366913][E](DirConManager): Sending response message type 0x04 to client 0 + 144219 [367909][E](FTMS_SERVER): 11 00 00 fe ff 28 33 -> Sim Mode Incline -0.020000. Responding: 80 11 01 + 144220 [367915][E](DirConManager): Sending response message type 0x04 to client 0 + 144221 [368826][E](FTMS_SERVER): 11 00 00 fb ff 28 33 -> Sim Mode Incline -0.050000. Responding: 80 11 01 + 144222 [368831][E](DirConManager): Sending response message type 0x04 to client 0 + 144223 [369063][E](PTable): Averaged Entry: watts=160.000000, cad=72.800003, targetPosition=1439.599976, (2)(5) + 144224 [369065][E](PTData): Cleaned 235 readings + 144225 [369075][E](PTData): Existing entry averaged (2)(5)(1385), readings(10) + 144226 [369076][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144227 [369091][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144228 [369097][E](PTable): New Entry Processed in 34 ms + 144229 [369098][E](PTable): Power Buffer Reset + 144230 [369741][E](FTMS_SERVER): 11 00 00 f8 ff 28 33 -> Sim Mode Incline -0.080000. Responding: 80 11 01 + 144231 [369748][E](DirConManager): Sending response message type 0x04 to client 0 + 144232 [370776][E](FTMS_SERVER): 11 00 00 f7 ff 28 33 -> Sim Mode Incline -0.090000. Responding: 80 11 01 + 144233 [370784][E](DirConManager): Sending response message type 0x04 to client 0 + 144234 [370959][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 149, Cad 70, HR 149, Gear 12, Res 48, Current Pos 14337, Target Pos 14337 + 144235 [371726][E](FTMS_SERVER): 11 00 00 f6 ff 28 33 -> Sim Mode Incline -0.100000. Responding: 80 11 01 + 144236 [371733][E](DirConManager): Sending response message type 0x04 to client 0 + 144237 [372716][E](FTMS_SERVER): 11 00 00 f7 ff 28 33 -> Sim Mode Incline -0.090000. Responding: 80 11 01 + 144238 [372724][E](DirConManager): Sending response message type 0x04 to client 0 + 144239 [373624][E](FTMS_SERVER): 11 00 00 f9 ff 28 33 -> Sim Mode Incline -0.070000. Responding: 80 11 01 + 144240 [373631][E](DirConManager): Sending response message type 0x04 to client 0 + 144241 [375369][E](FTMS_SERVER): 11 00 00 fa ff 28 33 -> Sim Mode Incline -0.060000. Responding: 80 11 01 + 144242 [375376][E](DirConManager): Sending response message type 0x04 to client 0 + 144243 [375400][E](PTable): Averaged Entry: watts=150.899994, cad=69.300003, targetPosition=1434.300049, (2)(5) + 144244 [375401][E](PTData): Cleaned 235 readings + 144245 [375411][E](PTData): Existing entry averaged (2)(5)(1389), readings(11) + 144246 [375412][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144247 [375427][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 144248 [375436][E](PTable): New Entry Processed in 37 ms + 144249 [375437][E](PTable): Power Buffer Reset + 144250 [376419][E](FTMS_SERVER): 11 00 00 fb ff 28 33 -> Sim Mode Incline -0.050000. Responding: 80 11 01 + 144251 [376427][E](DirConManager): Sending response message type 0x04 to client 0 + 144252 [376972][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 159, Cad 70, HR 149, Gear 12, Res 48, Current Pos 14365, Target Pos 14365 + 144253 [377332][E](FTMS_SERVER): 11 00 00 fd ff 28 33 -> Sim Mode Incline -0.030000. Responding: 80 11 01 + 144254 [377340][E](DirConManager): Sending response message type 0x04 to client 0 + 144255 [378255][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 144256 [378260][E](DirConManager): Sending response message type 0x04 to client 0 + 144257 [379265][E](FTMS_SERVER): 11 00 00 08 00 28 33 -> Sim Mode Incline 0.080000. Responding: 80 11 01 + 144258 [379270][E](DirConManager): Sending response message type 0x04 to client 0 + 144259 [380283][E](FTMS_SERVER): 11 00 00 0c 00 28 33 -> Sim Mode Incline 0.120000. Responding: 80 11 01 + 144260 [380289][E](DirConManager): Sending response message type 0x04 to client 0 + 144261 [381303][E](FTMS_SERVER): 11 00 00 0e 00 28 33 -> Sim Mode Incline 0.140000. Responding: 80 11 01 + 144262 [381309][E](DirConManager): Sending response message type 0x04 to client 0 + 144263 [381743][E](PTable): Averaged Entry: watts=161.000000, cad=70.900002, targetPosition=1440.800049, (2)(5) + 144264 [381745][E](PTData): Cleaned 235 readings + 144265 [381755][E](PTData): Existing entry averaged (2)(5)(1392), readings(12) + 144266 [381756][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144267 [381771][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144268 [381777][E](PTable): New Entry Processed in 34 ms + 144269 [381778][E](PTable): Power Buffer Reset + 144270 [381778][E](PTable): Using detected travel limits during homing + 144271 [382344][E](FTMS_SERVER): 11 00 00 0f 00 28 33 -> Sim Mode Incline 0.150000. Responding: 80 11 01 + 144272 [382349][E](DirConManager): Sending response message type 0x04 to client 0 + 144273 [382989][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 203, Cad 73, HR 147, Gear 12, Res 49, Current Pos 14505, Target Pos 14505 + 144274 [383272][E](FTMS_SERVER): 11 00 00 10 00 28 33 -> Sim Mode Incline 0.160000. Responding: 80 11 01 + 144275 [383280][E](DirConManager): Sending response message type 0x04 to client 0 + 144276 [384272][E](FTMS_SERVER): 11 00 00 15 00 28 33 -> Sim Mode Incline 0.210000. Responding: 80 11 01 + 144277 [384280][E](DirConManager): Sending response message type 0x04 to client 0 + 144278 [385242][E](FTMS_SERVER): 11 00 00 17 00 28 33 -> Sim Mode Incline 0.230000. Responding: 80 11 01 + 144279 [385250][E](DirConManager): Sending response message type 0x04 to client 0 + 144280 [386229][E](FTMS_SERVER): 11 00 00 13 00 28 33 -> Sim Mode Incline 0.190000. Responding: 80 11 01 + 144281 [386237][E](DirConManager): Sending response message type 0x04 to client 0 + 144282 [387142][E](FTMS_SERVER): 11 00 00 09 00 28 33 -> Sim Mode Incline 0.090000. Responding: 80 11 01 + 144283 [387148][E](DirConManager): Sending response message type 0x04 to client 0 + 144284 [388110][E](PTable): Averaged Entry: watts=196.800003, cad=76.000000, targetPosition=1451.000000, (3)(7) + 144285 [388112][E](PTData): Cleaned 235 readings + 144286 [388122][E](PTData): Existing entry averaged (3)(7)(1489), readings(3) + 144287 [388123][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144288 [388138][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144289 [388144][E](PTable): New Entry Processed in 34 ms + 144290 [388145][E](PTable): Power Buffer Reset + 144291 [388170][E](FTMS_SERVER): 11 00 00 03 00 28 33 -> Sim Mode Incline 0.030000. Responding: 80 11 01 + 144292 [388175][E](DirConManager): Sending response message type 0x04 to client 0 + 144293 [388998][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 201, Cad 79, HR 147, Gear 12, Res 49, Current Pos 14421, Target Pos 14421 + 144294 [389195][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 144295 [389201][E](DirConManager): Sending response message type 0x04 to client 0 + 144296 [391657][E](FTMS_SERVER): 11 00 00 ff ff 28 33 -> Sim Mode Incline -0.010000. Responding: 80 11 01 + 144297 [391665][E](DirConManager): Sending response message type 0x04 to client 0 + 144298 [392566][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 144299 [392574][E](DirConManager): Sending response message type 0x04 to client 0 + 144300 [394461][E](PTable): Averaged Entry: watts=207.300003, cad=81.199997, targetPosition=1440.300049, (4)(7) + 144301 [394463][E](PTData): Cleaned 235 readings + 144302 [394473][E](PTData): Existing entry averaged (4)(7)(1448), readings(14) + 144303 [394474][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144304 [394489][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144305 [394496][E](PTable): New Entry Processed in 35 ms + 144306 [394496][E](PTable): Power Buffer Reset + 144307 [395007][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 196, Cad 82, HR 145, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144308 [400250][E](FTMS_SERVER): 11 00 00 ff ff 28 33 -> Sim Mode Incline -0.010000. Responding: 80 11 01 + 144309 [400257][E](DirConManager): Sending response message type 0x04 to client 0 + 144310 [400805][E](PTable): Averaged Entry: watts=210.100006, cad=82.300003, targetPosition=1439.900024, (4)(7) + 144311 [400806][E](PTData): Cleaned 235 readings + 144312 [400816][E](PTData): Existing entry averaged (4)(7)(1447), readings(15) + 144313 [400817][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144314 [400832][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 144315 [400839][E](PTable): New Entry Processed in 35 ms + 144316 [400839][E](PTable): Power Buffer Reset + 144317 [401021][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 211, Cad 82, HR 144, Gear 12, Res 49, Current Pos 14393, Target Pos 14393 + 144318 [403217][E](Main): Shift +1 pos 13 tgt 15593 min 0 max 29356 r_min -2000 r_max 2000 + 144319 [403467][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 144320 [403474][E](DirConManager): Sending response message type 0x04 to client 0 + 144321 [405991][E](FTMS_SERVER): 11 00 00 01 00 28 33 -> Sim Mode Incline 0.010000. Responding: 80 11 01 + 144322 [405999][E](DirConManager): Sending response message type 0x04 to client 0 + 144323 [407012][E](FTMS_SERVER): 11 00 00 03 00 28 33 -> Sim Mode Incline 0.030000. Responding: 80 11 01 + 144324 [407017][E](DirConManager): Sending response message type 0x04 to client 0 + 144325 [407030][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 327, Cad 87, HR 144, Gear 13, Res 53, Current Pos 15607, Target Pos 15621 + 144326 [407142][E](PTable): Averaged Entry: watts=232.500000, cad=84.400002, targetPosition=1501.900024, (5)(8) + 144327 [407143][E](PTData): Cleaned 235 readings + 144328 [407153][E](PTData): Existing entry averaged (5)(8)(1456), readings(20) + 144329 [407154][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144330 [407169][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144331 [407175][E](PTable): New Entry Processed in 34 ms + 144332 [407176][E](PTable): Power Buffer Reset + 144333 [407962][E](FTMS_SERVER): 11 00 00 07 00 28 33 -> Sim Mode Incline 0.070000. Responding: 80 11 01 + 144334 [407968][E](DirConManager): Sending response message type 0x04 to client 0 + 144335 [408971][E](FTMS_SERVER): 11 00 00 0a 00 28 33 -> Sim Mode Incline 0.100000. Responding: 80 11 01 + 144336 [408975][E](DirConManager): Sending response message type 0x04 to client 0 + 144337 [409878][E](FTMS_SERVER): 11 00 00 0c 00 28 33 -> Sim Mode Incline 0.120000. Responding: 80 11 01 + 144338 [409885][E](DirConManager): Sending response message type 0x04 to client 0 + 144339 [410803][E](FTMS_SERVER): 11 00 00 0f 00 28 33 -> Sim Mode Incline 0.150000. Responding: 80 11 01 + 144340 [410810][E](DirConManager): Sending response message type 0x04 to client 0 + 144341 [411763][E](FTMS_SERVER): 11 00 00 15 00 28 33 -> Sim Mode Incline 0.210000. Responding: 80 11 01 + 144342 [411770][E](DirConManager): Sending response message type 0x04 to client 0 + 144343 [412763][E](FTMS_SERVER): 11 00 00 1e 00 28 33 -> Sim Mode Incline 0.300000. Responding: 80 11 01 + 144344 [412770][E](DirConManager): Sending response message type 0x04 to client 0 + 144345 [413044][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 412, Cad 100, HR 144, Gear 13, Res 53, Current Pos 15810, Target Pos 15810 + 144346 [413500][E](PTable): Averaged Entry: watts=362.100006, cad=93.000000, targetPosition=1569.000000, (7)(12) + 144347 [413502][E](PTData): Cleaned 235 readings + 144348 [413512][E](PTData): New entry recorded (7)(12)(1569) + 144349 [413513][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144350 [413528][E](PTData): Fit Valid: 1, N: 66, Quad: 1, Time: 4 ms + 144351 [413535][E](PTable): New Entry Processed in 35 ms + 144352 [413535][E](PTable): Power Buffer Reset + 144353 [413667][E](FTMS_SERVER): 11 00 00 28 00 28 33 -> Sim Mode Incline 0.400000. Responding: 80 11 01 + 144354 [413672][E](DirConManager): Sending response message type 0x04 to client 0 + 144355 [414592][E](FTMS_SERVER): 11 00 00 30 00 28 33 -> Sim Mode Incline 0.480000. Responding: 80 11 01 + 144356 [414600][E](DirConManager): Sending response message type 0x04 to client 0 + 144357 [415504][E](FTMS_SERVER): 11 00 00 3c 00 28 33 -> Sim Mode Incline 0.600000. Responding: 80 11 01 + 144358 [415511][E](DirConManager): Sending response message type 0x04 to client 0 + 144359 [416478][E](FTMS_SERVER): 11 00 00 42 00 28 33 -> Sim Mode Incline 0.660000. Responding: 80 11 01 + 144360 [416487][E](DirConManager): Sending response message type 0x04 to client 0 + 144361 [417479][E](FTMS_SERVER): 11 00 00 43 00 28 33 -> Sim Mode Incline 0.670000. Responding: 80 11 01 + 144362 [417487][E](DirConManager): Sending response message type 0x04 to client 0 + 144363 [417751][E](PTable): Using detected travel limits during homing + 144364 [418373][E](FTMS_SERVER): 11 00 00 42 00 28 33 -> Sim Mode Incline 0.660000. Responding: 80 11 01 + 144365 [418378][E](DirConManager): Sending response message type 0x04 to client 0 + 144366 [419057][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 393, Cad 99, HR 144, Gear 13, Res 54, Current Pos 16062, Target Pos 16062 + 144367 [419302][E](FTMS_SERVER): 11 00 00 40 00 28 33 -> Sim Mode Incline 0.640000. Responding: 80 11 01 + 144368 [419309][E](DirConManager): Sending response message type 0x04 to client 0 + 144369 [419871][E](PTable): Averaged Entry: watts=403.700012, cad=100.800003, targetPosition=1599.400024, (8)(13) + 144370 [419873][E](PTData): Cleaned 234 readings + 144371 [419883][E](PTData): New entry recorded (8)(13)(1599) + 144372 [419884][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144373 [419899][E](PTData): Fit Valid: 1, N: 67, Quad: 1, Time: 5 ms + 144374 [419906][E](PTable): New Entry Processed in 35 ms + 144375 [419906][E](PTable): Power Buffer Reset + 144376 [420331][E](FTMS_SERVER): 11 00 00 3b 00 28 33 -> Sim Mode Incline 0.590000. Responding: 80 11 01 + 144377 [420338][E](DirConManager): Sending response message type 0x04 to client 0 + 144378 [421271][E](FTMS_SERVER): 11 00 00 32 00 28 33 -> Sim Mode Incline 0.500000. Responding: 80 11 01 + 144379 [421279][E](DirConManager): Sending response message type 0x04 to client 0 + 144380 [421422][E](Main): Shift -1 pos 12 tgt 14750 min 0 max 29356 r_min -2000 r_max 2000 + 144381 [422184][E](FTMS_SERVER): 11 00 00 24 00 28 33 -> Sim Mode Incline 0.360000. Responding: 80 11 01 + 144382 [422192][E](DirConManager): Sending response message type 0x04 to client 0 + 144383 [423104][E](FTMS_SERVER): 11 00 00 13 00 28 33 -> Sim Mode Incline 0.190000. Responding: 80 11 01 + 144384 [423110][E](DirConManager): Sending response message type 0x04 to client 0 + 144385 [424022][E](FTMS_SERVER): 11 00 00 05 00 28 33 -> Sim Mode Incline 0.050000. Responding: 80 11 01 + 144386 [424030][E](DirConManager): Sending response message type 0x04 to client 0 + 144387 [425042][E](FTMS_SERVER): 11 00 00 fe ff 28 33 -> Sim Mode Incline -0.020000. Responding: 80 11 01 + 144388 [425050][E](DirConManager): Sending response message type 0x04 to client 0 + 144389 [425073][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 284, Cad 84, HR 147, Gear 12, Res 49, Current Pos 14434, Target Pos 14386 + 144390 [425976][E](FTMS_SERVER): 11 00 00 fb ff 28 33 -> Sim Mode Incline -0.050000. Responding: 80 11 01 + 144391 [425984][E](DirConManager): Sending response message type 0x04 to client 0 + 144392 [426223][E](PTable): Averaged Entry: watts=318.299988, cad=90.000000, targetPosition=1502.199951, (6)(11) + 144393 [426224][E](PTData): Cleaned 233 readings + 144394 [426234][E](PTData): Existing entry averaged (6)(11)(1549), readings(6) + 144395 [426235][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144396 [426250][E](PTData): Fit Valid: 1, N: 67, Quad: 1, Time: 5 ms + 144397 [426259][E](PTable): New Entry Processed in 37 ms + 144398 [426260][E](PTable): Power Buffer Reset + 144399 [426884][E](FTMS_SERVER): 11 00 00 fa ff 28 33 -> Sim Mode Incline -0.060000. Responding: 80 11 01 + 144400 [426890][E](DirConManager): Sending response message type 0x04 to client 0 + 144401 [427793][E](FTMS_SERVER): 11 00 00 fe ff 28 33 -> Sim Mode Incline -0.020000. Responding: 80 11 01 + 144402 [427798][E](DirConManager): Sending response message type 0x04 to client 0 + 144403 [428728][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 144404 [428735][E](DirConManager): Sending response message type 0x04 to client 0 + 144405 [431091][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 239, Cad 91, HR 152, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144406 [432579][E](PTable): Averaged Entry: watts=261.700012, cad=92.400002, targetPosition=1438.500000, (6)(9) + 144407 [432581][E](PTData): Cleaned 233 readings + 144408 [432591][E](PTData): Existing entry averaged (6)(9)(1442), readings(18) + 144409 [432592][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144410 [432607][E](PTData): Fit Valid: 1, N: 67, Quad: 1, Time: 4 ms + 144411 [432615][E](PTable): New Entry Processed in 36 ms + 144412 [432615][E](PTable): Power Buffer Reset + 144413 [437101][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 206, Cad 84, HR 156, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144414 [438923][E](PTable): Averaged Entry: watts=211.600006, cad=84.900002, targetPosition=1440.000000, (5)(7) + 144415 [438924][E](PTData): Cleaned 233 readings + 144416 [438934][E](PTData): Existing entry averaged (5)(7)(1401), readings(13) + 144417 [438935][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144418 [438951][E](PTData): Fit Valid: 1, N: 67, Quad: 1, Time: 6 ms + 144419 [438958][E](PTable): New Entry Processed in 36 ms + 144420 [438959][E](PTable): Power Buffer Reset + 144421 [443117][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 177, Cad 77, HR 158, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144422 [445265][E](PTable): Averaged Entry: watts=184.699997, cad=77.500000, targetPosition=1440.000000, (3)(6) + 144423 [445266][E](PTData): Cleaned 233 readings + 144424 [445276][E](PTData): Existing entry averaged (3)(6)(1459), readings(5) + 144425 [445277][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144426 [445292][E](PTData): Fit Valid: 1, N: 67, Quad: 1, Time: 5 ms + 144427 [445299][E](PTable): New Entry Processed in 35 ms + 144428 [445299][E](PTable): Power Buffer Reset + 144429 [447669][E](FTMS_SERVER): 11 00 00 17 00 28 33 -> Sim Mode Incline 0.230000. Responding: 80 11 01 + 144430 [447674][E](DirConManager): Sending response message type 0x04 to client 0 + 144431 [448687][E](FTMS_SERVER): 11 00 00 23 00 28 33 -> Sim Mode Incline 0.350000. Responding: 80 11 01 + 144432 [448693][E](DirConManager): Sending response message type 0x04 to client 0 + 144433 [449141][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 178, Cad 76, HR 160, Gear 12, Res 49, Current Pos 14645, Target Pos 14645 + 144434 [449721][E](FTMS_SERVER): 11 00 00 25 00 28 33 -> Sim Mode Incline 0.370000. Responding: 80 11 01 + 144435 [449726][E](DirConManager): Sending response message type 0x04 to client 0 + 144436 [450637][E](FTMS_SERVER): 11 00 00 1f 00 28 33 -> Sim Mode Incline 0.310000. Responding: 80 11 01 + 144437 [450644][E](DirConManager): Sending response message type 0x04 to client 0 + 144438 [451613][E](PTable): Averaged Entry: watts=178.399994, cad=74.900002, targetPosition=1452.300049, (3)(6) + 144439 [451615][E](PTData): Cleaned 233 readings + 144440 [451625][E](PTData): Existing entry averaged (3)(6)(1458), readings(6) + 144441 [451626][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144442 [451641][E](PTData): Fit Valid: 1, N: 67, Quad: 1, Time: 4 ms + 144443 [451648][E](PTable): New Entry Processed in 35 ms + 144444 [451648][E](PTable): Power Buffer Reset + 144445 [451673][E](FTMS_SERVER): 11 00 00 13 00 28 33 -> Sim Mode Incline 0.190000. Responding: 80 11 01 + 144446 [451680][E](DirConManager): Sending response message type 0x04 to client 0 + 144447 [452625][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 144448 [452633][E](DirConManager): Sending response message type 0x04 to client 0 + 144449 [453618][E](FTMS_SERVER): 11 00 00 f3 ff 28 33 -> Sim Mode Incline -0.130000. Responding: 80 11 01 + 144450 [453625][E](DirConManager): Sending response message type 0x04 to client 0 + 144451 [453729][E](PTable): Using detected travel limits during homing + 144452 [454523][E](FTMS_SERVER): 11 00 00 e2 ff 28 33 -> Sim Mode Incline -0.300000. Responding: 80 11 01 + 144453 [454530][E](DirConManager): Sending response message type 0x04 to client 0 + 144454 [455150][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 155, Cad 71, HR 158, Gear 12, Res 48, Current Pos 14190, Target Pos 14190 + 144455 [455449][E](FTMS_SERVER): 11 00 00 c9 ff 28 33 -> Sim Mode Incline -0.550000. Responding: 80 11 01 + 144456 [455454][E](DirConManager): Sending response message type 0x04 to client 0 + 144457 [456487][E](FTMS_SERVER): 11 00 00 9b ff 28 33 -> Sim Mode Incline -1.010000. Responding: 80 11 01 + 144458 [456491][E](DirConManager): Sending response message type 0x04 to client 0 + 144459 [457515][E](FTMS_SERVER): 11 00 00 76 ff 28 33 -> Sim Mode Incline -1.380000. Responding: 80 11 01 + 144460 [457520][E](DirConManager): Sending response message type 0x04 to client 0 + 144461 [457975][E](PTable): Averaged Entry: watts=159.300003, cad=71.400002, targetPosition=1414.900024, (2)(5) + 144462 [457976][E](PTData): Cleaned 233 readings + 144463 [457986][E](PTData): Existing entry averaged (2)(5)(1393), readings(13) + 144464 [457987][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144465 [458002][E](PTData): Fit Valid: 1, N: 67, Quad: 1, Time: 5 ms + 144466 [458009][E](PTable): New Entry Processed in 35 ms + 144467 [458009][E](PTable): Power Buffer Reset + 144468 [458534][E](FTMS_SERVER): 11 00 00 61 ff 28 33 -> Sim Mode Incline -1.590000. Responding: 80 11 01 + 144469 [458542][E](DirConManager): Sending response message type 0x04 to client 0 + 144470 [459450][E](FTMS_SERVER): 11 00 00 5d ff 28 33 -> Sim Mode Incline -1.630000. Responding: 80 11 01 + 144471 [459458][E](DirConManager): Sending response message type 0x04 to client 0 + 144472 [460467][E](FTMS_SERVER): 11 00 00 66 ff 28 33 -> Sim Mode Incline -1.540000. Responding: 80 11 01 + 144473 [460475][E](DirConManager): Sending response message type 0x04 to client 0 + 144474 [461160][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 123, Cad 71, HR 155, Gear 12, Res 45, Current Pos 13322, Target Pos 13322 + 144475 [461435][E](FTMS_SERVER): 11 00 00 82 ff 28 33 -> Sim Mode Incline -1.260000. Responding: 80 11 01 + 144476 [461442][E](DirConManager): Sending response message type 0x04 to client 0 + 144477 [462426][E](FTMS_SERVER): 11 00 00 b1 ff 28 33 -> Sim Mode Incline -0.790000. Responding: 80 11 01 + 144478 [462433][E](DirConManager): Sending response message type 0x04 to client 0 + 144479 [463330][E](FTMS_SERVER): 11 00 00 f3 ff 28 33 -> Sim Mode Incline -0.130000. Responding: 80 11 01 + 144480 [463335][E](DirConManager): Sending response message type 0x04 to client 0 + 144481 [464258][E](FTMS_SERVER): 11 00 00 74 00 28 33 -> Sim Mode Incline 1.160000. Responding: 80 11 01 + 144482 [464265][E](DirConManager): Sending response message type 0x04 to client 0 + 144483 [464328][E](PTable): Averaged Entry: watts=127.900002, cad=69.800003, targetPosition=1355.599976, (2)(4) + 144484 [464330][E](PTData): Cleaned 233 readings + 144485 [464340][E](PTData): New entry recorded (2)(4)(1355) + 144486 [464340][E](PTData): Lower Up Found 1, 4, tp1319 + 144487 [464342][E](PTable): New Entry Processed in 14 ms + 144488 [464353][E](PTable): Power Buffer Reset + 144489 [465184][E](FTMS_SERVER): 11 00 00 e1 00 28 33 -> Sim Mode Incline 2.250000. Responding: 80 11 01 + 144490 [465191][E](DirConManager): Sending response message type 0x04 to client 0 + 144491 [466134][E](FTMS_SERVER): 11 00 00 30 01 28 33 -> Sim Mode Incline 3.040000. Responding: 80 11 01 + 144492 [466140][E](DirConManager): Sending response message type 0x04 to client 0 + 144493 [467131][E](FTMS_SERVER): 11 00 00 60 01 28 33 -> Sim Mode Incline 3.520000. Responding: 80 11 01 + 144494 [467138][E](DirConManager): Sending response message type 0x04 to client 0 + 144495 [467171][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 142, Cad 66, HR 155, Gear 12, Res 56, Current Pos 16530, Target Pos 16864 + 144496 [468037][E](FTMS_SERVER): 11 00 00 6c 01 28 33 -> Sim Mode Incline 3.640000. Responding: 80 11 01 + 144497 [468043][E](DirConManager): Sending response message type 0x04 to client 0 + 144498 [468978][E](FTMS_SERVER): 11 00 00 5a 01 28 33 -> Sim Mode Incline 3.460000. Responding: 80 11 01 + 144499 [468983][E](DirConManager): Sending response message type 0x04 to client 0 + 144500 [469991][E](FTMS_SERVER): 11 00 00 2d 01 28 33 -> Sim Mode Incline 3.010000. Responding: 80 11 01 + 144501 [469999][E](DirConManager): Sending response message type 0x04 to client 0 + 144502 [470676][E](PTable): Averaged Entry: watts=151.399994, cad=64.699997, targetPosition=1624.199951, (1)(5) + 144503 [470677][E](PTData): Cleaned 1 readings + 144504 [470687][E](PTData): Existing entry averaged (1)(5)(1500), readings(2) + 144505 [470687][E](PTData): Lower Right Found 1, 6, tp1476 + 144506 [470699][E](PTable): New Entry Processed in 24 ms + 144507 [470699][E](PTable): Power Buffer Reset + 144508 [470933][E](FTMS_SERVER): 11 00 00 dd 00 28 33 -> Sim Mode Incline 2.210000. Responding: 80 11 01 + 144509 [470941][E](DirConManager): Sending response message type 0x04 to client 0 + 144510 [471838][E](FTMS_SERVER): 11 00 00 7f 00 28 33 -> Sim Mode Incline 1.270000. Responding: 80 11 01 + 144511 [471845][E](DirConManager): Sending response message type 0x04 to client 0 + 144512 [472766][E](FTMS_SERVER): 11 00 00 4e 00 28 33 -> Sim Mode Incline 0.780000. Responding: 80 11 01 + 144513 [472771][E](DirConManager): Sending response message type 0x04 to client 0 + 144514 [473184][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 186, Cad 59, HR 154, Gear 12, Res 51, Current Pos 15045, Target Pos 14946 + 144515 [473684][E](FTMS_SERVER): 11 00 00 29 00 28 33 -> Sim Mode Incline 0.410000. Responding: 80 11 01 + 144516 [473690][E](DirConManager): Sending response message type 0x04 to client 0 + 144517 [474702][E](FTMS_SERVER): 11 00 00 0d 00 28 33 -> Sim Mode Incline 0.130000. Responding: 80 11 01 + 144518 [474709][E](DirConManager): Sending response message type 0x04 to client 0 + 144519 [475649][E](FTMS_SERVER): 11 00 00 fc ff 28 33 -> Sim Mode Incline -0.040000. Responding: 80 11 01 + 144520 [475660][E](DirConManager): Sending response message type 0x04 to client 0 + 144521 [476652][E](FTMS_SERVER): 11 00 00 f4 ff 28 33 -> Sim Mode Incline -0.120000. Responding: 80 11 01 + 144522 [476660][E](DirConManager): Sending response message type 0x04 to client 0 + 144523 [477028][E](PTable): Averaged Entry: watts=172.800003, cad=61.500000, targetPosition=1509.500000, (0)(6) + 144524 [477029][E](PTData): Cleaned 1 readings + 144525 [477039][E](PTData): Existing entry averaged (0)(6)(1648), readings(6) + 144526 [477040][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144527 [477055][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 144528 [477062][E](PTable): New Entry Processed in 35 ms + 144529 [477062][E](PTable): Power Buffer Reset + 144530 [477571][E](FTMS_SERVER): 11 00 00 ef ff 28 33 -> Sim Mode Incline -0.170000. Responding: 80 11 01 + 144531 [477579][E](DirConManager): Sending response message type 0x04 to client 0 + 144532 [478584][E](FTMS_SERVER): 11 00 00 ed ff 28 33 -> Sim Mode Incline -0.190000. Responding: 80 11 01 + 144533 [478591][E](DirConManager): Sending response message type 0x04 to client 0 + 144534 [479195][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 143, Cad 67, HR 152, Gear 12, Res 48, Current Pos 14267, Target Pos 14267 + 144535 [480247][E](FTMS_SERVER): 11 00 00 f0 ff 28 33 -> Sim Mode Incline -0.160000. Responding: 80 11 01 + 144536 [480254][E](DirConManager): Sending response message type 0x04 to client 0 + 144537 [481168][E](FTMS_SERVER): 11 00 00 f7 ff 28 33 -> Sim Mode Incline -0.090000. Responding: 80 11 01 + 144538 [481173][E](DirConManager): Sending response message type 0x04 to client 0 + 144539 [482085][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 144540 [482090][E](DirConManager): Sending response message type 0x04 to client 0 + 144541 [483374][E](PTable): Averaged Entry: watts=142.100006, cad=66.800003, targetPosition=1430.699951, (1)(5) + 144542 [483375][E](PTData): Cleaned 235 readings + 144543 [483385][E](PTData): Existing entry averaged (1)(5)(1435), readings(2) + 144544 [483386][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144545 [483401][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144546 [483408][E](PTable): New Entry Processed in 35 ms + 144547 [483545][E](PTable): Writing File: /PowerTable.txt + 144548 [483777][E](PTable): Power table saved successfully with 658 readings + 144549 [483777][E](PTable): Power Buffer Reset + 144550 [485204][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 129, Cad 65, HR 150, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144551 [489705][E](PTable): Averaged Entry: watts=131.800003, cad=65.400002, targetPosition=1440.000000, (1)(4) + 144552 [489706][E](PTData): Cleaned 235 readings + 144553 [489716][E](PTData): New entry recorded (1)(4)(1440) + 144554 [489716][E](PTData): Lower Right Found 1, 5, tp1435 + 144555 [489718][E](PTable): New Entry Processed in 14 ms + 144556 [489728][E](PTable): Power Buffer Reset + 144557 [489729][E](PTable): Using detected travel limits during homing + 144558 [491222][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 145, Cad 67, HR 148, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144559 [496049][E](PTable): Averaged Entry: watts=150.100006, cad=69.000000, targetPosition=1440.000000, (2)(5) + 144560 [496050][E](PTData): Existing entry averaged (2)(5)(1396), readings(14) + 144561 [496061][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144562 [496065][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 144563 [496082][E](PTable): New Entry Processed in 34 ms + 144564 [496083][E](PTable): Power Buffer Reset + 144565 [497236][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 155, Cad 70, HR 145, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144566 [502396][E](PTable): Averaged Entry: watts=178.300003, cad=73.699997, targetPosition=1440.000000, (3)(6) + 144567 [502397][E](PTData): Cleaned 235 readings + 144568 [502407][E](PTData): Existing entry averaged (3)(6)(1455), readings(7) + 144569 [502408][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144570 [502423][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144571 [502430][E](PTable): New Entry Processed in 35 ms + 144572 [502430][E](PTable): Power Buffer Reset + 144573 [503252][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 218, Cad 81, HR 143, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144574 [508739][E](PTable): Averaged Entry: watts=210.300003, cad=81.900002, targetPosition=1440.000000, (4)(7) + 144575 [508741][E](PTData): Cleaned 235 readings + 144576 [508751][E](PTData): Existing entry averaged (4)(7)(1446), readings(16) + 144577 [508752][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144578 [508766][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 144579 [508773][E](PTable): New Entry Processed in 34 ms + 144580 [508774][E](PTable): Power Buffer Reset + 144581 [509265][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 194, Cad 81, HR 140, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144582 [509328][E](FTMS_SERVER): 11 00 00 ea ff 28 33 -> Sim Mode Incline -0.220000. Responding: 80 11 01 + 144583 [509336][E](DirConManager): Sending response message type 0x04 to client 0 + 144584 [510334][E](FTMS_SERVER): 11 00 00 c3 ff 28 33 -> Sim Mode Incline -0.610000. Responding: 80 11 01 + 144585 [510342][E](DirConManager): Sending response message type 0x04 to client 0 + 144586 [511292][E](FTMS_SERVER): 11 00 00 d8 ff 28 33 -> Sim Mode Incline -0.400000. Responding: 80 11 01 + 144587 [511299][E](DirConManager): Sending response message type 0x04 to client 0 + 144588 [512283][E](FTMS_SERVER): 11 00 00 cd 00 28 33 -> Sim Mode Incline 2.050000. Responding: 80 11 01 + 144589 [512290][E](DirConManager): Sending response message type 0x04 to client 0 + 144590 [513202][E](FTMS_SERVER): 11 00 00 e2 01 28 33 -> Sim Mode Incline 4.820000. Responding: 80 11 01 + 144591 [513210][E](DirConManager): Sending response message type 0x04 to client 0 + 144592 [514123][E](FTMS_SERVER): 11 00 00 44 02 28 33 -> Sim Mode Incline 5.800000. Responding: 80 11 01 + 144593 [514128][E](DirConManager): Sending response message type 0x04 to client 0 + 144594 [514382][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 144595 [514383][E](PTable): Power Buffer Reset + 144596 [515163][E](FTMS_SERVER): 11 00 00 54 02 28 33 -> Sim Mode Incline 5.960000. Responding: 80 11 01 + 144597 [515168][E](DirConManager): Sending response message type 0x04 to client 0 + 144598 [515282][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 187, Cad 81, HR 140, Gear 12, Res 62, Current Pos 18482, Target Pos 18572 + 144599 [516182][E](FTMS_SERVER): 11 00 00 4b 02 28 33 -> Sim Mode Incline 5.870000. Responding: 80 11 01 + 144600 [516188][E](DirConManager): Sending response message type 0x04 to client 0 + 144601 [517203][E](FTMS_SERVER): 11 00 00 2f 02 28 33 -> Sim Mode Incline 5.590000. Responding: 80 11 01 + 144602 [517209][E](DirConManager): Sending response message type 0x04 to client 0 + 144603 [518119][E](FTMS_SERVER): 11 00 00 fb 01 28 33 -> Sim Mode Incline 5.070000. Responding: 80 11 01 + 144604 [518126][E](DirConManager): Sending response message type 0x04 to client 0 + 144605 [519040][E](FTMS_SERVER): 11 00 00 a2 01 28 33 -> Sim Mode Incline 4.180000. Responding: 80 11 01 + 144606 [519048][E](DirConManager): Sending response message type 0x04 to client 0 + 144607 [519994][E](FTMS_SERVER): 11 00 00 0c 01 28 33 -> Sim Mode Incline 2.680000. Responding: 80 11 01 + 144608 [520002][E](DirConManager): Sending response message type 0x04 to client 0 + 144609 [520760][E](PTable): Averaged Entry: watts=223.000000, cad=67.500000, targetPosition=1804.500000, (1)(7) + 144610 [520762][E](PTData): Cleaned 235 readings + 144611 [520772][E](PTData): New entry recorded (1)(7)(1804) + 144612 [520773][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 144613 [520784][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 144614 [520788][E](PTData): Fit Valid: 1, N: 66, Quad: 1, Time: 4 ms + 144615 [520795][E](PTable): New Entry Processed in 35 ms + 144616 [520795][E](PTable): Power Buffer Reset + 144617 [520999][E](FTMS_SERVER): 11 00 00 74 00 28 33 -> Sim Mode Incline 1.160000. Responding: 80 11 01 + 144618 [521006][E](DirConManager): Sending response message type 0x04 to client 0 + 144619 [521290][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 246, Cad 59, HR 141, Gear 12, Res 56, Current Pos 16105, Target Pos 15212 + 144620 [521921][E](FTMS_SERVER): 11 00 00 fa ff 28 33 -> Sim Mode Incline -0.060000. Responding: 80 11 01 + 144621 [521926][E](DirConManager): Sending response message type 0x04 to client 0 + 144622 [522828][E](FTMS_SERVER): 11 00 00 d0 ff 28 33 -> Sim Mode Incline -0.480000. Responding: 80 11 01 + 144623 [522835][E](DirConManager): Sending response message type 0x04 to client 0 + 144624 [523860][E](FTMS_SERVER): 11 00 00 c5 ff 28 33 -> Sim Mode Incline -0.590000. Responding: 80 11 01 + 144625 [523868][E](DirConManager): Sending response message type 0x04 to client 0 + 144626 [524813][E](FTMS_SERVER): 11 00 00 d9 ff 28 33 -> Sim Mode Incline -0.390000. Responding: 80 11 01 + 144627 [524820][E](DirConManager): Sending response message type 0x04 to client 0 + 144628 [525699][E](PTable): Using detected travel limits during homing + 144629 [525803][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 144630 [525810][E](DirConManager): Sending response message type 0x04 to client 0 + 144631 [527102][E](PTable): Averaged Entry: watts=199.500000, cad=66.199997, targetPosition=1461.099976, (1)(7) + 144632 [527103][E](PTData): Cleaned 235 readings + 144633 [527113][E](PTData): New entry recorded (1)(7)(1461) + 144634 [527113][E](PTData): Greater Down Found 3, 7, tp1489 + 144635 [527115][E](PTable): New Entry Processed in 14 ms + 144636 [527126][E](PTable): Power Buffer Reset + 144637 [527308][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 140, Cad 69, HR 141, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144638 [533317][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 130, Cad 64, HR 141, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144639 [533429][E](PTable): Averaged Entry: watts=137.000000, cad=67.000000, targetPosition=1440.000000, (1)(5) + 144640 [533431][E](PTData): Existing entry averaged (1)(5)(1436), readings(2) + 144641 [533442][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144642 [533446][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 144643 [533464][E](PTable): New Entry Processed in 35 ms + 144644 [533464][E](PTable): Power Buffer Reset + 144645 [539330][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 130, Cad 63, HR 142, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144646 [539766][E](PTable): Averaged Entry: watts=125.900002, cad=62.700001, targetPosition=1440.000000, (0)(4) + 144647 [539767][E](PTData): Cleaned 235 readings + 144648 [539777][E](PTData): Existing entry averaged (0)(4)(1420), readings(4) + 144649 [539778][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144650 [539793][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144651 [539800][E](PTable): New Entry Processed in 34 ms + 144652 [539800][E](PTable): Power Buffer Reset + 144653 [540244][E](FTMS_SERVER): 11 00 00 f4 ff 28 33 -> Sim Mode Incline -0.120000. Responding: 80 11 01 + 144654 [540249][E](DirConManager): Sending response message type 0x04 to client 0 + 144655 [541160][E](FTMS_SERVER): 11 00 00 ec ff 28 33 -> Sim Mode Incline -0.200000. Responding: 80 11 01 + 144656 [541167][E](DirConManager): Sending response message type 0x04 to client 0 + 144657 [542186][E](FTMS_SERVER): 11 00 00 ea ff 28 33 -> Sim Mode Incline -0.220000. Responding: 80 11 01 + 144658 [542193][E](DirConManager): Sending response message type 0x04 to client 0 + 144659 [543136][E](FTMS_SERVER): 11 00 00 f0 ff 28 33 -> Sim Mode Incline -0.160000. Responding: 80 11 01 + 144660 [543144][E](DirConManager): Sending response message type 0x04 to client 0 + 144661 [544138][E](FTMS_SERVER): 11 00 00 fe ff 28 33 -> Sim Mode Incline -0.020000. Responding: 80 11 01 + 144662 [544146][E](DirConManager): Sending response message type 0x04 to client 0 + 144663 [545046][E](FTMS_SERVER): 11 00 00 21 00 28 33 -> Sim Mode Incline 0.330000. Responding: 80 11 01 + 144664 [545054][E](DirConManager): Sending response message type 0x04 to client 0 + 144665 [545357][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 134, Cad 66, HR 142, Gear 12, Res 49, Current Pos 14525, Target Pos 14631 + 144666 [545967][E](FTMS_SERVER): 11 00 00 5c 00 28 33 -> Sim Mode Incline 0.920000. Responding: 80 11 01 + 144667 [545973][E](DirConManager): Sending response message type 0x04 to client 0 + 144668 [546139][E](PTable): Averaged Entry: watts=135.399994, cad=64.800003, targetPosition=1436.500000, (1)(5) + 144669 [546140][E](PTData): Cleaned 235 readings + 144670 [546150][E](PTData): Existing entry averaged (1)(5)(1436), readings(3) + 144671 [546151][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144672 [546167][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 6 ms + 144673 [546174][E](PTable): New Entry Processed in 36 ms + 144674 [546174][E](PTable): Power Buffer Reset + 144675 [547000][E](FTMS_SERVER): 11 00 00 c8 00 28 33 -> Sim Mode Incline 2.000000. Responding: 80 11 01 + 144676 [547005][E](DirConManager): Sending response message type 0x04 to client 0 + 144677 [548012][E](FTMS_SERVER): 11 00 00 52 01 28 33 -> Sim Mode Incline 3.380000. Responding: 80 11 01 + 144678 [548016][E](DirConManager): Sending response message type 0x04 to client 0 + 144679 [549059][E](FTMS_SERVER): 11 00 00 9d 01 28 33 -> Sim Mode Incline 4.130000. Responding: 80 11 01 + 144680 [549064][E](DirConManager): Sending response message type 0x04 to client 0 + 144681 [549965][E](FTMS_SERVER): 11 00 00 a6 01 28 33 -> Sim Mode Incline 4.220000. Responding: 80 11 01 + 144682 [549972][E](DirConManager): Sending response message type 0x04 to client 0 + 144683 [550992][E](FTMS_SERVER): 11 00 00 7f 01 28 33 -> Sim Mode Incline 3.830000. Responding: 80 11 01 + 144684 [551000][E](DirConManager): Sending response message type 0x04 to client 0 + 144685 [551375][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 169, Cad 61, HR 141, Gear 12, Res 59, Current Pos 17156, Target Pos 17081 + 144686 [551943][E](FTMS_SERVER): 11 00 00 2b 01 28 33 -> Sim Mode Incline 2.990000. Responding: 80 11 01 + 144687 [551951][E](DirConManager): Sending response message type 0x04 to client 0 + 144688 [552944][E](FTMS_SERVER): 11 00 00 bc 00 28 33 -> Sim Mode Incline 1.880000. Responding: 80 11 01 + 144689 [552952][E](DirConManager): Sending response message type 0x04 to client 0 + 144690 [553865][E](FTMS_SERVER): 11 00 00 41 00 28 33 -> Sim Mode Incline 0.650000. Responding: 80 11 01 + 144691 [553870][E](DirConManager): Sending response message type 0x04 to client 0 + 144692 [554790][E](FTMS_SERVER): 11 00 00 e0 ff 28 33 -> Sim Mode Incline -0.320000. Responding: 80 11 01 + 144693 [554795][E](DirConManager): Sending response message type 0x04 to client 0 + 144694 [555807][E](FTMS_SERVER): 11 00 00 b3 ff 28 33 -> Sim Mode Incline -0.770000. Responding: 80 11 01 + 144695 [555812][E](DirConManager): Sending response message type 0x04 to client 0 + 144696 [556745][E](FTMS_SERVER): 11 00 00 92 ff 28 33 -> Sim Mode Incline -1.100000. Responding: 80 11 01 + 144697 [556752][E](DirConManager): Sending response message type 0x04 to client 0 + 144698 [557388][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 140, Cad 60, HR 138, Gear 12, Res 46, Current Pos 13630, Target Pos 13630 + 144699 [557429][E](PTable): Averaged Entry: watts=149.699997, cad=65.000000, targetPosition=1607.900024, (1)(5) + 144700 [557430][E](PTData): Cleaned 235 readings + 144701 [557441][E](PTData): Existing entry averaged (1)(5)(1470), readings(4) + 144702 [557442][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 144703 [557452][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 144704 [557467][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144705 [557475][E](PTable): New Entry Processed in 46 ms + 144706 [557475][E](PTable): Power Buffer Reset + 144707 [557649][E](FTMS_SERVER): 11 00 00 7e ff 28 33 -> Sim Mode Incline -1.300000. Responding: 80 11 01 + 144708 [557656][E](DirConManager): Sending response message type 0x04 to client 0 + 144709 [558565][E](FTMS_SERVER): 11 00 00 71 ff 28 33 -> Sim Mode Incline -1.430000. Responding: 80 11 01 + 144710 [558571][E](DirConManager): Sending response message type 0x04 to client 0 + 144711 [559493][E](FTMS_SERVER): 11 00 00 6a ff 28 33 -> Sim Mode Incline -1.500000. Responding: 80 11 01 + 144712 [559498][E](DirConManager): Sending response message type 0x04 to client 0 + 144713 [560520][E](FTMS_SERVER): 11 00 00 69 ff 28 33 -> Sim Mode Incline -1.510000. Responding: 80 11 01 + 144714 [560525][E](DirConManager): Sending response message type 0x04 to client 0 + 144715 [561546][E](FTMS_SERVER): 11 00 00 74 ff 28 33 -> Sim Mode Incline -1.400000. Responding: 80 11 01 + 144716 [561554][E](DirConManager): Sending response message type 0x04 to client 0 + 144717 [561658][E](PTable): Using detected travel limits during homing + 144718 [562457][E](FTMS_SERVER): 11 00 00 92 ff 28 33 -> Sim Mode Incline -1.100000. Responding: 80 11 01 + 144719 [562464][E](DirConManager): Sending response message type 0x04 to client 0 + 144720 [563374][E](FTMS_SERVER): 11 00 00 d0 ff 28 33 -> Sim Mode Incline -0.480000. Responding: 80 11 01 + 144721 [563380][E](DirConManager): Sending response message type 0x04 to client 0 + 144722 [563403][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 106, Cad 65, HR 135, Gear 12, Res 46, Current Pos 13631, Target Pos 14064 + 144723 [563771][E](PTable): Averaged Entry: watts=118.099998, cad=63.599998, targetPosition=1347.199951, (1)(4) + 144724 [563773][E](PTData): Cleaned 236 readings + 144725 [563783][E](PTData): New entry recorded (1)(4)(1347) + 144726 [563784][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144727 [563799][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144728 [563806][E](PTable): New Entry Processed in 35 ms + 144729 [563806][E](PTable): Power Buffer Reset + 144730 [564408][E](FTMS_SERVER): 11 00 00 15 00 28 33 -> Sim Mode Incline 0.210000. Responding: 80 11 01 + 144731 [564416][E](DirConManager): Sending response message type 0x04 to client 0 + 144732 [565358][E](FTMS_SERVER): 11 00 00 5f 00 28 33 -> Sim Mode Incline 0.950000. Responding: 80 11 01 + 144733 [565366][E](DirConManager): Sending response message type 0x04 to client 0 + 144734 [566362][E](FTMS_SERVER): 11 00 00 6b 00 28 33 -> Sim Mode Incline 1.070000. Responding: 80 11 01 + 144735 [566370][E](DirConManager): Sending response message type 0x04 to client 0 + 144736 [567273][E](FTMS_SERVER): 11 00 00 3d 00 28 33 -> Sim Mode Incline 0.610000. Responding: 80 11 01 + 144737 [567280][E](DirConManager): Sending response message type 0x04 to client 0 + 144738 [568190][E](FTMS_SERVER): 11 00 00 ee ff 28 33 -> Sim Mode Incline -0.180000. Responding: 80 11 01 + 144739 [568197][E](DirConManager): Sending response message type 0x04 to client 0 + 144740 [569212][E](FTMS_SERVER): 11 00 00 a8 ff 28 33 -> Sim Mode Incline -0.880000. Responding: 80 11 01 + 144741 [569220][E](DirConManager): Sending response message type 0x04 to client 0 + 144742 [569417][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 135, Cad 61, HR 133, Gear 12, Res 48, Current Pos 14214, Target Pos 13784 + 144743 [570123][E](PTable): Averaged Entry: watts=121.699997, cad=63.500000, targetPosition=1451.300049, (1)(4) + 144744 [570125][E](PTData): Cleaned 235 readings + 144745 [570135][E](PTData): Existing entry averaged (1)(4)(1381), readings(2) + 144746 [570136][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144747 [570151][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144748 [570158][E](PTable): New Entry Processed in 36 ms + 144749 [570158][E](PTable): Power Buffer Reset + 144750 [570163][E](FTMS_SERVER): 11 00 00 57 ff 28 33 -> Sim Mode Incline -1.690000. Responding: 80 11 01 + 144751 [570179][E](DirConManager): Sending response message type 0x04 to client 0 + 144752 [571165][E](FTMS_SERVER): 11 00 00 38 ff 28 33 -> Sim Mode Incline -2.000000. Responding: 80 11 01 + 144753 [571173][E](DirConManager): Sending response message type 0x04 to client 0 + 144754 [572087][E](FTMS_SERVER): 11 00 00 2d ff 28 33 -> Sim Mode Incline -2.110000. Responding: 80 11 01 + 144755 [572092][E](DirConManager): Sending response message type 0x04 to client 0 + 144756 [573100][E](FTMS_SERVER): 11 00 00 29 ff 28 33 -> Sim Mode Incline -2.150000. Responding: 80 11 01 + 144757 [573105][E](DirConManager): Sending response message type 0x04 to client 0 + 144758 [574140][E](FTMS_SERVER): 11 00 00 28 ff 28 33 -> Sim Mode Incline -2.160000. Responding: 80 11 01 + 144759 [574145][E](DirConManager): Sending response message type 0x04 to client 0 + 144760 [575164][E](FTMS_SERVER): 11 00 00 2c ff 28 33 -> Sim Mode Incline -2.120000. Responding: 80 11 01 + 144761 [575168][E](DirConManager): Sending response message type 0x04 to client 0 + 144762 [575433][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 101, Cad 68, HR 135, Gear 12, Res 43, Current Pos 12916, Target Pos 12916 + 144763 [576090][E](FTMS_SERVER): 11 00 00 39 ff 28 33 -> Sim Mode Incline -1.990000. Responding: 80 11 01 + 144764 [576098][E](DirConManager): Sending response message type 0x04 to client 0 + 144765 [576486][E](PTable): Averaged Entry: watts=116.699997, cad=64.599998, targetPosition=1300.400024, (1)(4) + 144766 [576487][E](PTData): Cleaned 235 readings + 144767 [576497][E](PTData): Existing entry averaged (1)(4)(1360), readings(3) + 144768 [576498][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144769 [576513][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 144770 [576520][E](PTable): New Entry Processed in 35 ms + 144771 [576521][E](PTable): Power Buffer Reset + 144772 [577103][E](FTMS_SERVER): 11 00 00 5b ff 28 33 -> Sim Mode Incline -1.650000. Responding: 80 11 01 + 144773 [577111][E](DirConManager): Sending response message type 0x04 to client 0 + 144774 [578156][E](FTMS_SERVER): 11 00 00 ae ff 28 33 -> Sim Mode Incline -0.820000. Responding: 80 11 01 + 144775 [578162][E](DirConManager): Sending response message type 0x04 to client 0 + 144776 [579264][E](FTMS_SERVER): 11 00 00 ed ff 28 33 -> Sim Mode Incline -0.190000. Responding: 80 11 01 + 144777 [579272][E](DirConManager): Sending response message type 0x04 to client 0 + 144778 [580270][E](FTMS_SERVER): 11 00 00 13 00 28 33 -> Sim Mode Incline 0.190000. Responding: 80 11 01 + 144779 [580277][E](DirConManager): Sending response message type 0x04 to client 0 + 144780 [581213][E](FTMS_SERVER): 11 00 00 2b 00 28 33 -> Sim Mode Incline 0.430000. Responding: 80 11 01 + 144781 [581220][E](DirConManager): Sending response message type 0x04 to client 0 + 144782 [581446][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 110, Cad 66, HR 133, Gear 12, Res 49, Current Pos 14612, Target Pos 14701 + 144783 [582216][E](FTMS_SERVER): 11 00 00 38 00 28 33 -> Sim Mode Incline 0.560000. Responding: 80 11 01 + 144784 [582223][E](DirConManager): Sending response message type 0x04 to client 0 + 144785 [582851][E](PTable): Averaged Entry: watts=109.099998, cad=66.400002, targetPosition=1395.000000, (1)(4) + 144786 [582852][E](PTData): Cleaned 235 readings + 144787 [582863][E](PTData): Existing entry averaged (1)(4)(1367), readings(4) + 144788 [582864][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144789 [582878][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 144790 [582885][E](PTable): New Entry Processed in 35 ms + 144791 [582886][E](PTable): Power Buffer Reset + 144792 [583169][E](FTMS_SERVER): 11 00 00 3b 00 28 33 -> Sim Mode Incline 0.590000. Responding: 80 11 01 + 144793 [583179][E](DirConManager): Sending response message type 0x04 to client 0 + 144794 [584179][E](FTMS_SERVER): 11 00 00 2a 00 28 33 -> Sim Mode Incline 0.420000. Responding: 80 11 01 + 144795 [584186][E](DirConManager): Sending response message type 0x04 to client 0 + 144796 [585089][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 144797 [585094][E](DirConManager): Sending response message type 0x04 to client 0 + 144798 [587460][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 147, Cad 67, HR 130, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144799 [589199][E](PTable): Averaged Entry: watts=144.600006, cad=65.800003, targetPosition=1455.099976, (1)(5) + 144800 [589200][E](PTData): Cleaned 235 readings + 144801 [589211][E](PTData): Existing entry averaged (1)(5)(1463), readings(5) + 144802 [589212][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144803 [589226][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 144804 [589233][E](PTable): New Entry Processed in 34 ms + 144805 [589233][E](PTable): Power Buffer Reset + 144806 [593473][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 143, Cad 68, HR 130, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144807 [595537][E](PTable): Averaged Entry: watts=145.100006, cad=68.199997, targetPosition=1440.000000, (2)(5) + 144808 [595538][E](PTData): Cleaned 235 readings + 144809 [595548][E](PTData): Existing entry averaged (2)(5)(1398), readings(15) + 144810 [595549][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144811 [595564][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144812 [595571][E](PTable): New Entry Processed in 35 ms + 144813 [595571][E](PTable): Power Buffer Reset + 144814 [597651][E](PTable): Using detected travel limits during homing + 144815 [599484][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 136, Cad 67, HR 131, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144816 [601880][E](PTable): Averaged Entry: watts=145.100006, cad=68.400002, targetPosition=1440.000000, (2)(5) + 144817 [601882][E](PTData): Cleaned 235 readings + 144818 [601892][E](PTData): Existing entry averaged (2)(5)(1400), readings(16) + 144819 [601893][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144820 [601908][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144821 [601915][E](PTable): New Entry Processed in 35 ms + 144822 [601915][E](PTable): Power Buffer Reset + 144823 [605498][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 134, Cad 66, HR 130, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144824 [608239][E](PTable): Averaged Entry: watts=135.000000, cad=65.000000, targetPosition=1440.000000, (1)(5) + 144825 [608241][E](PTData): Cleaned 235 readings + 144826 [608251][E](PTData): Existing entry averaged (1)(5)(1459), readings(6) + 144827 [608252][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144828 [608267][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144829 [608274][E](PTable): New Entry Processed in 35 ms + 144830 [608274][E](PTable): Power Buffer Reset + 144831 [608546][E](FTMS_SERVER): 11 00 00 35 00 28 33 -> Sim Mode Incline 0.530000. Responding: 80 11 01 + 144832 [608550][E](DirConManager): Sending response message type 0x04 to client 0 + 144833 [609568][E](FTMS_SERVER): 11 00 00 5e 00 28 33 -> Sim Mode Incline 0.940000. Responding: 80 11 01 + 144834 [609572][E](DirConManager): Sending response message type 0x04 to client 0 + 144835 [610585][E](FTMS_SERVER): 11 00 00 60 00 28 33 -> Sim Mode Incline 0.960000. Responding: 80 11 01 + 144836 [610592][E](DirConManager): Sending response message type 0x04 to client 0 + 144837 [611511][E](FTMS_SERVER): 11 00 00 50 00 28 33 -> Sim Mode Incline 0.800000. Responding: 80 11 01 + 144838 [611519][E](DirConManager): Sending response message type 0x04 to client 0 + 144839 [611521][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 131, Cad 63, HR 127, Gear 12, Res 51, Current Pos 15072, Target Pos 15072 + 144840 [612433][E](FTMS_SERVER): 11 00 00 37 00 28 33 -> Sim Mode Incline 0.550000. Responding: 80 11 01 + 144841 [612442][E](DirConManager): Sending response message type 0x04 to client 0 + 144842 [613446][E](FTMS_SERVER): 11 00 00 14 00 28 33 -> Sim Mode Incline 0.200000. Responding: 80 11 01 + 144843 [613453][E](DirConManager): Sending response message type 0x04 to client 0 + 144844 [614410][E](FTMS_SERVER): 11 00 00 ef ff 28 33 -> Sim Mode Incline -0.170000. Responding: 80 11 01 + 144845 [614417][E](DirConManager): Sending response message type 0x04 to client 0 + 144846 [614582][E](PTable): Averaged Entry: watts=135.899994, cad=63.299999, targetPosition=1479.400024, (1)(5) + 144847 [614583][E](PTData): Cleaned 235 readings + 144848 [614593][E](PTData): Existing entry averaged (1)(5)(1461), readings(7) + 144849 [614594][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144850 [614609][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 144851 [614616][E](PTable): New Entry Processed in 35 ms + 144852 [614616][E](PTable): Power Buffer Reset + 144853 [615505][E](FTMS_SERVER): 11 00 00 c9 ff 28 33 -> Sim Mode Incline -0.550000. Responding: 80 11 01 + 144854 [615510][E](DirConManager): Sending response message type 0x04 to client 0 + 144855 [616422][E](FTMS_SERVER): 11 00 00 8f ff 28 33 -> Sim Mode Incline -1.130000. Responding: 80 11 01 + 144856 [616426][E](DirConManager): Sending response message type 0x04 to client 0 + 144857 [617340][E](FTMS_SERVER): 11 00 00 45 ff 28 33 -> Sim Mode Incline -1.870000. Responding: 80 11 01 + 144858 [617348][E](DirConManager): Sending response message type 0x04 to client 0 + 144859 [617543][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 136, Cad 63, HR 127, Gear 12, Res 46, Current Pos 13550, Target Pos 13091 + 144860 [618303][E](FTMS_SERVER): 11 00 00 0d ff 28 33 -> Sim Mode Incline -2.430000. Responding: 80 11 01 + 144861 [618309][E](DirConManager): Sending response message type 0x04 to client 0 + 144862 [619311][E](FTMS_SERVER): 11 00 00 ec fe 28 33 -> Sim Mode Incline -2.760000. Responding: 80 11 01 + 144863 [619319][E](DirConManager): Sending response message type 0x04 to client 0 + 144864 [620210][E](FTMS_SERVER): 11 00 00 de fe 28 33 -> Sim Mode Incline -2.900000. Responding: 80 11 01 + 144865 [620217][E](DirConManager): Sending response message type 0x04 to client 0 + 144866 [620936][E](PTable): Averaged Entry: watts=126.599998, cad=63.200001, targetPosition=1333.900024, (1)(4) + 144867 [620937][E](PTData): Cleaned 235 readings + 144868 [620947][E](PTData): Existing entry averaged (1)(4)(1361), readings(5) + 144869 [620948][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144870 [620963][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 144871 [620970][E](PTable): New Entry Processed in 35 ms + 144872 [620970][E](PTable): Power Buffer Reset + 144873 [621134][E](FTMS_SERVER): 11 00 00 d8 fe 28 33 -> Sim Mode Incline -2.960000. Responding: 80 11 01 + 144874 [621139][E](DirConManager): Sending response message type 0x04 to client 0 + 144875 [622817][E](FTMS_SERVER): 11 00 00 dc fe 28 33 -> Sim Mode Incline -2.920000. Responding: 80 11 01 + 144876 [622823][E](DirConManager): Sending response message type 0x04 to client 0 + 144877 [623554][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 84, Cad 65, HR 130, Gear 12, Res 42, Current Pos 12356, Target Pos 12356 + 144878 [623811][E](FTMS_SERVER): 11 00 00 e8 fe 28 33 -> Sim Mode Incline -2.800000. Responding: 80 11 01 + 144879 [623818][E](DirConManager): Sending response message type 0x04 to client 0 + 144880 [624731][E](FTMS_SERVER): 11 00 00 00 ff 28 33 -> Sim Mode Incline -2.560000. Responding: 80 11 01 + 144881 [624736][E](DirConManager): Sending response message type 0x04 to client 0 + 144882 [625639][E](FTMS_SERVER): 11 00 00 24 ff 28 33 -> Sim Mode Incline -2.200000. Responding: 80 11 01 + 144883 [625646][E](DirConManager): Sending response message type 0x04 to client 0 + 144884 [626667][E](FTMS_SERVER): 11 00 00 35 ff 28 33 -> Sim Mode Incline -2.030000. Responding: 80 11 01 + 144885 [626675][E](DirConManager): Sending response message type 0x04 to client 0 + 144886 [627270][E](PTable): Averaged Entry: watts=91.300003, cad=65.199997, targetPosition=1252.099976, (1)(3) + 144887 [627272][E](PTData): Cleaned 235 readings + 144888 [627282][E](PTData): Existing entry averaged (1)(3)(1231), readings(6) + 144889 [627283][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144890 [627298][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144891 [627304][E](PTable): New Entry Processed in 34 ms + 144892 [627305][E](PTable): Power Buffer Reset + 144893 [627611][E](FTMS_SERVER): 11 00 00 44 ff 28 33 -> Sim Mode Incline -1.880000. Responding: 80 11 01 + 144894 [627619][E](DirConManager): Sending response message type 0x04 to client 0 + 144895 [628626][E](FTMS_SERVER): 11 00 00 51 ff 28 33 -> Sim Mode Incline -1.750000. Responding: 80 11 01 + 144896 [628633][E](DirConManager): Sending response message type 0x04 to client 0 + 144897 [629526][E](FTMS_SERVER): 11 00 00 5a ff 28 33 -> Sim Mode Incline -1.660000. Responding: 80 11 01 + 144898 [629535][E](DirConManager): Sending response message type 0x04 to client 0 + 144899 [629569][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 105, Cad 66, HR 130, Gear 12, Res 44, Current Pos 13177, Target Pos 13238 + 144900 [630449][E](FTMS_SERVER): 11 00 00 63 ff 28 33 -> Sim Mode Incline -1.570000. Responding: 80 11 01 + 144901 [630454][E](DirConManager): Sending response message type 0x04 to client 0 + 144902 [631472][E](FTMS_SERVER): 11 00 00 6c ff 28 33 -> Sim Mode Incline -1.480000. Responding: 80 11 01 + 144903 [631477][E](DirConManager): Sending response message type 0x04 to client 0 + 144904 [632504][E](FTMS_SERVER): 11 00 00 78 ff 28 33 -> Sim Mode Incline -1.360000. Responding: 80 11 01 + 144905 [632509][E](DirConManager): Sending response message type 0x04 to client 0 + 144906 [633522][E](FTMS_SERVER): 11 00 00 8b ff 28 33 -> Sim Mode Incline -1.170000. Responding: 80 11 01 + 144907 [633529][E](DirConManager): Sending response message type 0x04 to client 0 + 144908 [633621][E](PTable): Averaged Entry: watts=103.400002, cad=66.500000, targetPosition=1325.099976, (1)(3) + 144909 [633622][E](PTData): Cleaned 235 readings + 144910 [633632][E](PTData): Existing entry averaged (1)(3)(1242), readings(7) + 144911 [633633][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144912 [633648][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144913 [633655][E](PTable): New Entry Processed in 35 ms + 144914 [633655][E](PTable): Power Buffer Reset + 144915 [633656][E](PTable): Using detected travel limits during homing + 144916 [634445][E](FTMS_SERVER): 11 00 00 d2 ff 28 33 -> Sim Mode Incline -0.460000. Responding: 80 11 01 + 144917 [634451][E](DirConManager): Sending response message type 0x04 to client 0 + 144918 [635356][E](FTMS_SERVER): 11 00 00 3c 00 28 33 -> Sim Mode Incline 0.600000. Responding: 80 11 01 + 144919 [635364][E](DirConManager): Sending response message type 0x04 to client 0 + 144920 [635578][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 116, Cad 67, HR 127, Gear 12, Res 47, Current Pos 14150, Target Pos 14820 + 144921 [636321][E](FTMS_SERVER): 11 00 00 87 00 28 33 -> Sim Mode Incline 1.350000. Responding: 80 11 01 + 144922 [636328][E](DirConManager): Sending response message type 0x04 to client 0 + 144923 [637323][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 144924 [637330][E](DirConManager): Sending response message type 0x04 to client 0 + 144925 [639982][E](PTable): Averaged Entry: watts=127.000000, cad=66.099998, targetPosition=1437.400024, (1)(4) + 144926 [639984][E](PTData): Cleaned 235 readings + 144927 [639994][E](PTData): Existing entry averaged (1)(4)(1371), readings(6) + 144928 [639995][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144929 [640010][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144930 [640016][E](PTable): New Entry Processed in 34 ms + 144931 [640017][E](PTable): Power Buffer Reset + 144932 [641593][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 138, Cad 66, HR 126, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144933 [646321][E](PTable): Averaged Entry: watts=147.800003, cad=66.500000, targetPosition=1440.000000, (1)(5) + 144934 [646323][E](PTData): Cleaned 235 readings + 144935 [646333][E](PTData): Existing entry averaged (1)(5)(1458), readings(8) + 144936 [646334][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144937 [646349][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144938 [646358][E](PTable): New Entry Processed in 37 ms + 144939 [646359][E](PTable): Power Buffer Reset + 144940 [647611][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 151, Cad 69, HR 124, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144941 [649544][E](FTMS_SERVER): 11 00 00 ff ff 28 33 -> Sim Mode Incline -0.010000. Responding: 80 11 01 + 144942 [649552][E](DirConManager): Sending response message type 0x04 to client 0 + 144943 [652679][E](PTable): Averaged Entry: watts=147.399994, cad=68.099998, targetPosition=1439.500000, (2)(5) + 144944 [652681][E](PTData): Cleaned 235 readings + 144945 [652691][E](PTData): Existing entry averaged (2)(5)(1402), readings(17) + 144946 [652692][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144947 [652707][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144948 [652714][E](PTable): New Entry Processed in 35 ms + 144949 [652714][E](PTable): Power Buffer Reset + 144950 [653623][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 139, Cad 67, HR 123, Gear 12, Res 49, Current Pos 14393, Target Pos 14393 + 144951 [654243][E](FTMS_SERVER): 11 00 00 fe ff 28 33 -> Sim Mode Incline -0.020000. Responding: 80 11 01 + 144952 [654249][E](DirConManager): Sending response message type 0x04 to client 0 + 144953 [658304][E](FTMS_SERVER): 11 00 00 fd ff 28 33 -> Sim Mode Incline -0.030000. Responding: 80 11 01 + 144954 [658311][E](DirConManager): Sending response message type 0x04 to client 0 + 144955 [659030][E](PTable): Averaged Entry: watts=137.399994, cad=66.699997, targetPosition=1438.199951, (1)(5) + 144956 [659031][E](PTData): Cleaned 235 readings + 144957 [659041][E](PTData): Existing entry averaged (1)(5)(1456), readings(9) + 144958 [659042][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144959 [659057][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 144960 [659064][E](PTable): New Entry Processed in 35 ms + 144961 [659064][E](PTable): Power Buffer Reset + 144962 [659248][E](FTMS_SERVER): 11 00 00 fc ff 28 33 -> Sim Mode Incline -0.040000. Responding: 80 11 01 + 144963 [659255][E](DirConManager): Sending response message type 0x04 to client 0 + 144964 [659632][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 139, Cad 65, HR 123, Gear 12, Res 48, Current Pos 14372, Target Pos 14372 + 144965 [662494][E](FTMS_SERVER): 11 00 00 fd ff 28 33 -> Sim Mode Incline -0.030000. Responding: 80 11 01 + 144966 [662501][E](DirConManager): Sending response message type 0x04 to client 0 + 144967 [663445][E](FTMS_SERVER): 11 00 00 fe ff 28 33 -> Sim Mode Incline -0.020000. Responding: 80 11 01 + 144968 [663455][E](DirConManager): Sending response message type 0x04 to client 0 + 144969 [665163][E](FTMS_SERVER): 11 00 00 ff ff 28 33 -> Sim Mode Incline -0.010000. Responding: 80 11 01 + 144970 [665171][E](DirConManager): Sending response message type 0x04 to client 0 + 144971 [665379][E](PTable): Averaged Entry: watts=138.000000, cad=65.900002, targetPosition=1437.400024, (1)(5) + 144972 [665380][E](PTData): Cleaned 235 readings + 144973 [665391][E](PTData): Existing entry averaged (1)(5)(1454), readings(10) + 144974 [665391][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144975 [665406][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 144976 [665413][E](PTable): New Entry Processed in 35 ms + 144977 [665413][E](PTable): Power Buffer Reset + 144978 [665644][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 128, Cad 66, HR 124, Gear 12, Res 49, Current Pos 14393, Target Pos 14393 + 144979 [666086][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 144980 [666094][E](DirConManager): Sending response message type 0x04 to client 0 + 144981 [669596][E](PTable): Using detected travel limits during homing + 144982 [671659][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 140, Cad 66, HR 124, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144983 [671712][E](PTable): Averaged Entry: watts=133.399994, cad=65.699997, targetPosition=1439.800049, (1)(4) + 144984 [671713][E](PTData): Cleaned 235 readings + 144985 [671724][E](PTData): Existing entry averaged (1)(4)(1379), readings(7) + 144986 [671724][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144987 [671739][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 144988 [671746][E](PTable): New Entry Processed in 34 ms + 144989 [671746][E](PTable): Power Buffer Reset + 144990 [677676][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 138, Cad 66, HR 125, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144991 [678049][E](PTable): Averaged Entry: watts=137.199997, cad=66.599998, targetPosition=1440.000000, (1)(5) + 144992 [678051][E](PTData): Cleaned 235 readings + 144993 [678061][E](PTData): Existing entry averaged (1)(5)(1452), readings(11) + 144994 [678062][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 144995 [678077][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 144996 [678084][E](PTable): New Entry Processed in 36 ms + 144997 [678084][E](PTable): Power Buffer Reset + 144998 [683691][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 130, Cad 65, HR 125, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 144999 [684398][E](PTable): Averaged Entry: watts=132.800003, cad=65.800003, targetPosition=1440.000000, (1)(4) + 145000 [684400][E](PTData): Cleaned 235 readings + 145001 [684410][E](PTData): Existing entry averaged (1)(4)(1385), readings(8) + 145002 [684411][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145003 [684426][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145004 [684433][E](PTable): New Entry Processed in 36 ms + 145005 [684433][E](PTable): Power Buffer Reset + 145006 [689704][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 144, Cad 68, HR 125, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 145007 [690743][E](PTable): Averaged Entry: watts=137.600006, cad=66.000000, targetPosition=1440.000000, (1)(5) + 145008 [690745][E](PTData): Cleaned 235 readings + 145009 [690755][E](PTData): Existing entry averaged (1)(5)(1451), readings(12) + 145010 [690756][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145011 [690771][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145012 [690777][E](PTable): New Entry Processed in 34 ms + 145013 [690778][E](PTable): Power Buffer Reset + 145014 [695715][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 137, Cad 67, HR 125, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 145015 [697072][E](PTable): Averaged Entry: watts=146.300003, cad=68.699997, targetPosition=1440.000000, (2)(5) + 145016 [697074][E](PTData): Cleaned 235 readings + 145017 [697084][E](PTData): Existing entry averaged (2)(5)(1404), readings(18) + 145018 [697085][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145019 [697100][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145020 [697107][E](PTable): New Entry Processed in 35 ms + 145021 [697107][E](PTable): Power Buffer Reset + 145022 [701725][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 129, Cad 65, HR 127, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 145023 [703410][E](PTable): Averaged Entry: watts=133.500000, cad=65.099998, targetPosition=1440.000000, (1)(4) + 145024 [703411][E](PTData): Cleaned 235 readings + 145025 [703421][E](PTData): Existing entry averaged (1)(4)(1390), readings(9) + 145026 [703422][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145027 [703437][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145028 [703444][E](PTable): New Entry Processed in 35 ms + 145029 [703445][E](PTable): Power Buffer Reset + 145030 [705523][E](PTable): Using detected travel limits during homing + 145031 [707743][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 125, Cad 63, HR 126, Gear 12, Res 49, Current Pos 14400, Target Pos 14400 + 145032 [709754][E](PTable): Averaged Entry: watts=130.699997, cad=63.400002, targetPosition=1440.000000, (1)(4) + 145033 [709755][E](PTData): Cleaned 235 readings + 145034 [709766][E](PTData): Existing entry averaged (1)(4)(1394), readings(10) + 145035 [709766][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145036 [709781][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145037 [709788][E](PTable): New Entry Processed in 34 ms + 145038 [709788][E](PTable): Power Buffer Reset + 145039 [711358][E](FTMS_SERVER): 11 00 00 f5 ff 28 33 -> Sim Mode Incline -0.110000. Responding: 80 11 01 + 145040 [711362][E](DirConManager): Sending response message type 0x04 to client 0 + 145041 [712387][E](FTMS_SERVER): 11 00 00 ef ff 28 33 -> Sim Mode Incline -0.170000. Responding: 80 11 01 + 145042 [712392][E](DirConManager): Sending response message type 0x04 to client 0 + 145043 [713409][E](FTMS_SERVER): 11 00 00 f5 ff 28 33 -> Sim Mode Incline -0.110000. Responding: 80 11 01 + 145044 [713414][E](DirConManager): Sending response message type 0x04 to client 0 + 145045 [713758][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 135, Cad 65, HR 125, Gear 12, Res 48, Current Pos 14323, Target Pos 14323 + 145046 [714324][E](FTMS_SERVER): 11 00 00 1d 00 28 33 -> Sim Mode Incline 0.290000. Responding: 80 11 01 + 145047 [714331][E](DirConManager): Sending response message type 0x04 to client 0 + 145048 [715242][E](FTMS_SERVER): 11 00 00 ad 00 28 33 -> Sim Mode Incline 1.730000. Responding: 80 11 01 + 145049 [715250][E](DirConManager): Sending response message type 0x04 to client 0 + 145050 [716109][E](PTable): Averaged Entry: watts=135.000000, cad=64.900002, targetPosition=1450.300049, (1)(5) + 145051 [716111][E](PTData): Cleaned 235 readings + 145052 [716121][E](PTData): Existing entry averaged (1)(5)(1450), readings(13) + 145053 [716122][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145054 [716137][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145055 [716144][E](PTable): New Entry Processed in 35 ms + 145056 [716144][E](PTable): Power Buffer Reset + 145057 [716189][E](FTMS_SERVER): 11 00 00 c2 00 28 33 -> Sim Mode Incline 1.940000. Responding: 80 11 01 + 145058 [716196][E](DirConManager): Sending response message type 0x04 to client 0 + 145059 [717202][E](FTMS_SERVER): 11 00 00 aa 01 28 33 -> Sim Mode Incline 4.260000. Responding: 80 11 01 + 145060 [717212][E](DirConManager): Sending response message type 0x04 to client 0 + 145061 [718124][E](FTMS_SERVER): 11 00 00 86 02 28 33 -> Sim Mode Incline 6.460000. Responding: 80 11 01 + 145062 [718130][E](DirConManager): Sending response message type 0x04 to client 0 + 145063 [718937][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 145064 [718938][E](PTable): Power Buffer Reset + 145065 [719031][E](FTMS_SERVER): 11 00 00 2e 02 28 33 -> Sim Mode Incline 5.580000. Responding: 80 11 01 + 145066 [719038][E](DirConManager): Sending response message type 0x04 to client 0 + 145067 [719769][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 197, Cad 66, HR 124, Gear 12, Res 64, Current Pos 18703, Target Pos 18306 + 145068 [720053][E](FTMS_SERVER): 11 00 00 15 02 28 33 -> Sim Mode Incline 5.330000. Responding: 80 11 01 + 145069 [720061][E](DirConManager): Sending response message type 0x04 to client 0 + 145070 [721004][E](FTMS_SERVER): 11 00 00 06 02 28 33 -> Sim Mode Incline 5.180000. Responding: 80 11 01 + 145071 [721011][E](DirConManager): Sending response message type 0x04 to client 0 + 145072 [722004][E](FTMS_SERVER): 11 00 00 fd 01 28 33 -> Sim Mode Incline 5.090000. Responding: 80 11 01 + 145073 [722011][E](DirConManager): Sending response message type 0x04 to client 0 + 145074 [722927][E](FTMS_SERVER): 11 00 00 f7 01 28 33 -> Sim Mode Incline 5.030000. Responding: 80 11 01 + 145075 [722932][E](DirConManager): Sending response message type 0x04 to client 0 + 145076 [723945][E](FTMS_SERVER): 11 00 00 f3 01 28 33 -> Sim Mode Incline 4.990000. Responding: 80 11 01 + 145077 [723952][E](DirConManager): Sending response message type 0x04 to client 0 + 145078 [724897][E](FTMS_SERVER): 11 00 00 f1 01 28 33 -> Sim Mode Incline 4.970000. Responding: 80 11 01 + 145079 [724903][E](DirConManager): Sending response message type 0x04 to client 0 + 145080 [725784][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 204, Cad 56, HR 125, Gear 12, Res 60, Current Pos 17879, Target Pos 17879 + 145081 [725900][E](FTMS_SERVER): 11 00 00 df 01 28 33 -> Sim Mode Incline 4.790000. Responding: 80 11 01 + 145082 [725905][E](DirConManager): Sending response message type 0x04 to client 0 + 145083 [726921][E](FTMS_SERVER): 11 00 00 c7 01 28 33 -> Sim Mode Incline 4.550000. Responding: 80 11 01 + 145084 [726928][E](DirConManager): Sending response message type 0x04 to client 0 + 145085 [727841][E](FTMS_SERVER): 11 00 00 b7 01 28 33 -> Sim Mode Incline 4.390000. Responding: 80 11 01 + 145086 [727849][E](DirConManager): Sending response message type 0x04 to client 0 + 145087 [728864][E](FTMS_SERVER): 11 00 00 af 01 28 33 -> Sim Mode Incline 4.310000. Responding: 80 11 01 + 145088 [728872][E](DirConManager): Sending response message type 0x04 to client 0 + 145089 [729804][E](FTMS_SERVER): 11 00 00 a9 01 28 33 -> Sim Mode Incline 4.250000. Responding: 80 11 01 + 145090 [729810][E](DirConManager): Sending response message type 0x04 to client 0 + 145091 [730706][E](FTMS_SERVER): 11 00 00 a6 01 28 33 -> Sim Mode Incline 4.220000. Responding: 80 11 01 + 145092 [730711][E](DirConManager): Sending response message type 0x04 to client 0 + 145093 [731623][E](FTMS_SERVER): 11 00 00 a5 01 28 33 -> Sim Mode Incline 4.210000. Responding: 80 11 01 + 145094 [731630][E](DirConManager): Sending response message type 0x04 to client 0 + 145095 [731793][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 198, Cad 58, HR 128, Gear 12, Res 59, Current Pos 17347, Target Pos 17347 + 145096 [732550][E](FTMS_SERVER): 11 00 00 a6 01 28 33 -> Sim Mode Incline 4.220000. Responding: 80 11 01 + 145097 [732558][E](DirConManager): Sending response message type 0x04 to client 0 + 145098 [733560][E](FTMS_SERVER): 11 00 00 a8 01 28 33 -> Sim Mode Incline 4.240000. Responding: 80 11 01 + 145099 [733567][E](DirConManager): Sending response message type 0x04 to client 0 + 145100 [734521][E](FTMS_SERVER): 11 00 00 ad 01 28 33 -> Sim Mode Incline 4.290000. Responding: 80 11 01 + 145101 [734528][E](DirConManager): Sending response message type 0x04 to client 0 + 145102 [735509][E](FTMS_SERVER): 11 00 00 b4 01 28 33 -> Sim Mode Incline 4.360000. Responding: 80 11 01 + 145103 [735516][E](DirConManager): Sending response message type 0x04 to client 0 + 145104 [736442][E](FTMS_SERVER): 11 00 00 bf 01 28 33 -> Sim Mode Incline 4.470000. Responding: 80 11 01 + 145105 [736447][E](DirConManager): Sending response message type 0x04 to client 0 + 145106 [737470][E](FTMS_SERVER): 11 00 00 ce 01 28 33 -> Sim Mode Incline 4.620000. Responding: 80 11 01 + 145107 [737475][E](DirConManager): Sending response message type 0x04 to client 0 + 145108 [737809][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 185, Cad 56, HR 130, Gear 12, Res 59, Current Pos 17632, Target Pos 17634 + 145109 [738428][E](FTMS_SERVER): 11 00 00 e6 01 28 33 -> Sim Mode Incline 4.860000. Responding: 80 11 01 + 145110 [738434][E](DirConManager): Sending response message type 0x04 to client 0 + 145111 [739515][E](FTMS_SERVER): 11 00 00 0c 02 28 33 -> Sim Mode Incline 5.240000. Responding: 80 11 01 + 145112 [739521][E](DirConManager): Sending response message type 0x04 to client 0 + 145113 [740428][E](FTMS_SERVER): 11 00 00 44 02 28 33 -> Sim Mode Incline 5.800000. Responding: 80 11 01 + 145114 [740435][E](DirConManager): Sending response message type 0x04 to client 0 + 145115 [741350][E](FTMS_SERVER): 11 00 00 d3 01 28 33 -> Sim Mode Incline 4.670000. Responding: 80 11 01 + 145116 [741357][E](DirConManager): Sending response message type 0x04 to client 0 + 145117 [741531][E](PTable): Using detected travel limits during homing + 145118 [742373][E](FTMS_SERVER): 11 00 00 4c 01 28 33 -> Sim Mode Incline 3.320000. Responding: 80 11 01 + 145119 [742380][E](DirConManager): Sending response message type 0x04 to client 0 + 145120 [743315][E](FTMS_SERVER): 11 00 00 ec 00 28 33 -> Sim Mode Incline 2.360000. Responding: 80 11 01 + 145121 [743322][E](DirConManager): Sending response message type 0x04 to client 0 + 145122 [743819][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 209, Cad 57, HR 132, Gear 12, Res 56, Current Pos 16269, Target Pos 16052 + 145123 [744218][E](FTMS_SERVER): 11 00 00 af 00 28 33 -> Sim Mode Incline 1.750000. Responding: 80 11 01 + 145124 [744223][E](DirConManager): Sending response message type 0x04 to client 0 + 145125 [745145][E](FTMS_SERVER): 11 00 00 83 00 28 33 -> Sim Mode Incline 1.310000. Responding: 80 11 01 + 145126 [745152][E](DirConManager): Sending response message type 0x04 to client 0 + 145127 [745769][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 145128 [745770][E](PTable): Power Buffer Reset + 145129 [746056][E](FTMS_SERVER): 11 00 00 63 00 28 33 -> Sim Mode Incline 0.990000. Responding: 80 11 01 + 145130 [746063][E](DirConManager): Sending response message type 0x04 to client 0 + 145131 [747027][E](FTMS_SERVER): 11 00 00 4b 00 28 33 -> Sim Mode Incline 0.750000. Responding: 80 11 01 + 145132 [747034][E](DirConManager): Sending response message type 0x04 to client 0 + 145133 [748019][E](FTMS_SERVER): 11 00 00 39 00 28 33 -> Sim Mode Incline 0.570000. Responding: 80 11 01 + 145134 [748026][E](DirConManager): Sending response message type 0x04 to client 0 + 145135 [748930][E](FTMS_SERVER): 11 00 00 2e 00 28 33 -> Sim Mode Incline 0.460000. Responding: 80 11 01 + 145136 [748935][E](DirConManager): Sending response message type 0x04 to client 0 + 145137 [749833][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 193, Cad 73, HR 133, Gear 12, Res 50, Current Pos 14722, Target Pos 14722 + 145138 [749848][E](FTMS_SERVER): 11 00 00 29 00 28 33 -> Sim Mode Incline 0.410000. Responding: 80 11 01 + 145139 [749856][E](DirConManager): Sending response message type 0x04 to client 0 + 145140 [750877][E](FTMS_SERVER): 11 00 00 2b 00 28 33 -> Sim Mode Incline 0.430000. Responding: 80 11 01 + 145141 [750885][E](DirConManager): Sending response message type 0x04 to client 0 + 145142 [751827][E](FTMS_SERVER): 11 00 00 35 00 28 33 -> Sim Mode Incline 0.530000. Responding: 80 11 01 + 145143 [751834][E](DirConManager): Sending response message type 0x04 to client 0 + 145144 [752100][E](PTable): Averaged Entry: watts=206.000000, cad=70.900002, targetPosition=1485.500000, (2)(7) + 145145 [752101][E](PTData): Cleaned 235 readings + 145146 [752111][E](PTData): New entry recorded (2)(7)(1485) + 145147 [752111][E](PTData): Greater Down Found 3, 7, tp1489 + 145148 [752123][E](PTable): New Entry Processed in 24 ms + 145149 [752283][E](PTable): Writing File: /PowerTable.txt + 145150 [752571][E](PTable): Power table saved successfully with 452 readings + 145151 [752571][E](PTable): Power Buffer Reset + 145152 [752837][E](FTMS_SERVER): 11 00 00 2b 00 28 33 -> Sim Mode Incline 0.430000. Responding: 80 11 01 + 145153 [752845][E](DirConManager): Sending response message type 0x04 to client 0 + 145154 [753735][E](FTMS_SERVER): 11 00 00 19 00 28 33 -> Sim Mode Incline 0.250000. Responding: 80 11 01 + 145155 [753740][E](DirConManager): Sending response message type 0x04 to client 0 + 145156 [754676][E](FTMS_SERVER): 11 00 00 0e 00 28 33 -> Sim Mode Incline 0.140000. Responding: 80 11 01 + 145157 [754683][E](DirConManager): Sending response message type 0x04 to client 0 + 145158 [755684][E](FTMS_SERVER): 11 00 00 06 00 28 33 -> Sim Mode Incline 0.060000. Responding: 80 11 01 + 145159 [755691][E](DirConManager): Sending response message type 0x04 to client 0 + 145160 [755846][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 171, Cad 70, HR 135, Gear 12, Res 49, Current Pos 14461, Target Pos 14442 + 145161 [756625][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 145162 [756632][E](DirConManager): Sending response message type 0x04 to client 0 + 145163 [757525][E](FTMS_SERVER): 11 00 00 ff ff 28 33 -> Sim Mode Incline -0.010000. Responding: 80 11 01 + 145164 [757533][E](DirConManager): Sending response message type 0x04 to client 0 + 145165 [758455][E](PTable): Averaged Entry: watts=165.100006, cad=70.800003, targetPosition=1454.199951, (2)(6) + 145166 [758457][E](PTData): New entry recorded (2)(6)(1454) + 145167 [758467][E](PTData): Greater Down Found 3, 6, tp1455 + 145168 [758469][E](PTable): New Entry Processed in 14 ms + 145169 [758469][E](PTable): Power Buffer Reset + 145170 [758484][E](FTMS_SERVER): 11 00 00 fe ff 28 33 -> Sim Mode Incline -0.020000. Responding: 80 11 01 + 145171 [758489][E](DirConManager): Sending response message type 0x04 to client 0 + 145172 [759483][E](FTMS_SERVER): 11 00 00 fd ff 28 33 -> Sim Mode Incline -0.030000. Responding: 80 11 01 + 145173 [759489][E](DirConManager): Sending response message type 0x04 to client 0 + 145174 [760454][E](FTMS_SERVER): 11 00 00 fc ff 28 33 -> Sim Mode Incline -0.040000. Responding: 80 11 01 + 145175 [760458][E](DirConManager): Sending response message type 0x04 to client 0 + 145176 [761521][E](FTMS_SERVER): 11 00 00 fb ff 28 33 -> Sim Mode Incline -0.050000. Responding: 80 11 01 + 145177 [761525][E](DirConManager): Sending response message type 0x04 to client 0 + 145178 [761860][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 133, Cad 65, HR 136, Gear 12, Res 48, Current Pos 14365, Target Pos 14365 + 145179 [763989][E](FTMS_SERVER): 11 00 00 fc ff 28 33 -> Sim Mode Incline -0.040000. Responding: 80 11 01 + 145180 [763997][E](DirConManager): Sending response message type 0x04 to client 0 + 145181 [764803][E](PTable): Averaged Entry: watts=137.199997, cad=66.400002, targetPosition=1436.900024, (1)(5) + 145182 [764804][E](PTData): Existing entry averaged (1)(5)(1449), readings(14) + 145183 [764815][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145184 [764819][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145185 [764837][E](PTable): New Entry Processed in 34 ms + 145186 [764837][E](PTable): Power Buffer Reset + 145187 [764941][E](FTMS_SERVER): 11 00 00 fd ff 28 33 -> Sim Mode Incline -0.030000. Responding: 80 11 01 + 145188 [764949][E](DirConManager): Sending response message type 0x04 to client 0 + 145189 [765936][E](FTMS_SERVER): 11 00 00 ff ff 28 33 -> Sim Mode Incline -0.010000. Responding: 80 11 01 + 145190 [765943][E](DirConManager): Sending response message type 0x04 to client 0 + 145191 [766855][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 145192 [766862][E](DirConManager): Sending response message type 0x04 to client 0 + 145193 [767777][E](FTMS_SERVER): 11 00 00 02 00 28 33 -> Sim Mode Incline 0.020000. Responding: 80 11 01 + 145194 [767781][E](DirConManager): Sending response message type 0x04 to client 0 + 145195 [767875][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 130, Cad 65, HR 136, Gear 12, Res 49, Current Pos 14412, Target Pos 14414 + 145196 [768799][E](FTMS_SERVER): 11 00 00 04 00 28 33 -> Sim Mode Incline 0.040000. Responding: 80 11 01 + 145197 [768804][E](DirConManager): Sending response message type 0x04 to client 0 + 145198 [771156][E](PTable): Averaged Entry: watts=133.300003, cad=65.199997, targetPosition=1440.099976, (1)(4) + 145199 [771158][E](PTData): Cleaned 235 readings + 145200 [771168][E](PTData): Existing entry averaged (1)(4)(1397), readings(11) + 145201 [771169][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145202 [771184][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145203 [771191][E](PTable): New Entry Processed in 35 ms + 145204 [771191][E](PTable): Power Buffer Reset + 145205 [771265][E](FTMS_SERVER): 11 00 00 02 00 28 33 -> Sim Mode Incline 0.020000. Responding: 80 11 01 + 145206 [771272][E](DirConManager): Sending response message type 0x04 to client 0 + 145207 [772177][E](FTMS_SERVER): 11 00 00 ff ff 28 33 -> Sim Mode Incline -0.010000. Responding: 80 11 01 + 145208 [772185][E](DirConManager): Sending response message type 0x04 to client 0 + 145209 [773190][E](FTMS_SERVER): 11 00 00 fb ff 28 33 -> Sim Mode Incline -0.050000. Responding: 80 11 01 + 145210 [773197][E](DirConManager): Sending response message type 0x04 to client 0 + 145211 [773886][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 129, Cad 65, HR 139, Gear 12, Res 48, Current Pos 14365, Target Pos 14365 + 145212 [774153][E](FTMS_SERVER): 11 00 00 f1 ff 28 33 -> Sim Mode Incline -0.150000. Responding: 80 11 01 + 145213 [774162][E](DirConManager): Sending response message type 0x04 to client 0 + 145214 [775157][E](FTMS_SERVER): 11 00 00 e9 ff 28 33 -> Sim Mode Incline -0.230000. Responding: 80 11 01 + 145215 [775163][E](DirConManager): Sending response message type 0x04 to client 0 + 145216 [776088][E](FTMS_SERVER): 11 00 00 e6 ff 28 33 -> Sim Mode Incline -0.260000. Responding: 80 11 01 + 145217 [776092][E](DirConManager): Sending response message type 0x04 to client 0 + 145218 [776984][E](FTMS_SERVER): 11 00 00 e8 ff 28 33 -> Sim Mode Incline -0.240000. Responding: 80 11 01 + 145219 [776991][E](DirConManager): Sending response message type 0x04 to client 0 + 145220 [777511][E](PTable): Averaged Entry: watts=129.399994, cad=64.400002, targetPosition=1431.500000, (1)(4) + 145221 [777512][E](PTData): Cleaned 235 readings + 145222 [777522][E](PTData): Existing entry averaged (1)(4)(1399), readings(12) + 145223 [777523][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145224 [777538][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145225 [777545][E](PTable): New Entry Processed in 35 ms + 145226 [777545][E](PTable): Power Buffer Reset + 145227 [777545][E](PTable): Using detected travel limits during homing + 145228 [778008][E](FTMS_SERVER): 11 00 00 f0 ff 28 33 -> Sim Mode Incline -0.160000. Responding: 80 11 01 + 145229 [778015][E](DirConManager): Sending response message type 0x04 to client 0 + 145230 [778961][E](FTMS_SERVER): 11 00 00 ea ff 28 33 -> Sim Mode Incline -0.220000. Responding: 80 11 01 + 145231 [778969][E](DirConManager): Sending response message type 0x04 to client 0 + 145232 [779902][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 120, Cad 63, HR 140, Gear 12, Res 48, Current Pos 14246, Target Pos 14246 + 145233 [779957][E](FTMS_SERVER): 11 00 00 e3 ff 28 33 -> Sim Mode Incline -0.290000. Responding: 80 11 01 + 145234 [779964][E](DirConManager): Sending response message type 0x04 to client 0 + 145235 [780870][E](FTMS_SERVER): 11 00 00 21 01 28 33 -> Sim Mode Incline 2.890000. Responding: 80 11 01 + 145236 [780876][E](DirConManager): Sending response message type 0x04 to client 0 + 145237 [781908][E](FTMS_SERVER): 11 00 00 83 01 28 33 -> Sim Mode Incline 3.870000. Responding: 80 11 01 + 145238 [781914][E](DirConManager): Sending response message type 0x04 to client 0 + 145239 [782441][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 145240 [782442][E](PTable): Power Buffer Reset + 145241 [782934][E](FTMS_SERVER): 11 00 00 b8 01 28 33 -> Sim Mode Incline 4.400000. Responding: 80 11 01 + 145242 [782939][E](DirConManager): Sending response message type 0x04 to client 0 + 145243 [783961][E](FTMS_SERVER): 11 00 00 cc 01 28 33 -> Sim Mode Incline 4.600000. Responding: 80 11 01 + 145244 [783965][E](DirConManager): Sending response message type 0x04 to client 0 + 145245 [784871][E](FTMS_SERVER): 11 00 00 d2 01 28 33 -> Sim Mode Incline 4.660000. Responding: 80 11 01 + 145246 [784878][E](DirConManager): Sending response message type 0x04 to client 0 + 145247 [785913][E](FTMS_SERVER): 11 00 00 cf 01 28 33 -> Sim Mode Incline 4.630000. Responding: 80 11 01 + 145248 [785920][E](DirConManager): Sending response message type 0x04 to client 0 + 145249 [785922][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 160, Cad 60, HR 137, Gear 12, Res 60, Current Pos 17662, Target Pos 17662 + 145250 [786927][E](FTMS_SERVER): 11 00 00 c7 01 28 33 -> Sim Mode Incline 4.550000. Responding: 80 11 01 + 145251 [786934][E](DirConManager): Sending response message type 0x04 to client 0 + 145252 [787855][E](FTMS_SERVER): 11 00 00 b7 01 28 33 -> Sim Mode Incline 4.390000. Responding: 80 11 01 + 145253 [787863][E](DirConManager): Sending response message type 0x04 to client 0 + 145254 [788767][E](FTMS_SERVER): 11 00 00 a2 01 28 33 -> Sim Mode Incline 4.180000. Responding: 80 11 01 + 145255 [788775][E](DirConManager): Sending response message type 0x04 to client 0 + 145256 [789679][E](FTMS_SERVER): 11 00 00 85 01 28 33 -> Sim Mode Incline 3.890000. Responding: 80 11 01 + 145257 [789684][E](DirConManager): Sending response message type 0x04 to client 0 + 145258 [790614][E](FTMS_SERVER): 11 00 00 5a 01 28 33 -> Sim Mode Incline 3.460000. Responding: 80 11 01 + 145259 [790622][E](DirConManager): Sending response message type 0x04 to client 0 + 145260 [791576][E](FTMS_SERVER): 11 00 00 14 01 28 33 -> Sim Mode Incline 2.760000. Responding: 80 11 01 + 145261 [791583][E](DirConManager): Sending response message type 0x04 to client 0 + 145262 [791948][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 187, Cad 56, HR 134, Gear 12, Res 57, Current Pos 16613, Target Pos 16332 + 145263 [792569][E](FTMS_SERVER): 11 00 00 b7 00 28 33 -> Sim Mode Incline 1.830000. Responding: 80 11 01 + 145264 [792576][E](DirConManager): Sending response message type 0x04 to client 0 + 145265 [793472][E](FTMS_SERVER): 11 00 00 60 00 28 33 -> Sim Mode Incline 0.960000. Responding: 80 11 01 + 145266 [793479][E](DirConManager): Sending response message type 0x04 to client 0 + 145267 [794393][E](FTMS_SERVER): 11 00 00 09 00 28 33 -> Sim Mode Incline 0.090000. Responding: 80 11 01 + 145268 [794398][E](DirConManager): Sending response message type 0x04 to client 0 + 145269 [795512][E](FTMS_SERVER): 11 00 00 de ff 28 33 -> Sim Mode Incline -0.340000. Responding: 80 11 01 + 145270 [795516][E](DirConManager): Sending response message type 0x04 to client 0 + 145271 [795896][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 145272 [795897][E](PTable): Power Buffer Reset + 145273 [796466][E](FTMS_SERVER): 11 00 00 c5 ff 28 33 -> Sim Mode Incline -0.590000. Responding: 80 11 01 + 145274 [796473][E](DirConManager): Sending response message type 0x04 to client 0 + 145275 [797463][E](FTMS_SERVER): 11 00 00 d3 ff 28 33 -> Sim Mode Incline -0.450000. Responding: 80 11 01 + 145276 [797468][E](DirConManager): Sending response message type 0x04 to client 0 + 145277 [797966][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 134, Cad 60, HR 134, Gear 12, Res 47, Current Pos 14085, Target Pos 14085 + 145278 [798395][E](FTMS_SERVER): 11 00 00 f8 ff 28 33 -> Sim Mode Incline -0.080000. Responding: 80 11 01 + 145279 [798402][E](DirConManager): Sending response message type 0x04 to client 0 + 145280 [799302][E](FTMS_SERVER): 11 00 00 1e 00 28 33 -> Sim Mode Incline 0.300000. Responding: 80 11 01 + 145281 [799309][E](DirConManager): Sending response message type 0x04 to client 0 + 145282 [800276][E](FTMS_SERVER): 11 00 00 2e 00 28 33 -> Sim Mode Incline 0.460000. Responding: 80 11 01 + 145283 [800283][E](DirConManager): Sending response message type 0x04 to client 0 + 145284 [801266][E](FTMS_SERVER): 11 00 00 34 00 28 33 -> Sim Mode Incline 0.520000. Responding: 80 11 01 + 145285 [801274][E](DirConManager): Sending response message type 0x04 to client 0 + 145286 [802252][E](PTable): Averaged Entry: watts=133.699997, cad=61.299999, targetPosition=1437.599976, (0)(4) + 145287 [802254][E](PTData): Cleaned 235 readings + 145288 [802264][E](PTData): Existing entry averaged (0)(4)(1422), readings(5) + 145289 [802267][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145290 [802282][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145291 [802289][E](PTable): New Entry Processed in 37 ms + 145292 [802289][E](PTable): Power Buffer Reset + 145293 [802899][E](FTMS_SERVER): 11 00 00 30 00 28 33 -> Sim Mode Incline 0.480000. Responding: 80 11 01 + 145294 [802907][E](DirConManager): Sending response message type 0x04 to client 0 + 145295 [803909][E](FTMS_SERVER): 11 00 00 29 00 28 33 -> Sim Mode Incline 0.410000. Responding: 80 11 01 + 145296 [803917][E](DirConManager): Sending response message type 0x04 to client 0 + 145297 [803979][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 131, Cad 63, HR 134, Gear 12, Res 50, Current Pos 14729, Target Pos 14687 + 145298 [804884][E](FTMS_SERVER): 11 00 00 1b 00 28 33 -> Sim Mode Incline 0.270000. Responding: 80 11 01 + 145299 [804890][E](DirConManager): Sending response message type 0x04 to client 0 + 145300 [805875][E](FTMS_SERVER): 11 00 00 08 00 28 33 -> Sim Mode Incline 0.080000. Responding: 80 11 01 + 145301 [805882][E](DirConManager): Sending response message type 0x04 to client 0 + 145302 [806835][E](FTMS_SERVER): 11 00 00 f7 ff 28 33 -> Sim Mode Incline -0.090000. Responding: 80 11 01 + 145303 [806840][E](DirConManager): Sending response message type 0x04 to client 0 + 145304 [807697][E](FTMS_SERVER): 11 00 00 e2 ff 28 33 -> Sim Mode Incline -0.300000. Responding: 80 11 01 + 145305 [807704][E](DirConManager): Sending response message type 0x04 to client 0 + 145306 [808594][E](PTable): Averaged Entry: watts=133.300003, cad=62.900002, targetPosition=1453.800049, (0)(4) + 145307 [808596][E](PTData): Cleaned 235 readings + 145308 [808606][E](PTData): Existing entry averaged (0)(4)(1426), readings(6) + 145309 [808607][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145310 [808622][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145311 [808629][E](PTable): New Entry Processed in 35 ms + 145312 [808629][E](PTable): Power Buffer Reset + 145313 [808734][E](FTMS_SERVER): 11 00 00 bc ff 28 33 -> Sim Mode Incline -0.680000. Responding: 80 11 01 + 145314 [808741][E](DirConManager): Sending response message type 0x04 to client 0 + 145315 [809679][E](FTMS_SERVER): 11 00 00 5e ff 28 33 -> Sim Mode Incline -1.620000. Responding: 80 11 01 + 145316 [809687][E](DirConManager): Sending response message type 0x04 to client 0 + 145317 [809995][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 136, Cad 66, HR 133, Gear 12, Res 47, Current Pos 13776, Target Pos 13266 + 145318 [810685][E](FTMS_SERVER): 11 00 00 12 ff 28 33 -> Sim Mode Incline -2.380000. Responding: 80 11 01 + 145319 [810692][E](DirConManager): Sending response message type 0x04 to client 0 + 145320 [811601][E](FTMS_SERVER): 11 00 00 00 ff 28 33 -> Sim Mode Incline -2.560000. Responding: 80 11 01 + 145321 [811606][E](DirConManager): Sending response message type 0x04 to client 0 + 145322 [812546][E](FTMS_SERVER): 11 00 00 fc fe 28 33 -> Sim Mode Incline -2.600000. Responding: 80 11 01 + 145323 [812553][E](DirConManager): Sending response message type 0x04 to client 0 + 145324 [813529][E](PTable): Using detected travel limits during homing + 145325 [813544][E](FTMS_SERVER): 11 00 00 fb fe 28 33 -> Sim Mode Incline -2.610000. Responding: 80 11 01 + 145326 [813551][E](DirConManager): Sending response message type 0x04 to client 0 + 145327 [814053][E](FTMS_SERVER): 05 a5 00 -> ERG Mode Target: 165 Current: 116 Incline: -2.610000. Responding: 80 05 01 + 145328 [814060][E](DirConManager): Sending response message type 0x04 to client 0 + 145329 [814239][E](ERG_Mode): SetPoint changed:135w Waiting:888ms PowerTable Result: 13180 + 145330 [816010][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 107, Cad 71, HR 132, Gear 12, Res 44, Current Pos 13180, Target Pos 13180 + 145331 [816534][E](ERG_Mode): ERG wait expired, pos: 13180, tgt: 0 + 145332 [816535][E](PTable): Averaged Entry: watts=129.000000, cad=66.599998, targetPosition=1310.699951, (1)(4) + 145333 [816546][E](PTData): Cleaned 235 readings + 145334 [816546][E](PTData): Existing entry averaged (1)(4)(1392), readings(13) + 145335 [816557][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145336 [816562][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145337 [816569][E](PTable): New Entry Processed in 34 ms + 145338 [816569][E](PTable): Power Buffer Reset + 145339 [816569][E](ERG_Mode): Proportional: 138.000000 + 145340 [817944][E](ERG_Mode): Watts previously processed. + 145341 [820055][E](ERG_Mode): Watts previously processed. + 145342 [822026][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 141, Cad 76, HR 133, Gear 12, Res 46, Current Pos 13603, Target Pos 13603 + 145343 [822166][E](ERG_Mode): Watts previously processed. + 145344 [822872][E](PTable): Averaged Entry: watts=143.899994, cad=74.599998, targetPosition=1345.800049, (3)(5) + 145345 [822874][E](PTData): Cleaned 235 readings + 145346 [822884][E](PTData): Existing entry averaged (3)(5)(1327), readings(2) + 145347 [822885][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145348 [822900][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145349 [822907][E](PTable): New Entry Processed in 35 ms + 145350 [822907][E](PTable): Power Buffer Reset + 145351 [822907][E](ERG_Mode): Proportional: 60.000000 + 145352 [824283][E](ERG_Mode): Watts previously processed. + 145353 [827097][E](ERG_Mode): Watts previously processed. + 145354 [828045][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 146, Cad 72, HR 131, Gear 12, Res 47, Current Pos 13998, Target Pos 13999 + 145355 [828510][E](ERG_Mode): Proportional: -42.000000 + 145356 [829218][E](PTable): Averaged Entry: watts=149.699997, cad=73.599998, targetPosition=1382.800049, (3)(5) + 145357 [829220][E](PTData): Cleaned 235 readings + 145358 [829230][E](PTData): Existing entry averaged (3)(5)(1340), readings(3) + 145359 [829231][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145360 [829246][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145361 [829253][E](PTable): New Entry Processed in 35 ms + 145362 [829253][E](PTable): Power Buffer Reset + 145363 [829253][E](ERG_Mode): Watts previously processed. + 145364 [831330][E](ERG_Mode): Watts previously processed. + 145365 [833443][E](ERG_Mode): Watts previously processed. + 145366 [834062][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 158, Cad 72, HR 131, Gear 12, Res 48, Current Pos 14146, Target Pos 14146 + 145367 [834154][E](ERG_Mode): Proportional: 7.000000 + 145368 [835564][E](PTable): Averaged Entry: watts=151.899994, cad=72.800003, targetPosition=1406.400024, (2)(5) + 145369 [835565][E](PTData): Cleaned 235 readings + 145370 [835576][E](PTData): Existing entry averaged (2)(5)(1404), readings(19) + 145371 [835577][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145372 [835592][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145373 [835598][E](PTable): New Entry Processed in 34 ms + 145374 [835599][E](PTable): Power Buffer Reset + 145375 [836970][E](ERG_Mode): Watts previously processed. + 145376 [839092][E](ERG_Mode): Watts previously processed. + 145377 [839799][E](ERG_Mode): Proportional: 9.000000 + 145378 [840071][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 156, Cad 73, HR 130, Gear 12, Res 48, Current Pos 14240, Target Pos 14240 + 145379 [841212][E](ERG_Mode): Watts previously processed. + 145380 [841918][E](PTable): Averaged Entry: watts=157.500000, cad=72.400002, targetPosition=1422.000000, (2)(5) + 145381 [841920][E](PTData): Cleaned 235 readings + 145382 [841930][E](PTData): Existing entry averaged (2)(5)(1404), readings(20) + 145383 [841931][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145384 [841946][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145385 [841953][E](PTable): New Entry Processed in 35 ms + 145386 [841953][E](PTable): Power Buffer Reset + 145387 [843326][E](ERG_Mode): Watts previously processed. + 145388 [845441][E](ERG_Mode): Watts previously processed. + 145389 [846087][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 158, Cad 71, HR 130, Gear 12, Res 49, Current Pos 14388, Target Pos 14388 + 145390 [846148][E](ERG_Mode): Proportional: 7.000000 + 145391 [848266][E](PTable): Averaged Entry: watts=156.800003, cad=71.199997, targetPosition=1435.800049, (2)(5) + 145392 [848267][E](PTData): Cleaned 235 readings + 145393 [848277][E](PTData): Existing entry averaged (2)(5)(1405), readings(20) + 145394 [848278][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145395 [848293][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145396 [848299][E](PTable): New Entry Processed in 34 ms + 145397 [848300][E](PTable): Power Buffer Reset + 145398 [848970][E](ERG_Mode): Watts previously processed. + 145399 [851085][E](ERG_Mode): Watts previously processed. + 145400 [851086][E](PTable): Using detected travel limits during homing + 145401 [851794][E](ERG_Mode): Proportional: 5.000000 + 145402 [852099][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 160, Cad 70, HR 130, Gear 12, Res 49, Current Pos 14531, Target Pos 14531 + 145403 [853197][E](ERG_Mode): Watts previously processed. + 145404 [854605][E](PTable): Averaged Entry: watts=156.699997, cad=70.300003, targetPosition=1451.500000, (2)(5) + 145405 [854607][E](PTData): Cleaned 235 readings + 145406 [854617][E](PTData): Existing entry averaged (2)(5)(1407), readings(20) + 145407 [854618][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145408 [854633][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145409 [854640][E](PTable): New Entry Processed in 35 ms + 145410 [854640][E](PTable): Power Buffer Reset + 145411 [855307][E](ERG_Mode): Watts previously processed. + 145412 [857422][E](ERG_Mode): Watts previously processed. + 145413 [858112][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 156, Cad 71, HR 131, Gear 12, Res 49, Current Pos 14590, Target Pos 14590 + 145414 [858132][E](ERG_Mode): Proportional: 9.000000 + 145415 [860258][E](ERG_Mode): Watts previously processed. + 145416 [860964][E](PTable): Averaged Entry: watts=160.500000, cad=70.199997, targetPosition=1459.900024, (2)(5) + 145417 [860965][E](PTData): Cleaned 235 readings + 145418 [860975][E](PTData): Existing entry averaged (2)(5)(1409), readings(20) + 145419 [860976][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145420 [860991][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145421 [860998][E](PTable): New Entry Processed in 35 ms + 145422 [860998][E](PTable): Power Buffer Reset + 145423 [863075][E](ERG_Mode): Watts previously processed. + 145424 [863782][E](ERG_Mode): Proportional: 7.000000 + 145425 [864126][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 158, Cad 69, HR 132, Gear 12, Res 50, Current Pos 14697, Target Pos 14697 + 145426 [865193][E](ERG_Mode): Watts previously processed. + 145427 [867308][E](PTable): Averaged Entry: watts=160.800003, cad=69.900002, targetPosition=1467.400024, (2)(5) + 145428 [867310][E](PTData): Cleaned 235 readings + 145429 [867320][E](PTData): Existing entry averaged (2)(5)(1411), readings(20) + 145430 [867321][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145431 [867336][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145432 [867343][E](PTable): New Entry Processed in 35 ms + 145433 [867343][E](PTable): Power Buffer Reset + 145434 [867343][E](ERG_Mode): Watts previously processed. + 145435 [869418][E](ERG_Mode): Watts previously processed. + 145436 [870128][E](ERG_Mode): Proportional: -1.000000 + 145437 [870141][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 166, Cad 70, HR 133, Gear 12, Res 50, Current Pos 14701, Target Pos 14700 + 145438 [871547][E](ERG_Mode): Watts previously processed. + 145439 [872958][E](ERG_Mode): Watts previously processed. + 145440 [873663][E](PTable): Averaged Entry: watts=162.699997, cad=69.800003, targetPosition=1470.699951, (2)(5) + 145441 [873665][E](PTData): Cleaned 235 readings + 145442 [873675][E](PTData): Existing entry averaged (2)(5)(1413), readings(20) + 145443 [873676][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145444 [873691][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145445 [873697][E](PTable): New Entry Processed in 34 ms + 145446 [873698][E](PTable): Power Buffer Reset + 145447 [873962][E](FTMS_SERVER): 05 b4 00 -> ERG Mode Target: 180 Current: 161 Incline: 147.309998. Responding: 80 05 01 + 145448 [873970][E](DirConManager): Sending response message type 0x04 to client 0 + 145449 [875071][E](ERG_Mode): Watts previously processed. + 145450 [875777][E](ERG_Mode): Proportional: -75.000000 + 145451 [876150][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 205, Cad 75, HR 133, Gear 12, Res 50, Current Pos 14647, Target Pos 14647 + 145452 [877188][E](ERG_Mode): Watts previously processed. + 145453 [879308][E](ERG_Mode): Watts previously processed. + 145454 [880015][E](PTable): Averaged Entry: watts=192.399994, cad=75.000000, targetPosition=1462.599976, (3)(6) + 145455 [880017][E](PTData): Cleaned 235 readings + 145456 [880027][E](PTData): Existing entry averaged (3)(6)(1455), readings(7) + 145457 [880028][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145458 [880043][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145459 [880050][E](PTable): New Entry Processed in 35 ms + 145460 [880050][E](PTable): Power Buffer Reset + 145461 [881431][E](ERG_Mode): Watts previously processed. + 145462 [882138][E](ERG_Mode): Proportional: -4.000000 + 145463 [882162][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 184, Cad 75, HR 134, Gear 12, Res 49, Current Pos 14523, Target Pos 14520 + 145464 [883544][E](ERG_Mode): Watts previously processed. + 145465 [886366][E](PTable): Averaged Entry: watts=187.000000, cad=76.300003, targetPosition=1449.500000, (3)(6) + 145466 [886368][E](PTData): Cleaned 235 readings + 145467 [886378][E](PTData): Existing entry averaged (3)(6)(1454), readings(8) + 145468 [886379][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145469 [886394][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145470 [886401][E](PTable): New Entry Processed in 35 ms + 145471 [886401][E](PTable): Power Buffer Reset + 145472 [886401][E](ERG_Mode): Watts previously processed. + 145473 [887072][E](PTable): Using detected travel limits during homing + 145474 [887778][E](ERG_Mode): Proportional: -33.000000 + 145475 [888172][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 191, Cad 80, HR 135, Gear 12, Res 48, Current Pos 14233, Target Pos 14233 + 145476 [889189][E](ERG_Mode): Watts previously processed. + 145477 [891310][E](ERG_Mode): Watts previously processed. + 145478 [892720][E](PTable): Averaged Entry: watts=196.100006, cad=79.500000, targetPosition=1421.300049, (4)(7) + 145479 [892722][E](PTData): Cleaned 235 readings + 145480 [892732][E](PTData): Existing entry averaged (4)(7)(1444), readings(17) + 145481 [892733][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145482 [892748][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145483 [892754][E](PTable): New Entry Processed in 34 ms + 145484 [892755][E](PTable): Power Buffer Reset + 145485 [893422][E](ERG_Mode): Watts previously processed. + 145486 [894127][E](ERG_Mode): Proportional: -90.000000 + 145487 [894189][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 210, Cad 80, HR 137, Gear 12, Res 48, Current Pos 14109, Target Pos 14026 + 145488 [895536][E](ERG_Mode): Watts previously processed. + 145489 [899063][E](PTable): Averaged Entry: watts=199.899994, cad=81.800003, targetPosition=1391.099976, (4)(7) + 145490 [899065][E](PTData): Cleaned 235 readings + 145491 [899075][E](PTData): Existing entry averaged (4)(7)(1441), readings(18) + 145492 [899076][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145493 [899091][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145494 [899098][E](PTable): New Entry Processed in 35 ms + 145495 [899098][E](PTable): Power Buffer Reset + 145496 [899098][E](ERG_Mode): Watts previously processed. + 145497 [899768][E](ERG_Mode): Proportional: 30.000000 + 145498 [900201][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 170, Cad 81, HR 140, Gear 12, Res 46, Current Pos 13717, Target Pos 13717 + 145499 [901179][E](ERG_Mode): Watts previously processed. + 145500 [903287][E](ERG_Mode): Watts previously processed. + 145501 [905410][E](PTable): Averaged Entry: watts=177.300003, cad=81.400002, targetPosition=1372.500000, (4)(6) + 145502 [905412][E](PTData): Cleaned 235 readings + 145503 [905422][E](PTData): Existing entry averaged (4)(6)(1372), readings(13) + 145504 [905423][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145505 [905438][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145506 [905444][E](PTable): New Entry Processed in 34 ms + 145507 [905445][E](PTable): Power Buffer Reset + 145508 [905445][E](ERG_Mode): Watts previously processed. + 145509 [906120][E](ERG_Mode): Proportional: 9.000000 + 145510 [906213][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 171, Cad 82, HR 143, Gear 12, Res 46, Current Pos 13747, Target Pos 13747 + 145511 [907539][E](ERG_Mode): Watts previously processed. + 145512 [911077][E](ERG_Mode): Watts previously processed. + 145513 [911783][E](PTable): Averaged Entry: watts=193.000000, cad=85.000000, targetPosition=1359.000000, (5)(6) + 145514 [911785][E](PTData): Cleaned 235 readings + 145515 [911795][E](PTData): Existing entry averaged (5)(6)(1329), readings(14) + 145516 [911796][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145517 [911811][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145518 [911817][E](PTable): New Entry Processed in 34 ms + 145519 [911818][E](PTable): Power Buffer Reset + 145520 [911818][E](ERG_Mode): Proportional: -48.000000 + 145521 [912221][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 196, Cad 88, HR 145, Gear 12, Res 45, Current Pos 13290, Target Pos 13290 + 145522 [913202][E](ERG_Mode): Watts previously processed. + 145523 [915321][E](ERG_Mode): Watts previously processed. + 145524 [917442][E](ERG_Mode): Watts previously processed. + 145525 [918149][E](PTable): Averaged Entry: watts=181.600006, cad=86.400002, targetPosition=1328.199951, (5)(6) + 145526 [918151][E](PTData): Cleaned 235 readings + 145527 [918161][E](PTData): Existing entry averaged (5)(6)(1328), readings(15) + 145528 [918162][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145529 [918177][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145530 [918186][E](PTable): New Entry Processed in 37 ms + 145531 [918187][E](PTable): Power Buffer Reset + 145532 [918187][E](ERG_Mode): Proportional: -4.000000 + 145533 [918230][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 184, Cad 87, HR 145, Gear 12, Res 45, Current Pos 13279, Target Pos 13278 + 145534 [919560][E](ERG_Mode): Watts previously processed. + 145535 [923079][E](ERG_Mode): Watts previously processed. + 145536 [923080][E](PTable): Using detected travel limits during homing + 145537 [923795][E](ERG_Mode): Proportional: -1.000000 + 145538 [924240][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 181, Cad 87, HR 144, Gear 12, Res 45, Current Pos 13266, Target Pos 13266 + 145539 [924496][E](PTable): Averaged Entry: watts=181.100006, cad=86.699997, targetPosition=1326.900024, (5)(6) + 145540 [924498][E](PTData): Cleaned 235 readings + 145541 [924508][E](PTData): Existing entry averaged (5)(6)(1327), readings(16) + 145542 [924509][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145543 [924524][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145544 [924532][E](PTable): New Entry Processed in 36 ms + 145545 [924532][E](PTable): Power Buffer Reset + 145546 [925203][E](ERG_Mode): Watts previously processed. + 145547 [927320][E](ERG_Mode): Watts previously processed. + 145548 [929434][E](ERG_Mode): Watts previously processed. + 145549 [930136][E](ERG_Mode): Proportional: 1.000000 + 145550 [930249][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 179, Cad 89, HR 145, Gear 12, Res 44, Current Pos 13085, Target Pos 13085 + 145551 [930846][E](PTable): Averaged Entry: watts=190.600006, cad=89.000000, targetPosition=1317.199951, (6)(6) + 145552 [930847][E](PTData): Cleaned 235 readings + 145553 [930857][E](PTData): Existing entry averaged (6)(6)(1269), readings(20) + 145554 [930858][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145555 [930873][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145556 [930880][E](PTable): New Entry Processed in 35 ms + 145557 [930880][E](PTable): Power Buffer Reset + 145558 [931551][E](ERG_Mode): Watts previously processed. + 145559 [933664][E](ERG_Mode): Watts previously processed. + 145560 [934065][E](FTMS_SERVER): 05 c3 00 -> ERG Mode Target: 195 Current: 191 Incline: 130.880005. Responding: 80 05 01 + 145561 [934072][E](DirConManager): Sending response message type 0x04 to client 0 + 145562 [935075][E](ERG_Mode): Watts previously processed. + 145563 [935781][E](ERG_Mode): Proportional: 30.000000 + 145564 [936264][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 185, Cad 90, HR 148, Gear 12, Res 44, Current Pos 13113, Target Pos 13113 + 145565 [937192][E](PTable): Averaged Entry: watts=184.699997, cad=89.199997, targetPosition=1309.099976, (6)(6) + 145566 [937194][E](PTData): Cleaned 235 readings + 145567 [937204][E](PTData): Existing entry averaged (6)(6)(1270), readings(20) + 145568 [937205][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145569 [937220][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145570 [937227][E](PTable): New Entry Processed in 35 ms + 145571 [937227][E](PTable): Power Buffer Reset + 145572 [937227][E](ERG_Mode): Watts previously processed. + 145573 [939306][E](ERG_Mode): Watts previously processed. + 145574 [941415][E](ERG_Mode): Watts previously processed. + 145575 [942118][E](ERG_Mode): Proportional: 75.000000 + 145576 [942281][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 170, Cad 87, HR 148, Gear 12, Res 45, Current Pos 13338, Target Pos 13371 + 145577 [943528][E](PTable): Averaged Entry: watts=182.399994, cad=88.800003, targetPosition=1323.400024, (6)(6) + 145578 [943530][E](PTData): Cleaned 235 readings + 145579 [943540][E](PTData): Existing entry averaged (6)(6)(1272), readings(20) + 145580 [943541][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145581 [943556][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145582 [943563][E](PTable): New Entry Processed in 34 ms + 145583 [943563][E](PTable): Power Buffer Reset + 145584 [943563][E](ERG_Mode): Watts previously processed. + 145585 [947050][E](ERG_Mode): Watts previously processed. + 145586 [947758][E](ERG_Mode): Proportional: -3.000000 + 145587 [948299][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 198, Cad 87, HR 147, Gear 12, Res 45, Current Pos 13429, Target Pos 13429 + 145588 [949163][E](ERG_Mode): Watts previously processed. + 145589 [949871][E](PTable): Averaged Entry: watts=188.600006, cad=87.300003, targetPosition=1340.699951, (5)(6) + 145590 [949873][E](PTData): Cleaned 235 readings + 145591 [949883][E](PTData): Existing entry averaged (5)(6)(1327), readings(17) + 145592 [949884][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145593 [949899][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145594 [949906][E](PTable): New Entry Processed in 35 ms + 145595 [949906][E](PTable): Power Buffer Reset + 145596 [951274][E](ERG_Mode): Watts previously processed. + 145597 [953386][E](ERG_Mode): Watts previously processed. + 145598 [954090][E](ERG_Mode): Proportional: 39.000000 + 145599 [954316][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 182, Cad 87, HR 146, Gear 12, Res 45, Current Pos 13481, Target Pos 13481 + 145600 [955502][E](ERG_Mode): Watts previously processed. + 145601 [956208][E](PTable): Averaged Entry: watts=192.300003, cad=87.500000, targetPosition=1345.800049, (5)(6) + 145602 [956210][E](PTData): Cleaned 235 readings + 145603 [956221][E](PTData): Existing entry averaged (5)(6)(1327), readings(18) + 145604 [956222][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145605 [956236][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145606 [956243][E](PTable): New Entry Processed in 35 ms + 145607 [956243][E](PTable): Power Buffer Reset + 145608 [959028][E](ERG_Mode): Watts previously processed. + 145609 [959029][E](PTable): Using detected travel limits during homing + 145610 [959735][E](ERG_Mode): Proportional: 5.000000 + 145611 [960331][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 190, Cad 86, HR 146, Gear 12, Res 46, Current Pos 13574, Target Pos 13574 + 145612 [961141][E](ERG_Mode): Watts previously processed. + 145613 [962551][E](PTable): Averaged Entry: watts=191.399994, cad=86.400002, targetPosition=1354.699951, (5)(6) + 145614 [962553][E](PTData): Cleaned 235 readings + 145615 [962563][E](PTData): Existing entry averaged (5)(6)(1328), readings(19) + 145616 [962564][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145617 [962579][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145618 [962586][E](PTable): New Entry Processed in 35 ms + 145619 [962586][E](PTable): Power Buffer Reset + 145620 [963255][E](ERG_Mode): Watts previously processed. + 145621 [965369][E](ERG_Mode): Watts previously processed. + 145622 [966076][E](ERG_Mode): Proportional: 6.000000 + 145623 [966341][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 189, Cad 85, HR 145, Gear 12, Res 46, Current Pos 13592, Target Pos 13592 + 145624 [967487][E](ERG_Mode): Watts previously processed. + 145625 [968897][E](PTable): Averaged Entry: watts=193.199997, cad=86.099998, targetPosition=1357.800049, (5)(6) + 145626 [968899][E](PTData): Cleaned 235 readings + 145627 [968909][E](PTData): Existing entry averaged (5)(6)(1329), readings(20) + 145628 [968910][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145629 [968925][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145630 [968932][E](PTable): New Entry Processed in 35 ms + 145631 [968932][E](PTable): Power Buffer Reset + 145632 [971009][E](ERG_Mode): Watts previously processed. + 145633 [971716][E](ERG_Mode): Proportional: 4.000000 + 145634 [972352][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 191, Cad 86, HR 145, Gear 12, Res 46, Current Pos 13517, Target Pos 13517 + 145635 [973118][E](ERG_Mode): Watts previously processed. + 145636 [975228][E](PTable): Averaged Entry: watts=190.800003, cad=86.099998, targetPosition=1356.000000, (5)(6) + 145637 [975230][E](PTData): Cleaned 235 readings + 145638 [975240][E](PTData): Existing entry averaged (5)(6)(1330), readings(20) + 145639 [975241][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145640 [975256][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145641 [975263][E](PTable): New Entry Processed in 35 ms + 145642 [975263][E](PTable): Power Buffer Reset + 145643 [975264][E](ERG_Mode): Watts previously processed. + 145644 [977343][E](ERG_Mode): Watts previously processed. + 145645 [978048][E](ERG_Mode): Proportional: 39.000000 + 145646 [978364][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 182, Cad 83, HR 146, Gear 12, Res 46, Current Pos 13799, Target Pos 13799 + 145647 [979468][E](ERG_Mode): Watts previously processed. + 145648 [981581][E](PTable): Averaged Entry: watts=189.699997, cad=84.000000, targetPosition=1375.599976, (5)(6) + 145649 [981583][E](PTData): Cleaned 235 readings + 145650 [981593][E](PTData): Existing entry averaged (5)(6)(1332), readings(20) + 145651 [981594][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145652 [981609][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145653 [981616][E](PTable): New Entry Processed in 35 ms + 145654 [981616][E](PTable): Power Buffer Reset + 145655 [982293][E](ERG_Mode): Watts previously processed. + 145656 [983697][E](ERG_Mode): Proportional: -51.000000 + 145657 [984384][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 202, Cad 89, HR 148, Gear 12, Res 46, Current Pos 13741, Target Pos 13741 + 145658 [985110][E](ERG_Mode): Watts previously processed. + 145659 [987227][E](ERG_Mode): Watts previously processed. + 145660 [987936][E](PTable): Averaged Entry: watts=204.399994, cad=87.500000, targetPosition=1373.300049, (5)(7) + 145661 [987937][E](PTData): Cleaned 235 readings + 145662 [987947][E](PTData): Existing entry averaged (5)(7)(1399), readings(14) + 145663 [987948][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145664 [987963][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145665 [987970][E](PTable): New Entry Processed in 35 ms + 145666 [987970][E](PTable): Power Buffer Reset + 145667 [989352][E](ERG_Mode): Watts previously processed. + 145668 [990059][E](ERG_Mode): Proportional: 9.000000 + 145669 [990394][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 186, Cad 87, HR 150, Gear 12, Res 46, Current Pos 13569, Target Pos 13569 + 145670 [991478][E](ERG_Mode): Watts previously processed. + 145671 [993589][E](ERG_Mode): Watts previously processed. + 145672 [994300][E](PTable): Averaged Entry: watts=193.300003, cad=86.500000, targetPosition=1358.800049, (5)(6) + 145673 [994302][E](PTData): Cleaned 235 readings + 145674 [994312][E](PTData): Existing entry averaged (5)(6)(1333), readings(20) + 145675 [994313][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145676 [994328][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145677 [994334][E](PTable): New Entry Processed in 34 ms + 145678 [994521][E](PTable): Writing File: /PowerTable.txt + 145679 [995284][E](PTable): Power table saved successfully with 706 readings + 145680 [995285][E](PTable): Power Buffer Reset + 145681 [995285][E](ERG_Mode): Proportional: 3.000000 + 145682 [995327][E](PTable): Using detected travel limits during homing + 145683 [996033][E](ERG_Mode): Watts previously processed. + 145684 [996409][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 193, Cad 85, HR 151, Gear 12, Res 46, Current Pos 13642, Target Pos 13642 + 145685 [998148][E](ERG_Mode): Watts previously processed. + 145686 [1000264][E](ERG_Mode): Watts previously processed. + 145687 [1000971][E](PTable): Averaged Entry: watts=193.899994, cad=85.000000, targetPosition=1364.300049, (5)(6) + 145688 [1000973][E](PTData): Cleaned 235 readings + 145689 [1000983][E](PTData): Existing entry averaged (5)(6)(1334), readings(20) + 145690 [1000984][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145691 [1000999][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145692 [1001006][E](PTable): New Entry Processed in 35 ms + 145693 [1001006][E](PTable): Power Buffer Reset + 145694 [1001006][E](ERG_Mode): Proportional: 3.000000 + 145695 [1002388][E](ERG_Mode): Watts previously processed. + 145696 [1002419][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 190, Cad 85, HR 152, Gear 12, Res 46, Current Pos 13659, Target Pos 13659 + 145697 [1004509][E](ERG_Mode): Watts previously processed. + 145698 [1006624][E](ERG_Mode): Proportional: 2.000000 + 145699 [1007329][E](PTable): Averaged Entry: watts=195.399994, cad=86.000000, targetPosition=1364.199951, (5)(7) + 145700 [1007331][E](PTData): Cleaned 235 readings + 145701 [1007341][E](PTData): Existing entry averaged (5)(7)(1396), readings(15) + 145702 [1007342][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145703 [1007357][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145704 [1007364][E](PTable): New Entry Processed in 35 ms + 145705 [1007364][E](PTable): Power Buffer Reset + 145706 [1007364][E](ERG_Mode): Watts previously processed. + 145707 [1008429][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 183, Cad 87, HR 152, Gear 12, Res 46, Current Pos 13574, Target Pos 13574 + 145708 [1010146][E](ERG_Mode): Watts previously processed. + 145709 [1012257][E](ERG_Mode): Watts previously processed. + 145710 [1012961][E](ERG_Mode): Proportional: 1.000000 + 145711 [1013667][E](PTable): Averaged Entry: watts=195.100006, cad=87.400002, targetPosition=1358.800049, (5)(7) + 145712 [1013669][E](PTData): Cleaned 235 readings + 145713 [1013679][E](PTData): Existing entry averaged (5)(7)(1393), readings(16) + 145714 [1013680][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145715 [1013695][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145716 [1013702][E](PTable): New Entry Processed in 35 ms + 145717 [1013702][E](PTable): Power Buffer Reset + 145718 [1014371][E](ERG_Mode): Watts previously processed. + 145719 [1014442][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 196, Cad 87, HR 151, Gear 12, Res 46, Current Pos 13597, Target Pos 13597 + 145720 [1016492][E](ERG_Mode): Watts previously processed. + 145721 [1018605][E](ERG_Mode): Proportional: -4.000000 + 145722 [1019309][E](ERG_Mode): Watts previously processed. + 145723 [1020015][E](PTable): Averaged Entry: watts=196.000000, cad=86.300003, targetPosition=1359.400024, (5)(7) + 145724 [1020017][E](PTData): Cleaned 235 readings + 145725 [1020027][E](PTData): Existing entry averaged (5)(7)(1391), readings(17) + 145726 [1020028][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145727 [1020043][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145728 [1020050][E](PTable): New Entry Processed in 35 ms + 145729 [1020050][E](PTable): Power Buffer Reset + 145730 [1020454][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 209, Cad 88, HR 151, Gear 12, Res 46, Current Pos 13595, Target Pos 13595 + 145731 [1022142][E](ERG_Mode): Watts previously processed. + 145732 [1024262][E](ERG_Mode): Watts previously processed. + 145733 [1024967][E](ERG_Mode): Proportional: -2.000000 + 145734 [1026386][E](PTable): Averaged Entry: watts=206.800003, cad=88.900002, targetPosition=1347.199951, (6)(7) + 145735 [1026387][E](PTData): Cleaned 235 readings + 145736 [1026397][E](PTData): Existing entry averaged (6)(7)(1322), readings(9) + 145737 [1026398][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145738 [1026413][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145739 [1026420][E](PTable): New Entry Processed in 35 ms + 145740 [1026420][E](PTable): Power Buffer Reset + 145741 [1026420][E](ERG_Mode): Watts previously processed. + 145742 [1026472][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 198, Cad 88, HR 150, Gear 12, Res 45, Current Pos 13395, Target Pos 13395 + 145743 [1028505][E](ERG_Mode): Watts previously processed. + 145744 [1030619][E](ERG_Mode): Proportional: 0.000000 + 145745 [1031325][E](ERG_Mode): Watts previously processed. + 145746 [1031326][E](PTable): Using detected travel limits during homing + 145747 [1032486][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 189, Cad 87, HR 150, Gear 12, Res 45, Current Pos 13447, Target Pos 13447 + 145748 [1032737][E](PTable): Averaged Entry: watts=192.000000, cad=87.800003, targetPosition=1339.800049, (5)(6) + 145749 [1032739][E](PTData): Cleaned 235 readings + 145750 [1032749][E](PTData): Existing entry averaged (5)(6)(1334), readings(20) + 145751 [1032750][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145752 [1032765][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145753 [1032772][E](PTable): New Entry Processed in 35 ms + 145754 [1032772][E](PTable): Power Buffer Reset + 145755 [1034152][E](ERG_Mode): Watts previously processed. + 145756 [1036261][E](ERG_Mode): Watts previously processed. + 145757 [1036966][E](ERG_Mode): Proportional: 7.000000 + 145758 [1038382][E](ERG_Mode): Watts previously processed. + 145759 [1038504][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 197, Cad 86, HR 150, Gear 12, Res 46, Current Pos 13511, Target Pos 13511 + 145760 [1039091][E](PTable): Averaged Entry: watts=189.000000, cad=86.400002, targetPosition=1348.099976, (5)(6) + 145761 [1039093][E](PTData): Cleaned 235 readings + 145762 [1039103][E](PTData): Existing entry averaged (5)(6)(1334), readings(20) + 145763 [1039104][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145764 [1039119][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145765 [1039126][E](PTable): New Entry Processed in 35 ms + 145766 [1039126][E](PTable): Power Buffer Reset + 145767 [1040498][E](ERG_Mode): Watts previously processed. + 145768 [1042611][E](ERG_Mode): Proportional: 72.000000 + 145769 [1043315][E](ERG_Mode): Watts previously processed. + 145770 [1044514][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 185, Cad 84, HR 150, Gear 12, Res 46, Current Pos 13680, Target Pos 13680 + 145771 [1045428][E](PTable): Averaged Entry: watts=182.600006, cad=85.500000, targetPosition=1358.000000, (5)(6) + 145772 [1045430][E](PTData): Cleaned 235 readings + 145773 [1045440][E](PTData): Existing entry averaged (5)(6)(1335), readings(20) + 145774 [1045441][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145775 [1045456][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145776 [1045463][E](PTable): New Entry Processed in 35 ms + 145777 [1045463][E](PTable): Power Buffer Reset + 145778 [1045463][E](ERG_Mode): Watts previously processed. + 145779 [1047551][E](ERG_Mode): Watts previously processed. + 145780 [1048257][E](ERG_Mode): Proportional: 9.000000 + 145781 [1050371][E](ERG_Mode): Watts previously processed. + 145782 [1050533][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 188, Cad 84, HR 150, Gear 12, Res 46, Current Pos 13778, Target Pos 13778 + 145783 [1051783][E](PTable): Averaged Entry: watts=187.800003, cad=84.400002, targetPosition=1374.699951, (5)(6) + 145784 [1051785][E](PTData): Cleaned 235 readings + 145785 [1051795][E](PTData): Existing entry averaged (5)(6)(1336), readings(20) + 145786 [1051796][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145787 [1051811][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145788 [1051818][E](PTable): New Entry Processed in 35 ms + 145789 [1051819][E](PTable): Power Buffer Reset + 145790 [1053191][E](ERG_Mode): Watts previously processed. + 145791 [1053899][E](ERG_Mode): Proportional: -2.000000 + 145792 [1053984][E](FTMS_SERVER): 05 d2 00 -> ERG Mode Target: 210 Current: 197 Incline: 137.759995. Responding: 80 05 01 + 145793 [1053990][E](DirConManager): Sending response message type 0x04 to client 0 + 145794 [1055305][E](ERG_Mode): Watts previously processed. + 145795 [1056547][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 200, Cad 86, HR 148, Gear 12, Res 47, Current Pos 13860, Target Pos 13860 + 145796 [1057422][E](ERG_Mode): Watts previously processed. + 145797 [1058127][E](PTable): Averaged Entry: watts=197.399994, cad=85.699997, targetPosition=1380.900024, (5)(7) + 145798 [1058129][E](PTData): Cleaned 235 readings + 145799 [1058139][E](PTData): Existing entry averaged (5)(7)(1390), readings(18) + 145800 [1058140][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145801 [1058155][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145802 [1058164][E](PTable): New Entry Processed in 37 ms + 145803 [1058165][E](PTable): Power Buffer Reset + 145804 [1059539][E](ERG_Mode): Watts previously processed. + 145805 [1060246][E](ERG_Mode): Proportional: -1.000000 + 145806 [1062378][E](ERG_Mode): Watts previously processed. + 145807 [1062559][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 208, Cad 87, HR 147, Gear 12, Res 47, Current Pos 13941, Target Pos 13941 + 145808 [1064500][E](PTable): Averaged Entry: watts=207.100006, cad=86.199997, targetPosition=1393.199951, (5)(7) + 145809 [1064502][E](PTData): Cleaned 235 readings + 145810 [1064513][E](PTData): Existing entry averaged (5)(7)(1390), readings(19) + 145811 [1064514][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145812 [1064528][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145813 [1064535][E](PTable): New Entry Processed in 35 ms + 145814 [1064535][E](PTable): Power Buffer Reset + 145815 [1064536][E](ERG_Mode): Watts previously processed. + 145816 [1065915][E](ERG_Mode): Proportional: -30.000000 + 145817 [1067324][E](ERG_Mode): Watts previously processed. + 145818 [1067325][E](PTable): Using detected travel limits during homing + 145819 [1068576][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 198, Cad 86, HR 147, Gear 12, Res 47, Current Pos 13883, Target Pos 13883 + 145820 [1069440][E](ERG_Mode): Watts previously processed. + 145821 [1070851][E](PTable): Averaged Entry: watts=208.500000, cad=87.000000, targetPosition=1391.099976, (5)(7) + 145822 [1070853][E](PTData): Cleaned 235 readings + 145823 [1070863][E](PTData): Existing entry averaged (5)(7)(1390), readings(20) + 145824 [1070864][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145825 [1070879][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145826 [1070886][E](PTable): New Entry Processed in 35 ms + 145827 [1070886][E](PTable): Power Buffer Reset + 145828 [1071554][E](ERG_Mode): Watts previously processed. + 145829 [1072259][E](ERG_Mode): Proportional: 36.000000 + 145830 [1073675][E](ERG_Mode): Watts previously processed. + 145831 [1074591][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 213, Cad 85, HR 147, Gear 12, Res 47, Current Pos 14029, Target Pos 14029 + 145832 [1077199][E](PTable): Averaged Entry: watts=204.600006, cad=85.000000, targetPosition=1402.199951, (5)(7) + 145833 [1077200][E](PTData): Cleaned 235 readings + 145834 [1077210][E](PTData): Existing entry averaged (5)(7)(1390), readings(20) + 145835 [1077211][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145836 [1077226][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145837 [1077233][E](PTable): New Entry Processed in 35 ms + 145838 [1077233][E](PTable): Power Buffer Reset + 145839 [1077233][E](ERG_Mode): Watts previously processed. + 145840 [1077903][E](ERG_Mode): Proportional: 30.000000 + 145841 [1079318][E](ERG_Mode): Watts previously processed. + 145842 [1080606][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 211, Cad 83, HR 148, Gear 12, Res 47, Current Pos 14087, Target Pos 14087 + 145843 [1081428][E](ERG_Mode): Watts previously processed. + 145844 [1083542][E](PTable): Averaged Entry: watts=205.300003, cad=83.500000, targetPosition=1407.300049, (5)(7) + 145845 [1083544][E](PTData): Cleaned 235 readings + 145846 [1083554][E](PTData): Existing entry averaged (5)(7)(1390), readings(20) + 145847 [1083555][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145848 [1083570][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145849 [1083577][E](PTable): New Entry Processed in 35 ms + 145850 [1083577][E](PTable): Power Buffer Reset + 145851 [1083578][E](ERG_Mode): Watts previously processed. + 145852 [1084246][E](ERG_Mode): Proportional: 6.000000 + 145853 [1085656][E](ERG_Mode): Watts previously processed. + 145854 [1086622][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 201, Cad 84, HR 148, Gear 12, Res 48, Current Pos 14114, Target Pos 14114 + 145855 [1087770][E](ERG_Mode): Watts previously processed. + 145856 [1089883][E](PTable): Averaged Entry: watts=203.399994, cad=83.500000, targetPosition=1411.699951, (5)(7) + 145857 [1089885][E](PTData): Cleaned 235 readings + 145858 [1089895][E](PTData): Existing entry averaged (5)(7)(1391), readings(20) + 145859 [1089896][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145860 [1089911][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145861 [1089918][E](PTable): New Entry Processed in 35 ms + 145862 [1089918][E](PTable): Power Buffer Reset + 145863 [1089919][E](ERG_Mode): Proportional: 8.000000 + 145864 [1091296][E](ERG_Mode): Watts previously processed. + 145865 [1092632][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 214, Cad 83, HR 148, Gear 12, Res 48, Current Pos 14203, Target Pos 14203 + 145866 [1093416][E](ERG_Mode): Watts previously processed. + 145867 [1095528][E](ERG_Mode): Watts previously processed. + 145868 [1096233][E](PTable): Averaged Entry: watts=205.399994, cad=83.000000, targetPosition=1418.800049, (5)(7) + 145869 [1096235][E](PTData): Cleaned 235 readings + 145870 [1096245][E](PTData): Existing entry averaged (5)(7)(1392), readings(20) + 145871 [1096246][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145872 [1096261][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145873 [1096268][E](PTable): New Entry Processed in 35 ms + 145874 [1096268][E](PTable): Power Buffer Reset + 145875 [1096268][E](ERG_Mode): Proportional: 3.000000 + 145876 [1097642][E](ERG_Mode): Watts previously processed. + 145877 [1098642][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 212, Cad 84, HR 149, Gear 12, Res 48, Current Pos 14208, Target Pos 14208 + 145878 [1099766][E](ERG_Mode): Watts previously processed. + 145879 [1101177][E](ERG_Mode): Watts previously processed. + 145880 [1101894][E](ERG_Mode): Proportional: 42.000000 + 145881 [1102597][E](PTable): Averaged Entry: watts=206.399994, cad=83.300003, targetPosition=1420.400024, (5)(7) + 145882 [1102599][E](PTData): Cleaned 235 readings + 145883 [1102609][E](PTData): Existing entry averaged (5)(7)(1393), readings(20) + 145884 [1102610][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145885 [1102625][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145886 [1102632][E](PTable): New Entry Processed in 35 ms + 145887 [1102632][E](PTable): Power Buffer Reset + 145888 [1103301][E](ERG_Mode): Watts previously processed. + 145889 [1103302][E](PTable): Using detected travel limits during homing + 145890 [1104651][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 194, Cad 81, HR 150, Gear 12, Res 48, Current Pos 14325, Target Pos 14325 + 145891 [1105417][E](ERG_Mode): Watts previously processed. + 145892 [1107529][E](ERG_Mode): Watts previously processed. + 145893 [1108238][E](ERG_Mode): Proportional: 0.000000 + 145894 [1108947][E](PTable): Averaged Entry: watts=199.800003, cad=81.300003, targetPosition=1435.000000, (4)(7) + 145895 [1108949][E](PTData): Cleaned 235 readings + 145896 [1108960][E](PTData): Existing entry averaged (4)(7)(1440), readings(19) + 145897 [1108960][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145898 [1108975][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145899 [1108982][E](PTable): New Entry Processed in 35 ms + 145900 [1108982][E](PTable): Power Buffer Reset + 145901 [1109649][E](ERG_Mode): Watts previously processed. + 145902 [1110666][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 208, Cad 82, HR 150, Gear 12, Res 49, Current Pos 14425, Target Pos 14425 + 145903 [1111769][E](ERG_Mode): Watts previously processed. + 145904 [1113881][E](ERG_Mode): Proportional: -7.000000 + 145905 [1115290][E](PTable): Averaged Entry: watts=212.300003, cad=82.900002, targetPosition=1441.500000, (4)(7) + 145906 [1115292][E](PTData): Cleaned 235 readings + 145907 [1115302][E](PTData): Existing entry averaged (4)(7)(1440), readings(20) + 145908 [1115303][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145909 [1115318][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145910 [1115325][E](PTable): New Entry Processed in 35 ms + 145911 [1115325][E](PTable): Power Buffer Reset + 145912 [1115325][E](ERG_Mode): Watts previously processed. + 145913 [1116681][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 224, Cad 85, HR 152, Gear 12, Res 48, Current Pos 14373, Target Pos 14373 + 145914 [1117404][E](ERG_Mode): Watts previously processed. + 145915 [1119526][E](ERG_Mode): Watts previously processed. + 145916 [1120232][E](ERG_Mode): Proportional: 1.000000 + 145917 [1121642][E](PTable): Averaged Entry: watts=216.500000, cad=84.500000, targetPosition=1432.900024, (5)(7) + 145918 [1121643][E](PTData): Cleaned 235 readings + 145919 [1121653][E](PTData): Existing entry averaged (5)(7)(1394), readings(20) + 145920 [1121654][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145921 [1121669][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145922 [1121676][E](PTable): New Entry Processed in 35 ms + 145923 [1121676][E](PTable): Power Buffer Reset + 145924 [1121676][E](ERG_Mode): Watts previously processed. + 145925 [1122696][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 210, Cad 83, HR 153, Gear 12, Res 48, Current Pos 14299, Target Pos 14299 + 145926 [1123760][E](ERG_Mode): Watts previously processed. + 145927 [1125873][E](ERG_Mode): Proportional: 3.000000 + 145928 [1127291][E](ERG_Mode): Watts previously processed. + 145929 [1127995][E](PTable): Averaged Entry: watts=208.899994, cad=82.900002, targetPosition=1429.500000, (4)(7) + 145930 [1127997][E](PTData): Cleaned 235 readings + 145931 [1128008][E](PTData): Existing entry averaged (4)(7)(1439), readings(20) + 145932 [1128009][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145933 [1128023][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 145934 [1128030][E](PTable): New Entry Processed in 35 ms + 145935 [1128030][E](PTable): Power Buffer Reset + 145936 [1128706][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 206, Cad 83, HR 155, Gear 12, Res 48, Current Pos 14312, Target Pos 14312 + 145937 [1129409][E](ERG_Mode): Watts previously processed. + 145938 [1131519][E](ERG_Mode): Watts previously processed. + 145939 [1132223][E](ERG_Mode): Proportional: 30.000000 + 145940 [1133641][E](ERG_Mode): Watts previously processed. + 145941 [1134348][E](PTable): Averaged Entry: watts=217.000000, cad=84.599998, targetPosition=1426.900024, (5)(7) + 145942 [1134352][E](PTData): Cleaned 235 readings + 145943 [1134362][E](PTData): Existing entry averaged (5)(7)(1395), readings(20) + 145944 [1134363][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145945 [1134378][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145946 [1134385][E](PTable): New Entry Processed in 38 ms + 145947 [1134385][E](PTable): Power Buffer Reset + 145948 [1134716][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 220, Cad 85, HR 156, Gear 12, Res 48, Current Pos 14191, Target Pos 14191 + 145949 [1135758][E](ERG_Mode): Watts previously processed. + 145950 [1137870][E](ERG_Mode): Proportional: -3.000000 + 145951 [1139279][E](ERG_Mode): Watts previously processed. + 145952 [1139280][E](PTable): Using detected travel limits during homing + 145953 [1140701][E](PTable): Averaged Entry: watts=214.000000, cad=85.400002, targetPosition=1416.900024, (5)(7) + 145954 [1140702][E](PTData): Cleaned 235 readings + 145955 [1140712][E](PTData): Existing entry averaged (5)(7)(1396), readings(20) + 145956 [1140713][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145957 [1140728][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145958 [1140735][E](PTable): New Entry Processed in 35 ms + 145959 [1140735][E](PTable): Power Buffer Reset + 145960 [1140736][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 205, Cad 84, HR 156, Gear 12, Res 48, Current Pos 14152, Target Pos 14152 + 145961 [1141405][E](ERG_Mode): Watts previously processed. + 145962 [1143522][E](ERG_Mode): Watts previously processed. + 145963 [1144228][E](ERG_Mode): Proportional: -51.000000 + 145964 [1145639][E](ERG_Mode): Watts previously processed. + 145965 [1146756][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 199, Cad 85, HR 156, Gear 12, Res 47, Current Pos 13980, Target Pos 13980 + 145966 [1147054][E](PTable): Averaged Entry: watts=215.500000, cad=86.000000, targetPosition=1402.800049, (5)(7) + 145967 [1147055][E](PTData): Cleaned 235 readings + 145968 [1147065][E](PTData): Existing entry averaged (5)(7)(1396), readings(20) + 145969 [1147066][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145970 [1147081][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145971 [1147088][E](PTable): New Entry Processed in 35 ms + 145972 [1147088][E](PTable): Power Buffer Reset + 145973 [1147756][E](ERG_Mode): Watts previously processed. + 145974 [1149869][E](ERG_Mode): Proportional: 8.000000 + 145975 [1151277][E](ERG_Mode): Watts previously processed. + 145976 [1152770][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 208, Cad 85, HR 156, Gear 12, Res 48, Current Pos 14116, Target Pos 14116 + 145977 [1153406][E](PTable): Averaged Entry: watts=201.899994, cad=84.199997, targetPosition=1407.099976, (5)(7) + 145978 [1153407][E](PTData): Cleaned 235 readings + 145979 [1153417][E](PTData): Existing entry averaged (5)(7)(1396), readings(20) + 145980 [1153418][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145981 [1153433][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145982 [1153440][E](PTable): New Entry Processed in 35 ms + 145983 [1153440][E](PTable): Power Buffer Reset + 145984 [1153441][E](ERG_Mode): Watts previously processed. + 145985 [1155514][E](ERG_Mode): Watts previously processed. + 145986 [1156220][E](ERG_Mode): Proportional: -1.000000 + 145987 [1157632][E](ERG_Mode): Watts previously processed. + 145988 [1158784][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 218, Cad 87, HR 155, Gear 12, Res 47, Current Pos 14072, Target Pos 14072 + 145989 [1159752][E](PTable): Averaged Entry: watts=215.500000, cad=85.599998, targetPosition=1408.300049, (5)(7) + 145990 [1159753][E](PTData): Cleaned 235 readings + 145991 [1159763][E](PTData): Existing entry averaged (5)(7)(1396), readings(20) + 145992 [1159764][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 145993 [1159779][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 145994 [1159786][E](PTable): New Entry Processed in 35 ms + 145995 [1159786][E](PTable): Power Buffer Reset + 145996 [1159786][E](ERG_Mode): Watts previously processed. + 145997 [1161861][E](ERG_Mode): Watts previously processed. + 145998 [1162571][E](ERG_Mode): Proportional: -1.000000 + 145999 [1163278][E](ERG_Mode): Watts previously processed. + 146000 [1164798][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 221, Cad 86, HR 154, Gear 12, Res 47, Current Pos 14057, Target Pos 14045 + 146001 [1165392][E](ERG_Mode): Watts previously processed. + 146002 [1166096][E](PTable): Averaged Entry: watts=208.800003, cad=85.199997, targetPosition=1406.400024, (5)(7) + 146003 [1166098][E](PTData): Cleaned 235 readings + 146004 [1166108][E](PTData): Existing entry averaged (5)(7)(1396), readings(20) + 146005 [1166109][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146006 [1166124][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 146007 [1166130][E](PTable): New Entry Processed in 34 ms + 146008 [1166131][E](PTable): Power Buffer Reset + 146009 [1167504][E](ERG_Mode): Watts previously processed. + 146010 [1168209][E](ERG_Mode): Proportional: 6.000000 + 146011 [1169627][E](ERG_Mode): Watts previously processed. + 146012 [1170815][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 210, Cad 84, HR 153, Gear 12, Res 48, Current Pos 14097, Target Pos 14097 + 146013 [1171740][E](ERG_Mode): Watts previously processed. + 146014 [1172449][E](PTable): Averaged Entry: watts=204.100006, cad=84.400002, targetPosition=1407.900024, (5)(7) + 146015 [1172450][E](PTData): Cleaned 235 readings + 146016 [1172460][E](PTData): Existing entry averaged (5)(7)(1396), readings(20) + 146017 [1172461][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146018 [1172476][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 146019 [1172483][E](PTable): New Entry Processed in 35 ms + 146020 [1172483][E](PTable): Power Buffer Reset + 146021 [1173858][E](ERG_Mode): Watts previously processed. + 146022 [1173997][E](FTMS_SERVER): 05 91 00 -> ERG Mode Target: 145 Current: 209 Incline: 141.089996. Responding: 80 05 01 + 146023 [1174002][E](DirConManager): Sending response message type 0x04 to client 0 + 146024 [1174564][E](ERG_Mode): SetPoint changed:175w Waiting:1020ms PowerTable Result: 12990 + 146025 [1176831][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 197, Cad 85, HR 154, Gear 12, Res 44, Current Pos 12990, Target Pos 12990 + 146026 [1176992][E](ERG_Mode): ERG wait expired, pos: 12990, tgt: 0 + 146027 [1176993][E](ERG_Mode): Proportional: -208.000000 + 146028 [1176994][E](PTable): Using detected travel limits during homing + 146029 [1178410][E](ERG_Mode): Watts previously processed. + 146030 [1180520][E](PTable): Averaged Entry: watts=185.600006, cad=85.400002, targetPosition=1327.699951, (5)(6) + 146031 [1180522][E](PTData): Cleaned 235 readings + 146032 [1180532][E](PTData): Existing entry averaged (5)(6)(1335), readings(20) + 146033 [1180533][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146034 [1180548][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 146035 [1180555][E](PTable): New Entry Processed in 35 ms + 146036 [1180555][E](PTable): Power Buffer Reset + 146037 [1180555][E](ERG_Mode): Watts previously processed. + 146038 [1182627][E](ERG_Mode): Watts previously processed. + 146039 [1182842][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 156, Cad 87, HR 154, Gear 12, Res 42, Current Pos 12482, Target Pos 12482 + 146040 [1183334][E](ERG_Mode): Proportional: -33.000000 + 146041 [1184751][E](ERG_Mode): Watts previously processed. + 146042 [1186868][E](PTable): Averaged Entry: watts=157.399994, cad=87.199997, targetPosition=1247.000000, (5)(5) + 146043 [1186870][E](PTData): Cleaned 235 readings + 146044 [1186880][E](PTData): Existing entry averaged (5)(5)(1243), readings(2) + 146045 [1186881][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146046 [1186896][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 146047 [1186903][E](PTable): New Entry Processed in 35 ms + 146048 [1186903][E](PTable): Power Buffer Reset + 146049 [1188282][E](ERG_Mode): Watts previously processed. + 146050 [1188861][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 148, Cad 88, HR 153, Gear 12, Res 41, Current Pos 12289, Target Pos 12289 + 146051 [1188991][E](ERG_Mode): Proportional: -3.000000 + 146052 [1190400][E](ERG_Mode): Watts previously processed. + 146053 [1192510][E](ERG_Mode): Watts previously processed. + 146054 [1193225][E](PTable): Averaged Entry: watts=149.800003, cad=87.400002, targetPosition=1229.000000, (5)(5) + 146055 [1193228][E](PTData): Cleaned 235 readings + 146056 [1193238][E](PTData): Existing entry averaged (5)(5)(1239), readings(3) + 146057 [1193239][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146058 [1193254][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 146059 [1193261][E](PTable): New Entry Processed in 36 ms + 146060 [1193261][E](PTable): Power Buffer Reset + 146061 [1194636][E](ERG_Mode): Watts previously processed. + 146062 [1194872][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 147, Cad 88, HR 151, Gear 12, Res 41, Current Pos 12252, Target Pos 12252 + 146063 [1195345][E](ERG_Mode): Proportional: -2.000000 + 146064 [1196761][E](ERG_Mode): Watts previously processed. + 146065 [1198169][E](ERG_Mode): Watts previously processed. + 146066 [1199579][E](PTable): Averaged Entry: watts=145.199997, cad=87.199997, targetPosition=1225.900024, (5)(5) + 146067 [1199581][E](PTData): Cleaned 235 readings + 146068 [1199591][E](PTData): Existing entry averaged (5)(5)(1236), readings(4) + 146069 [1199592][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146070 [1199607][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 146071 [1199614][E](PTable): New Entry Processed in 35 ms + 146072 [1199614][E](PTable): Power Buffer Reset + 146073 [1200284][E](ERG_Mode): Watts previously processed. + 146074 [1200881][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 139, Cad 86, HR 150, Gear 12, Res 41, Current Pos 12271, Target Pos 12271 + 146075 [1200991][E](ERG_Mode): Proportional: 6.000000 + 146076 [1202407][E](ERG_Mode): Watts previously processed. + 146077 [1204526][E](ERG_Mode): Watts previously processed. + 146078 [1205947][E](PTable): Averaged Entry: watts=140.899994, cad=85.900002, targetPosition=1227.900024, (5)(5) + 146079 [1205949][E](PTData): Cleaned 235 readings + 146080 [1205959][E](PTData): Existing entry averaged (5)(5)(1234), readings(5) + 146081 [1205960][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146082 [1205975][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 146083 [1205982][E](PTable): New Entry Processed in 35 ms + 146084 [1205982][E](PTable): Power Buffer Reset + 146085 [1206650][E](ERG_Mode): Watts previously processed. + 146086 [1206895][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 148, Cad 86, HR 148, Gear 12, Res 41, Current Pos 12288, Target Pos 12288 + 146087 [1207359][E](ERG_Mode): Proportional: -3.000000 + 146088 [1208768][E](ERG_Mode): Watts previously processed. + 146089 [1212287][E](PTable): Averaged Entry: watts=147.399994, cad=86.599998, targetPosition=1227.500000, (5)(5) + 146090 [1212289][E](PTData): Cleaned 235 readings + 146091 [1212299][E](PTData): Existing entry averaged (5)(5)(1233), readings(6) + 146092 [1212300][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146093 [1212315][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 146094 [1212321][E](PTable): New Entry Processed in 34 ms + 146095 [1212322][E](PTable): Power Buffer Reset + 146096 [1212322][E](ERG_Mode): Watts previously processed. + 146097 [1212905][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 134, Cad 87, HR 146, Gear 12, Res 41, Current Pos 12268, Target Pos 12268 + 146098 [1212996][E](ERG_Mode): Proportional: 33.000000 + 146099 [1212997][E](PTable): Using detected travel limits during homing + 146100 [1214413][E](ERG_Mode): Watts previously processed. + 146101 [1216532][E](ERG_Mode): Watts previously processed. + 146102 [1218654][E](PTable): Averaged Entry: watts=138.100006, cad=85.800003, targetPosition=1231.800049, (5)(5) + 146103 [1218656][E](PTData): Cleaned 235 readings + 146104 [1218666][E](PTData): Existing entry averaged (5)(5)(1232), readings(7) + 146105 [1218667][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146106 [1218682][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 5 ms + 146107 [1218689][E](PTable): New Entry Processed in 35 ms + 146108 [1218689][E](PTable): Power Buffer Reset + 146109 [1218689][E](ERG_Mode): Watts previously processed. + 146110 [1218919][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 149, Cad 87, HR 144, Gear 12, Res 42, Current Pos 12349, Target Pos 12349 + 146111 [1219365][E](ERG_Mode): Proportional: -4.000000 + 146112 [1220779][E](ERG_Mode): Watts previously processed. + 146113 [1224294][E](ERG_Mode): Watts previously processed. + 146114 [1224929][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 145, Cad 88, HR 143, Gear 12, Res 42, Current Pos 12339, Target Pos 12339 + 146115 [1225000][E](PTable): Averaged Entry: watts=146.600006, cad=87.400002, targetPosition=1233.800049, (5)(5) + 146116 [1225002][E](PTData): Cleaned 235 readings + 146117 [1225012][E](PTData): Existing entry averaged (5)(5)(1232), readings(8) + 146118 [1225013][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146119 [1225027][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 146120 [1225034][E](PTable): New Entry Processed in 34 ms + 146121 [1225035][E](PTable): Power Buffer Reset + 146122 [1225035][E](ERG_Mode): Proportional: 0.000000 + 146123 [1226409][E](ERG_Mode): Watts previously processed. + 146124 [1228527][E](ERG_Mode): Watts previously processed. + 146125 [1230636][E](ERG_Mode): Watts previously processed. + 146126 [1230945][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 151, Cad 88, HR 142, Gear 12, Res 41, Current Pos 12298, Target Pos 12298 + 146127 [1231346][E](PTable): Averaged Entry: watts=148.699997, cad=88.500000, targetPosition=1231.199951, (6)(5) + 146128 [1231348][E](PTData): Cleaned 235 readings + 146129 [1231359][E](PTData): Existing entry averaged (6)(5)(1194), readings(18) + 146130 [1231360][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146131 [1231374][E](PTData): Fit Valid: 1, N: 65, Quad: 1, Time: 4 ms + 146132 [1231381][E](PTable): New Entry Processed in 35 ms + 146133 [1231381][E](PTable): Power Buffer Reset + 146134 [1231382][E](ERG_Mode): Proportional: -6.000000 + 146135 [1232757][E](ERG_Mode): Watts previously processed. + 146136 [1234001][E](FTMS_SERVER): 05 f4 01 -> ERG Mode Target: 500 Current: 150 Incline: 121.480003. Responding: 80 05 01 + 146137 [1234007][E](DirConManager): Sending response message type 0x04 to client 0 + 146138 [1234172][E](ERG_Mode): SetPoint changed:470w Waiting:2458ms PowerTable Result: 18300 + 146139 [1236957][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 207, Cad 98, HR 140, Gear 12, Res 60, Current Pos 18273, Target Pos 18300 + 146140 [1238034][E](ERG_Mode): ERG wait expired, pos: 18300, tgt: 0 + 146141 [1238035][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 146142 [1238045][E](PTable): Power Buffer Reset + 146143 [1238046][E](ERG_Mode): Proportional: 880.000000 + 146144 [1239448][E](ERG_Mode): Watts previously processed. + 146145 [1241561][E](ERG_Mode): Watts previously processed. + 146146 [1242972][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 521, Cad 88, HR 139, Gear 12, Res 63, Current Pos 18746, Target Pos 18746 + 146147 [1243675][E](ERG_Mode): Watts previously processed. + 146148 [1244381][E](PTable): Averaged Entry: watts=509.100006, cad=91.300003, targetPosition=1891.599976, (6)(17) + 146149 [1244383][E](PTData): Cleaned 235 readings + 146150 [1244393][E](PTData): New entry recorded (6)(17)(1891) + 146151 [1244394][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146152 [1244409][E](PTData): Fit Valid: 1, N: 66, Quad: 1, Time: 5 ms + 146153 [1244416][E](PTable): New Entry Processed in 35 ms + 146154 [1244457][E](PTable): Writing File: /PowerTable.txt + 146155 [1244688][E](PTable): Power table saved successfully with 722 readings + 146156 [1244688][E](PTable): Power Buffer Reset + 146157 [1244688][E](ERG_Mode): Proportional: -147.000000 + 146158 [1246498][E](ERG_Mode): Watts previously processed. + 146159 [1248609][E](ERG_Mode): Watts previously processed. + 146160 [1248984][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 482, Cad 86, HR 142, Gear 12, Res 63, Current Pos 18603, Target Pos 18603 + 146161 [1250020][E](ERG_Mode): Proportional: 87.000000 + 146162 [1250724][E](PTable): Averaged Entry: watts=490.000000, cad=86.000000, targetPosition=1858.699951, (5)(16) + 146163 [1250726][E](PTData): Cleaned 234 readings + 146164 [1250736][E](PTData): New entry recorded (5)(16)(1858) + 146165 [1250737][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146166 [1250747][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146167 [1250752][E](PTData): Fit Valid: 1, N: 67, Quad: 1, Time: 4 ms + 146168 [1250769][E](PTable): New Entry Processed in 45 ms + 146169 [1250769][E](PTable): Power Buffer Reset + 146170 [1250770][E](ERG_Mode): Watts previously processed. + 146171 [1252137][E](PTable): Using detected travel limits during homing + 146172 [1253553][E](ERG_Mode): Watts previously processed. + 146173 [1254999][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 476, Cad 84, HR 150, Gear 12, Res 65, Current Pos 19212, Target Pos 19280 + 146174 [1255662][E](ERG_Mode): Watts previously processed. + 146175 [1256371][E](ERG_Mode): Proportional: 90.000000 + 146176 [1257078][E](PTable): Averaged Entry: watts=470.799988, cad=84.099998, targetPosition=1908.800049, (5)(16) + 146177 [1257080][E](PTData): Cleaned 233 readings + 146178 [1257091][E](PTData): Existing entry averaged (5)(16)(1876), readings(2) + 146179 [1257091][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146180 [1257102][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146181 [1257117][E](PTData): Fit Valid: 1, N: 67, Quad: 1, Time: 5 ms + 146182 [1257124][E](PTable): New Entry Processed in 46 ms + 146183 [1257124][E](PTable): Power Buffer Reset + 146184 [1258497][E](ERG_Mode): Watts previously processed. + 146185 [1260606][E](ERG_Mode): Watts previously processed. + 146186 [1261013][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 463, Cad 82, HR 158, Gear 12, Res 66, Current Pos 19522, Target Pos 19522 + 146187 [1262019][E](ERG_Mode): Proportional: 30.000000 + 146188 [1263428][E](PTable): Averaged Entry: watts=475.700012, cad=81.900002, targetPosition=1950.400024, (4)(16) + 146189 [1263430][E](PTData): Cleaned 233 readings + 146190 [1263440][E](PTData): New entry recorded (4)(16)(1950) + 146191 [1263441][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146192 [1263452][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146193 [1263456][E](PTData): Fit Valid: 1, N: 68, Quad: 1, Time: 4 ms + 146194 [1263463][E](PTable): New Entry Processed in 35 ms + 146195 [1263464][E](PTable): Power Buffer Reset + 146196 [1263474][E](ERG_Mode): Watts previously processed. + 146197 [1263997][E](FTMS_SERVER): 05 a0 00 -> ERG Mode Target: 160 Current: 485 Incline: 198.039993. Responding: 80 05 01 + 146198 [1264004][E](DirConManager): Sending response message type 0x04 to client 0 + 146199 [1264138][E](ERG_Mode): SetPoint changed:190w Waiting:2410ms PowerTable Result: 13820 + 146200 [1267026][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 331, Cad 81, HR 158, Gear 12, Res 47, Current Pos 13820, Target Pos 13820 + 146201 [1267952][E](ERG_Mode): ERG wait expired, pos: 13820, tgt: 0 + 146202 [1267953][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 146203 [1267963][E](PTable): Power Buffer Reset + 146204 [1267964][E](ERG_Mode): Proportional: -388.000000 + 146205 [1268661][E](ERG_Mode): Watts previously processed. + 146206 [1270770][E](ERG_Mode): Watts previously processed. + 146207 [1272890][E](ERG_Mode): Watts previously processed. + 146208 [1273037][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 174, Cad 84, HR 163, Gear 12, Res 44, Current Pos 13085, Target Pos 13085 + 146209 [1273593][E](ERG_Mode): Proportional: -42.000000 + 146210 [1274299][E](PTable): Averaged Entry: watts=197.399994, cad=82.800003, targetPosition=1321.900024, (4)(7) + 146211 [1274301][E](PTData): Cleaned 232 readings + 146212 [1274311][E](PTData): Existing entry averaged (4)(7)(1433), readings(20) + 146213 [1274312][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146214 [1274323][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146215 [1274337][E](PTData): Fit Valid: 1, N: 68, Quad: 1, Time: 4 ms + 146216 [1274344][E](PTable): New Entry Processed in 45 ms + 146217 [1274344][E](PTable): Power Buffer Reset + 146218 [1276414][E](ERG_Mode): Watts previously processed. + 146219 [1278524][E](ERG_Mode): Watts previously processed. + 146220 [1279050][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 153, Cad 80, HR 168, Gear 12, Res 44, Current Pos 13107, Target Pos 13107 + 146221 [1279233][E](ERG_Mode): Proportional: 7.000000 + 146222 [1280648][E](PTable): Averaged Entry: watts=151.600006, cad=81.099998, targetPosition=1308.300049, (4)(5) + 146223 [1280649][E](PTData): Cleaned 232 readings + 146224 [1280660][E](PTData): Existing entry averaged (4)(5)(1314), readings(3) + 146225 [1280661][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146226 [1280671][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146227 [1280686][E](PTData): Fit Valid: 1, N: 68, Quad: 1, Time: 5 ms + 146228 [1280693][E](PTable): New Entry Processed in 46 ms + 146229 [1280693][E](PTable): Power Buffer Reset + 146230 [1280693][E](ERG_Mode): Watts previously processed. + 146231 [1282768][E](ERG_Mode): Watts previously processed. + 146232 [1284891][E](ERG_Mode): Watts previously processed. + 146233 [1285067][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 166, Cad 82, HR 172, Gear 12, Res 44, Current Pos 13207, Target Pos 13207 + 146234 [1285594][E](ERG_Mode): Proportional: -6.000000 + 146235 [1287004][E](PTable): Averaged Entry: watts=159.500000, cad=81.800003, targetPosition=1316.300049, (4)(5) + 146236 [1287005][E](PTData): Cleaned 232 readings + 146237 [1287016][E](PTData): Existing entry averaged (4)(5)(1314), readings(4) + 146238 [1287017][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146239 [1287027][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146240 [1287042][E](PTData): Fit Valid: 1, N: 68, Quad: 1, Time: 5 ms + 146241 [1287049][E](PTable): New Entry Processed in 45 ms + 146242 [1287049][E](PTable): Power Buffer Reset + 146243 [1288416][E](ERG_Mode): Watts previously processed. + 146244 [1290539][E](ERG_Mode): Watts previously processed. + 146245 [1291078][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 173, Cad 86, HR 172, Gear 12, Res 44, Current Pos 12961, Target Pos 12961 + 146246 [1291240][E](ERG_Mode): Proportional: -39.000000 + 146247 [1291242][E](PTable): Using detected travel limits during homing + 146248 [1292657][E](ERG_Mode): Watts previously processed. + 146249 [1293364][E](PTable): Averaged Entry: watts=171.100006, cad=86.000000, targetPosition=1299.000000, (5)(6) + 146250 [1293366][E](PTData): Cleaned 232 readings + 146251 [1293378][E](PTData): Existing entry averaged (5)(6)(1333), readings(20) + 146252 [1293379][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146253 [1293390][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146254 [1293394][E](PTData): Fit Valid: 1, N: 68, Quad: 1, Time: 4 ms + 146255 [1293401][E](PTable): New Entry Processed in 37 ms + 146256 [1293401][E](PTable): Power Buffer Reset + 146257 [1294774][E](ERG_Mode): Watts previously processed. + 146258 [1296895][E](ERG_Mode): Watts previously processed. + 146259 [1297092][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 153, Cad 85, HR 171, Gear 12, Res 44, Current Pos 12917, Target Pos 12917 + 146260 [1297596][E](ERG_Mode): Proportional: 7.000000 + 146261 [1299711][E](PTable): Averaged Entry: watts=160.399994, cad=85.699997, targetPosition=1291.500000, (5)(5) + 146262 [1299713][E](PTData): Cleaned 232 readings + 146263 [1299723][E](PTData): Existing entry averaged (5)(5)(1237), readings(9) + 146264 [1299724][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146265 [1299735][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146266 [1299749][E](PTData): Fit Valid: 1, N: 68, Quad: 1, Time: 4 ms + 146267 [1299756][E](PTable): New Entry Processed in 45 ms + 146268 [1299757][E](PTable): Power Buffer Reset + 146269 [1300417][E](ERG_Mode): Watts previously processed. + 146270 [1302526][E](ERG_Mode): Watts previously processed. + 146271 [1303104][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 167, Cad 87, HR 171, Gear 12, Res 43, Current Pos 12904, Target Pos 12904 + 146272 [1303236][E](ERG_Mode): Proportional: -7.000000 + 146273 [1304643][E](ERG_Mode): Watts previously processed. + 146274 [1306056][E](PTable): Averaged Entry: watts=168.500000, cad=87.199997, targetPosition=1289.900024, (5)(6) + 146275 [1306057][E](PTData): Cleaned 232 readings + 146276 [1306067][E](PTData): Existing entry averaged (5)(6)(1330), readings(20) + 146277 [1306068][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146278 [1306079][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146279 [1306093][E](PTData): Fit Valid: 1, N: 68, Quad: 1, Time: 4 ms + 146280 [1306100][E](PTable): New Entry Processed in 45 ms + 146281 [1306101][E](PTable): Power Buffer Reset + 146282 [1306760][E](ERG_Mode): Watts previously processed. + 146283 [1308869][E](ERG_Mode): Watts previously processed. + 146284 [1309115][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 161, Cad 87, HR 171, Gear 12, Res 43, Current Pos 12812, Target Pos 12812 + 146285 [1309578][E](ERG_Mode): Proportional: -1.000000 + 146286 [1310992][E](ERG_Mode): Watts previously processed. + 146287 [1312404][E](PTable): Averaged Entry: watts=167.199997, cad=88.000000, targetPosition=1279.300049, (6)(6) + 146288 [1312406][E](PTData): Cleaned 232 readings + 146289 [1312416][E](PTData): Existing entry averaged (6)(6)(1272), readings(20) + 146290 [1312417][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146291 [1312427][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146292 [1312442][E](PTData): Fit Valid: 1, N: 68, Quad: 1, Time: 4 ms + 146293 [1312449][E](PTable): New Entry Processed in 45 ms + 146294 [1312449][E](PTable): Power Buffer Reset + 146295 [1312449][E](ERG_Mode): Watts previously processed. + 146296 [1314516][E](ERG_Mode): Watts previously processed. + 146297 [1315124][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 168, Cad 87, HR 168, Gear 12, Res 43, Current Pos 12759, Target Pos 12759 + 146298 [1315226][E](ERG_Mode): Proportional: -8.000000 + 146299 [1316636][E](ERG_Mode): Watts previously processed. + 146300 [1318752][E](PTable): Averaged Entry: watts=165.800003, cad=87.500000, targetPosition=1274.699951, (5)(6) + 146301 [1318754][E](PTData): Cleaned 232 readings + 146302 [1318764][E](PTData): Existing entry averaged (5)(6)(1327), readings(20) + 146303 [1318765][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146304 [1318780][E](PTData): Fit Valid: 1, N: 68, Quad: 1, Time: 4 ms + 146305 [1318787][E](PTable): New Entry Processed in 35 ms + 146306 [1318787][E](PTable): Power Buffer Reset + 146307 [1318788][E](ERG_Mode): Watts previously processed. + 146308 [1320870][E](ERG_Mode): Watts previously processed. + 146309 [1321137][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 177, Cad 89, HR 165, Gear 12, Res 43, Current Pos 12715, Target Pos 12715 + 146310 [1321574][E](ERG_Mode): Proportional: -51.000000 + 146311 [1322981][E](ERG_Mode): Watts previously processed. + 146312 [1324390][E](ERG_Mode): Watts previously processed. + 146313 [1325102][E](PTable): Averaged Entry: watts=174.100006, cad=89.900002, targetPosition=1265.400024, (6)(6) + 146314 [1325104][E](PTData): Cleaned 232 readings + 146315 [1325114][E](PTData): Existing entry averaged (6)(6)(1271), readings(20) + 146316 [1325115][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146317 [1325130][E](PTData): Fit Valid: 1, N: 68, Quad: 1, Time: 4 ms + 146318 [1325137][E](PTable): New Entry Processed in 35 ms + 146319 [1325137][E](PTable): Power Buffer Reset + 146320 [1325805][E](ERG_Mode): Watts previously processed. + 146321 [1327145][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 192, Cad 96, HR 162, Gear 12, Res 42, Current Pos 12397, Target Pos 12397 + 146322 [1327218][E](ERG_Mode): Proportional: -96.000000 + 146323 [1327220][E](PTable): Using detected travel limits during homing + 146324 [1328634][E](ERG_Mode): Watts previously processed. + 146325 [1330752][E](ERG_Mode): Watts previously processed. + 146326 [1331458][E](PTable): Averaged Entry: watts=185.899994, cad=95.199997, targetPosition=1228.699951, (7)(6) + 146327 [1331459][E](PTData): Cleaned 232 readings + 146328 [1331469][E](PTData): Existing entry averaged (7)(6)(1254), readings(3) + 146329 [1331470][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146330 [1331486][E](PTData): Fit Valid: 1, N: 68, Quad: 1, Time: 5 ms + 146331 [1331493][E](PTable): New Entry Processed in 36 ms + 146332 [1331493][E](PTable): Power Buffer Reset + 146333 [1332868][E](ERG_Mode): Watts previously processed. + 146334 [1333155][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 181, Cad 99, HR 158, Gear 12, Res 40, Current Pos 11959, Target Pos 11959 + 146335 [1333578][E](ERG_Mode): Proportional: -63.000000 + 146336 [1334997][E](ERG_Mode): Watts previously processed. + 146337 [1337815][E](PTable): Averaged Entry: watts=176.500000, cad=100.300003, targetPosition=1188.099976, (8)(6) + 146338 [1337817][E](PTData): Cleaned 232 readings + 146339 [1337827][E](PTData): New entry recorded (8)(6)(1188) + 146340 [1337828][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146341 [1337843][E](PTData): Fit Valid: 1, N: 69, Quad: 1, Time: 5 ms + 146342 [1337850][E](PTable): New Entry Processed in 36 ms + 146343 [1337850][E](PTable): Power Buffer Reset + 146344 [1338518][E](ERG_Mode): Watts previously processed. + 146345 [1339164][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 167, Cad 103, HR 157, Gear 12, Res 39, Current Pos 11736, Target Pos 11736 + 146346 [1339227][E](ERG_Mode): Proportional: -7.000000 + 146347 [1340633][E](ERG_Mode): Watts previously processed. + 146348 [1342753][E](ERG_Mode): Watts previously processed. + 146349 [1344166][E](PTable): Averaged Entry: watts=159.399994, cad=102.099998, targetPosition=1173.599976, (8)(5) + 146350 [1344168][E](PTData): Cleaned 231 readings + 146351 [1344178][E](PTData): Existing entry averaged (8)(5)(1163), readings(2) + 146352 [1344179][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146353 [1344194][E](PTData): Fit Valid: 1, N: 69, Quad: 1, Time: 4 ms + 146354 [1344201][E](PTable): New Entry Processed in 35 ms + 146355 [1344201][E](PTable): Power Buffer Reset + 146356 [1344869][E](ERG_Mode): Watts previously processed. + 146357 [1345177][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 157, Cad 102, HR 155, Gear 12, Res 40, Current Pos 11788, Target Pos 11788 + 146358 [1345579][E](ERG_Mode): Proportional: 3.000000 + 146359 [1346986][E](ERG_Mode): Watts previously processed. + 146360 [1350511][E](PTable): Averaged Entry: watts=158.300003, cad=102.000000, targetPosition=1176.300049, (8)(5) + 146361 [1350512][E](PTData): Cleaned 231 readings + 146362 [1350523][E](PTData): Existing entry averaged (8)(5)(1166), readings(3) + 146363 [1350523][E](PTData): Lower Up Found 7, 5, tp1165 + 146364 [1350534][E](PTable): New Entry Processed in 24 ms + 146365 [1350534][E](PTable): Power Buffer Reset + 146366 [1350535][E](ERG_Mode): Watts previously processed. + 146367 [1351195][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 156, Cad 101, HR 154, Gear 12, Res 40, Current Pos 11773, Target Pos 11773 + 146368 [1351215][E](ERG_Mode): Proportional: 4.000000 + 146369 [1352633][E](ERG_Mode): Watts previously processed. + 146370 [1354748][E](ERG_Mode): Watts previously processed. + 146371 [1356858][E](PTable): Averaged Entry: watts=153.800003, cad=101.699997, targetPosition=1180.699951, (8)(5) + 146372 [1356860][E](PTData): Existing entry averaged (8)(5)(1167), readings(3) + 146373 [1356871][E](PTData): Lower Up Found 7, 5, tp1165 + 146374 [1356872][E](PTable): New Entry Processed in 14 ms + 146375 [1356883][E](PTable): Power Buffer Reset + 146376 [1356883][E](ERG_Mode): Watts previously processed. + 146377 [1357210][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 133, Cad 100, HR 152, Gear 12, Res 40, Current Pos 11870, Target Pos 11870 + 146378 [1357564][E](ERG_Mode): Proportional: 81.000000 + 146379 [1358981][E](ERG_Mode): Watts previously processed. + 146380 [1362500][E](ERG_Mode): Watts previously processed. + 146381 [1363204][E](PTable): Averaged Entry: watts=146.899994, cad=98.300003, targetPosition=1199.900024, (8)(5) + 146382 [1363206][E](PTData): Existing entry averaged (8)(5)(1172), readings(3) + 146383 [1363216][E](PTData): Lower Up Found 7, 5, tp1165 + 146384 [1363218][E](PTable): New Entry Processed in 14 ms + 146385 [1363228][E](PTable): Power Buffer Reset + 146386 [1363228][E](ERG_Mode): Proportional: 3.000000 + 146387 [1363229][E](PTable): Using detected travel limits during homing + 146388 [1363240][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 157, Cad 97, HR 151, Gear 12, Res 41, Current Pos 12077, Target Pos 12077 + 146389 [1364614][E](ERG_Mode): Watts previously processed. + 146390 [1366729][E](ERG_Mode): Watts previously processed. + 146391 [1368839][E](ERG_Mode): Watts previously processed. + 146392 [1369265][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 165, Cad 101, HR 152, Gear 12, Res 40, Current Pos 11907, Target Pos 11907 + 146393 [1369542][E](PTable): Averaged Entry: watts=168.600006, cad=99.300003, targetPosition=1201.400024, (8)(6) + 146394 [1369543][E](PTData): Existing entry averaged (8)(6)(1192), readings(2) + 146395 [1369554][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146396 [1369569][E](PTData): Fit Valid: 1, N: 69, Quad: 1, Time: 4 ms + 146397 [1369576][E](PTable): New Entry Processed in 35 ms + 146398 [1369577][E](PTable): Power Buffer Reset + 146399 [1369577][E](ERG_Mode): Proportional: -5.000000 + 146400 [1370950][E](ERG_Mode): Watts previously processed. + 146401 [1374474][E](ERG_Mode): Watts previously processed. + 146402 [1375178][E](ERG_Mode): Proportional: -3.000000 + 146403 [1375283][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 163, Cad 102, HR 152, Gear 12, Res 40, Current Pos 11862, Target Pos 11862 + 146404 [1375881][E](PTable): Averaged Entry: watts=165.399994, cad=101.599998, targetPosition=1188.300049, (8)(6) + 146405 [1375883][E](PTData): Cleaned 231 readings + 146406 [1375893][E](PTData): Existing entry averaged (8)(6)(1191), readings(3) + 146407 [1375894][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146408 [1375909][E](PTData): Fit Valid: 1, N: 69, Quad: 1, Time: 5 ms + 146409 [1375917][E](PTable): New Entry Processed in 36 ms + 146410 [1375917][E](PTable): Power Buffer Reset + 146411 [1376586][E](ERG_Mode): Watts previously processed. + 146412 [1378705][E](ERG_Mode): Watts previously processed. + 146413 [1380822][E](ERG_Mode): Watts previously processed. + 146414 [1381298][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 164, Cad 103, HR 150, Gear 12, Res 40, Current Pos 11834, Target Pos 11834 + 146415 [1381531][E](ERG_Mode): Proportional: -4.000000 + 146416 [1382241][E](PTable): Averaged Entry: watts=161.399994, cad=102.099998, targetPosition=1185.099976, (8)(5) + 146417 [1382242][E](PTData): Cleaned 231 readings + 146418 [1382252][E](PTData): Existing entry averaged (8)(5)(1168), readings(3) + 146419 [1382252][E](PTData): Lower Up Found 7, 5, tp1165 + 146420 [1382264][E](PTable): New Entry Processed in 24 ms + 146421 [1382264][E](PTable): Power Buffer Reset + 146422 [1382944][E](ERG_Mode): Watts previously processed. + 146423 [1384026][E](FTMS_SERVER): 05 f4 01 -> ERG Mode Target: 500 Current: 150 Incline: 118.639999. Responding: 80 05 01 + 146424 [1384033][E](DirConManager): Sending response message type 0x04 to client 0 + 146425 [1384361][E](ERG_Mode): SetPoint changed:470w Waiting:2096ms PowerTable Result: 16750 + 146426 [1387309][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 249, Cad 107, HR 149, Gear 12, Res 57, Current Pos 16750, Target Pos 16750 + 146427 [1387866][E](ERG_Mode): ERG wait expired, pos: 16750, tgt: 0 + 146428 [1387867][E](ERG_Mode): Proportional: 384.000000 + 146429 [1388574][E](ERG_Mode): Watts previously processed. + 146430 [1390685][E](ERG_Mode): Watts previously processed. + 146431 [1392793][E](ERG_Mode): Watts previously processed. + 146432 [1393319][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 524, Cad 106, HR 149, Gear 12, Res 55, Current Pos 16284, Target Pos 16284 + 146433 [1393502][E](ERG_Mode): Proportional: -72.000000 + 146434 [1394921][E](ERG_Mode): Watts previously processed. + 146435 [1397031][E](ERG_Mode): Watts previously processed. + 146436 [1398435][E](ERG_Mode): Watts previously processed. + 146437 [1399142][E](ERG_Mode): Proportional: 138.000000 + 146438 [1399330][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 454, Cad 107, HR 150, Gear 12, Res 54, Current Pos 16080, Target Pos 16161 + 146439 [1399845][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 146440 [1399846][E](PTable): Power Buffer Reset + 146441 [1400549][E](ERG_Mode): Watts previously processed. + 146442 [1401956][E](PTable): Using detected travel limits during homing + 146443 [1402659][E](ERG_Mode): Watts previously processed. + 146444 [1404772][E](ERG_Mode): Watts previously processed. + 146445 [1405340][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 525, Cad 109, HR 153, Gear 12, Res 55, Current Pos 16358, Target Pos 16358 + 146446 [1405473][E](ERG_Mode): Proportional: -75.000000 + 146447 [1406890][E](ERG_Mode): Watts previously processed. + 146448 [1409004][E](ERG_Mode): Watts previously processed. + 146449 [1411120][E](ERG_Mode): Proportional: 96.000000 + 146450 [1411356][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 468, Cad 104, HR 158, Gear 12, Res 56, Current Pos 16602, Target Pos 16622 + 146451 [1412530][E](ERG_Mode): Watts previously processed. + 146452 [1413930][E](FTMS_SERVER): 05 a0 00 -> ERG Mode Target: 160 Current: 514 Incline: 166.770004. Responding: 80 05 01 + 146453 [1413938][E](DirConManager): Sending response message type 0x04 to client 0 + 146454 [1413950][E](ERG_Mode): SetPoint changed:190w Waiting:2193ms PowerTable Result: 11450 + 146455 [1417367][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 203, Cad 92, HR 163, Gear 12, Res 39, Current Pos 11450, Target Pos 11450 + 146456 [1417551][E](ERG_Mode): ERG wait expired, pos: 11450, tgt: 0 + 146457 [1417552][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 146458 [1417562][E](PTable): Power Buffer Reset + 146459 [1417563][E](ERG_Mode): Proportional: -129.000000 + 146460 [1418963][E](ERG_Mode): Watts previously processed. + 146461 [1421784][E](ERG_Mode): Watts previously processed. + 146462 [1423196][E](ERG_Mode): Proportional: 123.000000 + 146463 [1423381][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 119, Cad 90, HR 168, Gear 12, Res 40, Current Pos 11999, Target Pos 12068 + 146464 [1423897][E](PTable): Averaged Entry: watts=117.300003, cad=90.800003, targetPosition=1163.300049, (6)(4) + 146465 [1423898][E](PTData): New entry recorded (6)(4)(1163) + 146466 [1423909][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146467 [1423914][E](PTData): Fit Valid: 1, N: 70, Quad: 1, Time: 5 ms + 146468 [1423921][E](PTable): New Entry Processed in 25 ms + 146469 [1423921][E](PTable): Power Buffer Reset + 146470 [1424598][E](ERG_Mode): Watts previously processed. + 146471 [1426716][E](ERG_Mode): Watts previously processed. + 146472 [1428830][E](ERG_Mode): Watts previously processed. + 146473 [1429407][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 134, Cad 83, HR 172, Gear 12, Res 43, Current Pos 12680, Target Pos 12680 + 146474 [1429537][E](ERG_Mode): Proportional: 78.000000 + 146475 [1430246][E](PTable): Averaged Entry: watts=122.300003, cad=85.500000, targetPosition=1245.699951, (5)(4) + 146476 [1430248][E](PTData): Cleaned 230 readings + 146477 [1430258][E](PTData): Existing entry averaged (5)(4)(1192), readings(2) + 146478 [1430259][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146479 [1430274][E](PTData): Fit Valid: 1, N: 70, Quad: 1, Time: 5 ms + 146480 [1430281][E](PTable): New Entry Processed in 35 ms + 146481 [1430281][E](PTable): Power Buffer Reset + 146482 [1430950][E](ERG_Mode): Watts previously processed. + 146483 [1433769][E](ERG_Mode): Watts previously processed. + 146484 [1435178][E](ERG_Mode): Proportional: 54.000000 + 146485 [1435422][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 142, Cad 78, HR 171, Gear 12, Res 44, Current Pos 13253, Target Pos 13253 + 146486 [1436598][E](PTable): Averaged Entry: watts=134.500000, cad=79.599998, targetPosition=1303.900024, (4)(4) + 146487 [1436600][E](PTData): Cleaned 230 readings + 146488 [1436610][E](PTData): New entry recorded (4)(4)(1303) + 146489 [1436611][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146490 [1436621][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146491 [1436626][E](PTData): Fit Valid: 1, N: 71, Quad: 1, Time: 4 ms + 146492 [1436633][E](PTable): New Entry Processed in 35 ms + 146493 [1436633][E](PTable): Power Buffer Reset + 146494 [1436644][E](ERG_Mode): Watts previously processed. + 146495 [1438711][E](ERG_Mode): Watts previously processed. + 146496 [1440831][E](ERG_Mode): Watts previously processed. + 146497 [1440832][E](PTable): Using detected travel limits during homing + 146498 [1441438][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 137, Cad 74, HR 171, Gear 12, Res 46, Current Pos 13550, Target Pos 13550 + 146499 [1441538][E](ERG_Mode): Proportional: 69.000000 + 146500 [1442951][E](PTable): Averaged Entry: watts=138.800003, cad=76.300003, targetPosition=1346.800049, (3)(5) + 146501 [1442953][E](PTData): Cleaned 229 readings + 146502 [1442963][E](PTData): Existing entry averaged (3)(5)(1341), readings(4) + 146503 [1442964][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146504 [1442974][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146505 [1442990][E](PTData): Fit Valid: 1, N: 71, Quad: 1, Time: 5 ms + 146506 [1442997][E](PTable): New Entry Processed in 46 ms + 146507 [1442997][E](PTable): Power Buffer Reset + 146508 [1442997][E](ERG_Mode): Watts previously processed. + 146509 [1445060][E](ERG_Mode): Watts previously processed. + 146510 [1447170][E](ERG_Mode): Proportional: 30.000000 + 146511 [1447446][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 150, Cad 73, HR 170, Gear 12, Res 47, Current Pos 14006, Target Pos 14006 + 146512 [1448582][E](ERG_Mode): Watts previously processed. + 146513 [1449287][E](PTable): Averaged Entry: watts=144.199997, cad=73.800003, targetPosition=1386.599976, (3)(5) + 146514 [1449289][E](PTData): Cleaned 229 readings + 146515 [1449299][E](PTData): Existing entry averaged (3)(5)(1348), readings(5) + 146516 [1449300][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146517 [1449311][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146518 [1449326][E](PTData): Fit Valid: 1, N: 71, Quad: 1, Time: 5 ms + 146519 [1449332][E](PTable): New Entry Processed in 45 ms + 146520 [1449332][E](PTable): Power Buffer Reset + 146521 [1450695][E](ERG_Mode): Watts previously processed. + 146522 [1452809][E](ERG_Mode): Watts previously processed. + 146523 [1453457][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 143, Cad 70, HR 168, Gear 12, Res 48, Current Pos 14166, Target Pos 14166 + 146524 [1453518][E](ERG_Mode): Proportional: 51.000000 + 146525 [1454929][E](ERG_Mode): Watts previously processed. + 146526 [1455637][E](PTable): Averaged Entry: watts=142.500000, cad=71.800003, targetPosition=1412.599976, (2)(5) + 146527 [1455639][E](PTData): Cleaned 229 readings + 146528 [1455649][E](PTData): Existing entry averaged (2)(5)(1412), readings(20) + 146529 [1455650][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146530 [1455660][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146531 [1455675][E](PTData): Fit Valid: 1, N: 71, Quad: 1, Time: 4 ms + 146532 [1455682][E](PTable): New Entry Processed in 45 ms + 146533 [1455683][E](PTable): Power Buffer Reset + 146534 [1457046][E](ERG_Mode): Watts previously processed. + 146535 [1459167][E](ERG_Mode): Watts previously processed. + 146536 [1459474][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 145, Cad 69, HR 166, Gear 12, Res 49, Current Pos 14472, Target Pos 14472 + 146537 [1459869][E](ERG_Mode): Proportional: 42.000000 + 146538 [1460573][E](ERG_Mode): Watts previously processed. + 146539 [1461982][E](PTable): Averaged Entry: watts=144.300003, cad=68.900002, targetPosition=1443.099976, (2)(5) + 146540 [1461984][E](PTData): Cleaned 229 readings + 146541 [1461994][E](PTData): Existing entry averaged (2)(5)(1413), readings(20) + 146542 [1461995][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146543 [1462005][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146544 [1462020][E](PTData): Fit Valid: 1, N: 71, Quad: 1, Time: 4 ms + 146545 [1462028][E](PTable): New Entry Processed in 46 ms + 146546 [1462028][E](PTable): Power Buffer Reset + 146547 [1462691][E](ERG_Mode): Watts previously processed. + 146548 [1464804][E](ERG_Mode): Watts previously processed. + 146549 [1465493][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 151, Cad 68, HR 165, Gear 12, Res 49, Current Pos 14673, Target Pos 14673 + 146550 [1465514][E](ERG_Mode): Proportional: 9.000000 + 146551 [1466923][E](ERG_Mode): Watts previously processed. + 146552 [1468334][E](PTable): Averaged Entry: watts=150.300003, cad=68.000000, targetPosition=1466.400024, (2)(5) + 146553 [1468336][E](PTData): Cleaned 229 readings + 146554 [1468346][E](PTData): Existing entry averaged (2)(5)(1415), readings(20) + 146555 [1468347][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146556 [1468357][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146557 [1468372][E](PTData): Fit Valid: 1, N: 71, Quad: 1, Time: 4 ms + 146558 [1468380][E](PTable): New Entry Processed in 46 ms + 146559 [1468380][E](PTable): Power Buffer Reset + 146560 [1469040][E](ERG_Mode): Watts previously processed. + 146561 [1471152][E](ERG_Mode): Watts previously processed. + 146562 [1471507][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 157, Cad 71, HR 163, Gear 12, Res 50, Current Pos 14679, Target Pos 14679 + 146563 [1471860][E](ERG_Mode): Proportional: -7.000000 + 146564 [1472567][E](ERG_Mode): Watts previously processed. + 146565 [1474681][E](PTable): Averaged Entry: watts=165.100006, cad=69.800003, targetPosition=1468.900024, (2)(6) + 146566 [1474683][E](PTData): Cleaned 229 readings + 146567 [1474693][E](PTData): New entry recorded (2)(6)(1468) + 146568 [1474694][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146569 [1474704][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146570 [1474709][E](PTData): Fit Valid: 1, N: 72, Quad: 1, Time: 4 ms + 146571 [1474716][E](PTable): New Entry Processed in 35 ms + 146572 [1474716][E](PTable): Power Buffer Reset + 146573 [1474727][E](ERG_Mode): Watts previously processed. + 146574 [1476792][E](ERG_Mode): Watts previously processed. + 146575 [1476793][E](PTable): Using detected travel limits during homing + 146576 [1477499][E](ERG_Mode): Proportional: 0.000000 + 146577 [1477521][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 160, Cad 70, HR 161, Gear 12, Res 49, Current Pos 14672, Target Pos 14672 + 146578 [1478904][E](ERG_Mode): Watts previously processed. + 146579 [1481019][E](PTable): Averaged Entry: watts=157.399994, cad=69.099998, targetPosition=1467.699951, (2)(5) + 146580 [1481021][E](PTData): Cleaned 228 readings + 146581 [1481031][E](PTData): Existing entry averaged (2)(5)(1417), readings(20) + 146582 [1481032][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146583 [1481043][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146584 [1481058][E](PTData): Fit Valid: 1, N: 72, Quad: 1, Time: 5 ms + 146585 [1481065][E](PTable): New Entry Processed in 46 ms + 146586 [1481065][E](PTable): Power Buffer Reset + 146587 [1481065][E](ERG_Mode): Watts previously processed. + 146588 [1483132][E](ERG_Mode): Proportional: 4.000000 + 146589 [1483539][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 156, Cad 68, HR 159, Gear 12, Res 50, Current Pos 14736, Target Pos 14736 + 146590 [1484535][E](ERG_Mode): Watts previously processed. + 146591 [1486646][E](ERG_Mode): Watts previously processed. + 146592 [1487351][E](PTable): Averaged Entry: watts=152.100006, cad=67.800003, targetPosition=1473.199951, (1)(5) + 146593 [1487353][E](PTData): Cleaned 228 readings + 146594 [1487363][E](PTData): Existing entry averaged (1)(5)(1450), readings(15) + 146595 [1487364][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146596 [1487375][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146597 [1487390][E](PTData): Fit Valid: 1, N: 72, Quad: 1, Time: 5 ms + 146598 [1487396][E](PTable): New Entry Processed in 45 ms + 146599 [1487463][E](PTable): Writing File: /PowerTable.txt + 146600 [1487697][E](PTable): Power table saved successfully with 736 readings + 146601 [1487698][E](PTable): Power Buffer Reset + 146602 [1488773][E](ERG_Mode): Proportional: 39.000000 + 146603 [1489479][E](ERG_Mode): Watts previously processed. + 146604 [1489550][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 147, Cad 66, HR 158, Gear 12, Res 50, Current Pos 14863, Target Pos 14863 + 146605 [1491598][E](ERG_Mode): Watts previously processed. + 146606 [1493716][E](PTable): Averaged Entry: watts=152.500000, cad=67.400002, targetPosition=1485.099976, (1)(5) + 146607 [1493718][E](PTData): Cleaned 228 readings + 146608 [1493728][E](PTData): Existing entry averaged (1)(5)(1452), readings(16) + 146609 [1493729][E](PTData): PAVA iteration done, still converging: cad 1, watt 0, Loop 1 + 146610 [1493740][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 2 + 146611 [1493755][E](PTData): Fit Valid: 1, N: 72, Quad: 1, Time: 5 ms + 146612 [1493761][E](PTable): New Entry Processed in 45 ms + 146613 [1493762][E](PTable): Power Buffer Reset + 146614 [1493762][E](ERG_Mode): Watts previously processed. + 146615 [1494417][E](ERG_Mode): Proportional: 7.000000 + 146616 [1495565][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 161, Cad 67, HR 155, Gear 12, Res 50, Current Pos 14926, Target Pos 14926 + 146617 [1495826][E](ERG_Mode): Watts previously processed. + 146618 [1497942][E](ERG_Mode): Watts previously processed. + 146619 [1500056][E](PTable): Averaged Entry: watts=163.800003, cad=68.199997, targetPosition=1490.400024, (2)(5) + 146620 [1500058][E](PTData): Cleaned 228 readings + 146621 [1500068][E](PTData): Existing entry averaged (2)(5)(1420), readings(20) + 146622 [1500069][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146623 [1500084][E](PTData): Fit Valid: 1, N: 72, Quad: 1, Time: 5 ms + 146624 [1500091][E](PTable): New Entry Processed in 35 ms + 146625 [1500091][E](PTable): Power Buffer Reset + 146626 [1500091][E](ERG_Mode): Proportional: -6.000000 + 146627 [1500762][E](ERG_Mode): Watts previously processed. + 146628 [1501581][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 172, Cad 70, HR 153, Gear 12, Res 50, Current Pos 14788, Target Pos 14773 + 146629 [1503584][E](ERG_Mode): Watts previously processed. + 146630 [1505699][E](ERG_Mode): Watts previously processed. + 146631 [1506404][E](PTable): Averaged Entry: watts=164.500000, cad=69.400002, targetPosition=1475.500000, (2)(5) + 146632 [1506406][E](PTData): Cleaned 228 readings + 146633 [1506416][E](PTData): Existing entry averaged (2)(5)(1422), readings(20) + 146634 [1506417][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146635 [1506432][E](PTData): Fit Valid: 1, N: 72, Quad: 1, Time: 5 ms + 146636 [1506439][E](PTable): New Entry Processed in 35 ms + 146637 [1506440][E](PTable): Power Buffer Reset + 146638 [1506440][E](ERG_Mode): Proportional: -1.000000 + 146639 [1507591][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 161, Cad 69, HR 150, Gear 12, Res 50, Current Pos 14731, Target Pos 14731 + 146640 [1507813][E](ERG_Mode): Watts previously processed. + 146641 [1509925][E](ERG_Mode): Watts previously processed. + 146642 [1512036][E](ERG_Mode): Proportional: 30.000000 + 146643 [1512740][E](PTable): Averaged Entry: watts=155.600006, cad=68.000000, targetPosition=1474.199951, (2)(5) + 146644 [1512742][E](PTData): Cleaned 228 readings + 146645 [1512753][E](PTData): Existing entry averaged (2)(5)(1424), readings(20) + 146646 [1512754][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146647 [1512769][E](PTData): Fit Valid: 1, N: 72, Quad: 1, Time: 5 ms + 146648 [1512775][E](PTable): New Entry Processed in 35 ms + 146649 [1512776][E](PTable): Power Buffer Reset + 146650 [1512776][E](ERG_Mode): Watts previously processed. + 146651 [1512786][E](PTable): Using detected travel limits during homing + 146652 [1513600][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 150, Cad 67, HR 149, Gear 12, Res 50, Current Pos 14830, Target Pos 14832 + 146653 [1514859][E](ERG_Mode): Watts previously processed. + 146654 [1517688][E](ERG_Mode): Watts previously processed. + 146655 [1518393][E](ERG_Mode): Proportional: 0.000000 + 146656 [1519101][E](PTable): Averaged Entry: watts=152.000000, cad=66.800003, targetPosition=1486.000000, (1)(5) + 146657 [1519103][E](PTData): Cleaned 228 readings + 146658 [1519113][E](PTData): Existing entry averaged (1)(5)(1453), readings(17) + 146659 [1519114][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146660 [1519129][E](PTData): Fit Valid: 1, N: 72, Quad: 1, Time: 5 ms + 146661 [1519136][E](PTable): New Entry Processed in 35 ms + 146662 [1519136][E](PTable): Power Buffer Reset + 146663 [1519615][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 152, Cad 67, HR 148, Gear 12, Res 50, Current Pos 14926, Target Pos 14926 + 146664 [1519808][E](ERG_Mode): Watts previously processed. + 146665 [1521923][E](ERG_Mode): Watts previously processed. + 146666 [1524035][E](ERG_Mode): Proportional: -3.000000 + 146667 [1524741][E](ERG_Mode): Watts previously processed. + 146668 [1525448][E](PTable): Averaged Entry: watts=162.899994, cad=68.199997, targetPosition=1487.400024, (2)(5) + 146669 [1525450][E](PTData): Cleaned 228 readings + 146670 [1525460][E](PTData): Existing entry averaged (2)(5)(1427), readings(20) + 146671 [1525461][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146672 [1525476][E](PTData): Fit Valid: 1, N: 72, Quad: 1, Time: 5 ms + 146673 [1525483][E](PTable): New Entry Processed in 35 ms + 146674 [1525483][E](PTable): Power Buffer Reset + 146675 [1525624][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 165, Cad 69, HR 146, Gear 12, Res 50, Current Pos 14848, Target Pos 14848 + 146676 [1526854][E](ERG_Mode): Watts previously processed. + 146677 [1528977][E](ERG_Mode): Watts previously processed. + 146678 [1529686][E](ERG_Mode): Proportional: 90.000000 + 146679 [1531641][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 148, Cad 67, HR 145, Gear 12, Res 50, Current Pos 14958, Target Pos 14958 + 146680 [1531801][E](PTable): Averaged Entry: watts=158.100006, cad=68.000000, targetPosition=1485.300049, (2)(5) + 146681 [1531803][E](PTData): Cleaned 228 readings + 146682 [1531813][E](PTData): Existing entry averaged (2)(5)(1429), readings(20) + 146683 [1531814][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146684 [1531830][E](PTData): Fit Valid: 1, N: 72, Quad: 1, Time: 5 ms + 146685 [1531837][E](PTable): New Entry Processed in 36 ms + 146686 [1531837][E](PTable): Power Buffer Reset + 146687 [1531837][E](ERG_Mode): Watts previously processed. + 146688 [1533914][E](ERG_Mode): Watts previously processed. + 146689 [1533959][E](FTMS_SERVER): 05 f4 01 -> ERG Mode Target: 500 Current: 172 Incline: 148.679993. Responding: 80 05 01 + 146690 [1533966][E](DirConManager): Sending response message type 0x04 to client 0 + 146691 [1534619][E](ERG_Mode): SetPoint changed:470w Waiting:2578ms PowerTable Result: 21440 + 146692 [1537653][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 172, Cad 72, HR 145, Gear 12, Res 72, Current Pos 21440, Target Pos 21440 + 146693 [1538598][E](ERG_Mode): ERG wait expired, pos: 21440, tgt: 0 + 146694 [1538599][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 146695 [1538609][E](PTable): Power Buffer Reset + 146696 [1538610][E](ERG_Mode): Proportional: 1215.000000 + 146697 [1540715][E](ERG_Mode): Watts previously processed. + 146698 [1542829][E](ERG_Mode): Watts previously processed. + 146699 [1543667][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 469, Cad 67, HR 149, Gear 12, Res 79, Current Pos 23345, Target Pos 23409 + 146700 [1544245][E](ERG_Mode): Proportional: 129.000000 + 146701 [1544953][E](PTable): Averaged Entry: watts=440.600006, cad=68.500000, targetPosition=2292.500000, (2)(15) + 146702 [1544954][E](PTData): Cleaned 228 readings + 146703 [1544964][E](PTData): New entry recorded (2)(15)(2292) + 146704 [1544965][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146705 [1544981][E](PTData): Fit Valid: 1, N: 73, Quad: 1, Time: 6 ms + 146706 [1544988][E](PTable): New Entry Processed in 36 ms + 146707 [1544988][E](PTable): Power Buffer Reset + 146708 [1544988][E](ERG_Mode): Watts previously processed. + 146709 [1547065][E](ERG_Mode): Watts previously processed. + 146710 [1549682][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 456, Cad 64, HR 149, Gear 12, Res 81, Current Pos 24123, Target Pos 24123 + 146711 [1549884][E](ERG_Mode): Watts previously processed. + 146712 [1550592][E](ERG_Mode): Proportional: 108.000000 + 146713 [1551300][E](PTable): Averaged Entry: watts=462.299988, cad=65.300003, targetPosition=2384.600098, (1)(15) + 146714 [1551301][E](PTData): Cleaned 227 readings + 146715 [1551311][E](PTData): New entry recorded (1)(15)(2384) + 146716 [1551312][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146717 [1551328][E](PTData): Fit Valid: 1, N: 74, Quad: 1, Time: 6 ms + 146718 [1551335][E](PTable): New Entry Processed in 36 ms + 146719 [1551335][E](PTable): Power Buffer Reset + 146720 [1552007][E](PTable): Using detected travel limits during homing + 146721 [1552711][E](ERG_Mode): Watts previously processed. + 146722 [1554827][E](ERG_Mode): Watts previously processed. + 146723 [1555697][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 489, Cad 66, HR 154, Gear 12, Res 83, Current Pos 24586, Target Pos 24588 + 146724 [1556241][E](ERG_Mode): Proportional: 141.000000 + 146725 [1556949][E](ERG_Mode): Watts previously processed. + 146726 [1557657][E](PTable): Averaged Entry: watts=471.000000, cad=64.900002, targetPosition=2451.500000, (1)(16) + 146727 [1557658][E](PTData): Cleaned 226 readings + 146728 [1557668][E](PTData): New entry recorded (1)(16)(2451) + 146729 [1557669][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146730 [1557684][E](PTData): Fit Valid: 1, N: 75, Quad: 1, Time: 5 ms + 146731 [1557691][E](PTable): New Entry Processed in 35 ms + 146732 [1557691][E](PTable): Power Buffer Reset + 146733 [1559764][E](ERG_Mode): Watts previously processed. + 146734 [1561705][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 525, Cad 67, HR 159, Gear 12, Res 85, Current Pos 24975, Target Pos 24975 + 146735 [1561876][E](ERG_Mode): Watts previously processed. + 146736 [1562588][E](ERG_Mode): Proportional: -4.000000 + 146737 [1564000][E](PTable): Averaged Entry: watts=489.000000, cad=65.199997, targetPosition=2495.600098, (1)(16) + 146738 [1564002][E](PTData): Cleaned 225 readings + 146739 [1564012][E](PTData): Existing entry averaged (1)(16)(2465), readings(2) + 146740 [1564013][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146741 [1564029][E](PTData): Fit Valid: 1, N: 75, Quad: 1, Time: 6 ms + 146742 [1564036][E](PTable): New Entry Processed in 36 ms + 146743 [1564037][E](PTable): Power Buffer Reset + 146744 [1564041][E](FTMS_SERVER): 05 a0 00 -> ERG Mode Target: 160 Current: 470 Incline: 251.000000. Responding: 80 05 01 + 146745 [1564055][E](DirConManager): Sending response message type 0x04 to client 0 + 146746 [1564708][E](ERG_Mode): SetPoint changed:190w Waiting:3351ms PowerTable Result: 15820 + 146747 [1567719][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 427, Cad 61, HR 164, Gear 12, Res 58, Current Pos 16775, Target Pos 15820 + 146748 [1569461][E](ERG_Mode): ERG wait expired, pos: 15820, tgt: 0 + 146749 [1569462][E](ERG_Mode): Proportional: -75.000000 + 146750 [1570168][E](ERG_Mode): Watts previously processed. + 146751 [1572983][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 146752 [1572984][E](PTable): Power Buffer Reset + 146753 [1573688][E](ERG_Mode): Watts previously processed. + 146754 [1573728][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 154, Cad 59, HR 166, Gear 12, Res 53, Current Pos 15683, Target Pos 15683 + 146755 [1575110][E](ERG_Mode): Proportional: -6.000000 + 146756 [1575816][E](ERG_Mode): Watts previously processed. + 146757 [1577930][E](ERG_Mode): Watts previously processed. + 146758 [1579340][E](PTable): Averaged Entry: watts=162.899994, cad=60.900002, targetPosition=1566.599976, (0)(5) + 146759 [1579342][E](PTData): Cleaned 225 readings + 146760 [1579352][E](PTData): New entry recorded (0)(5)(1566) + 146761 [1579353][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146762 [1579368][E](PTData): Fit Valid: 1, N: 76, Quad: 1, Time: 5 ms + 146763 [1579375][E](PTable): New Entry Processed in 35 ms + 146764 [1579375][E](PTable): Power Buffer Reset + 146765 [1579744][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 162, Cad 62, HR 166, Gear 12, Res 53, Current Pos 15636, Target Pos 15636 + 146766 [1580044][E](ERG_Mode): Watts previously processed. + 146767 [1580753][E](ERG_Mode): Proportional: -6.000000 + 146768 [1582161][E](ERG_Mode): Watts previously processed. + 146769 [1585694][E](PTable): Averaged Entry: watts=168.399994, cad=62.299999, targetPosition=1561.099976, (0)(6) + 146770 [1585695][E](PTData): Cleaned 224 readings + 146771 [1585705][E](PTData): Existing entry averaged (0)(6)(1637), readings(7) + 146772 [1585706][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146773 [1585721][E](PTData): Fit Valid: 1, N: 76, Quad: 1, Time: 5 ms + 146774 [1585728][E](PTable): New Entry Processed in 35 ms + 146775 [1585728][E](PTable): Power Buffer Reset + 146776 [1585728][E](ERG_Mode): Watts previously processed. + 146777 [1585760][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 192, Cad 65, HR 167, Gear 12, Res 52, Current Pos 15490, Target Pos 15490 + 146778 [1586400][E](ERG_Mode): Proportional: -6.000000 + 146779 [1587814][E](ERG_Mode): Watts previously processed. + 146780 [1589927][E](ERG_Mode): Watts previously processed. + 146781 [1591769][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 171, Cad 70, HR 166, Gear 12, Res 51, Current Pos 15188, Target Pos 15188 + 146782 [1592042][E](PTable): Averaged Entry: watts=173.800003, cad=64.900002, targetPosition=1541.599976, (1)(6) + 146783 [1592044][E](PTData): Cleaned 224 readings + 146784 [1592054][E](PTData): New entry recorded (1)(6)(1541) + 146785 [1592055][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146786 [1592070][E](PTData): Fit Valid: 1, N: 77, Quad: 1, Time: 5 ms + 146787 [1592077][E](PTable): New Entry Processed in 35 ms + 146788 [1592077][E](PTable): Power Buffer Reset + 146789 [1592077][E](ERG_Mode): Watts previously processed. + 146790 [1592088][E](PTable): Using detected travel limits during homing + 146791 [1592744][E](ERG_Mode): Proportional: 0.000000 + 146792 [1594154][E](ERG_Mode): Watts previously processed. + 146793 [1597675][E](ERG_Mode): Watts previously processed. + 146794 [1597787][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 141, Cad 61, HR 166, Gear 12, Res 52, Current Pos 15371, Target Pos 15371 + 146795 [1598385][E](PTable): Averaged Entry: watts=149.600006, cad=63.200001, targetPosition=1523.900024, (1)(5) + 146796 [1598386][E](PTData): Cleaned 223 readings + 146797 [1598396][E](PTData): Existing entry averaged (1)(5)(1456), readings(18) + 146798 [1598397][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146799 [1598412][E](PTData): Fit Valid: 1, N: 77, Quad: 1, Time: 5 ms + 146800 [1598419][E](PTable): New Entry Processed in 35 ms + 146801 [1598419][E](PTable): Power Buffer Reset + 146802 [1598420][E](ERG_Mode): Proportional: 60.000000 + 146803 [1599795][E](ERG_Mode): Watts previously processed. + 146804 [1601906][E](ERG_Mode): Watts previously processed. + 146805 [1603797][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 151, Cad 59, HR 167, Gear 12, Res 53, Current Pos 15644, Target Pos 15644 + 146806 [1604017][E](ERG_Mode): Watts previously processed. + 146807 [1604722][E](PTable): Averaged Entry: watts=147.699997, cad=59.599998, targetPosition=1553.800049, (0)(5) + 146808 [1604724][E](PTData): Cleaned 223 readings + 146809 [1604735][E](PTData): Existing entry averaged (0)(5)(1561), readings(2) + 146810 [1604736][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146811 [1604751][E](PTData): Fit Valid: 1, N: 77, Quad: 1, Time: 5 ms + 146812 [1604758][E](PTable): New Entry Processed in 36 ms + 146813 [1604758][E](PTable): Power Buffer Reset + 146814 [1604758][E](ERG_Mode): Proportional: -33.000000 + 146815 [1606126][E](ERG_Mode): Watts previously processed. + 146816 [1607533][E](ERG_Mode): Watts previously processed. + 146817 [1609647][E](ERG_Mode): Watts previously processed. + 146818 [1609809][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 171, Cad 65, HR 165, Gear 12, Res 52, Current Pos 15419, Target Pos 15419 + 146819 [1610356][E](ERG_Mode): Proportional: -48.000000 + 146820 [1611062][E](PTable): Averaged Entry: watts=178.199997, cad=65.099998, targetPosition=1548.800049, (1)(6) + 146821 [1611063][E](PTData): Cleaned 223 readings + 146822 [1611073][E](PTData): Existing entry averaged (1)(6)(1543), readings(2) + 146823 [1611074][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146824 [1611089][E](PTData): Fit Valid: 1, N: 77, Quad: 1, Time: 5 ms + 146825 [1611096][E](PTable): New Entry Processed in 35 ms + 146826 [1611096][E](PTable): Power Buffer Reset + 146827 [1611764][E](ERG_Mode): Watts previously processed. + 146828 [1613879][E](ERG_Mode): Watts previously processed. + 146829 [1615824][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 199, Cad 72, HR 164, Gear 12, Res 50, Current Pos 14715, Target Pos 14715 + 146830 [1615996][E](ERG_Mode): Watts previously processed. + 146831 [1616713][E](ERG_Mode): Proportional: -102.000000 + 146832 [1617421][E](PTable): Averaged Entry: watts=197.699997, cad=70.599998, targetPosition=1497.199951, (2)(7) + 146833 [1617423][E](PTData): Cleaned 223 readings + 146834 [1617433][E](PTData): New entry recorded (2)(7)(1497) + 146835 [1617434][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146836 [1617449][E](PTData): Fit Valid: 1, N: 78, Quad: 1, Time: 5 ms + 146837 [1617457][E](PTable): New Entry Processed in 36 ms + 146838 [1617457][E](PTable): Power Buffer Reset + 146839 [1618124][E](ERG_Mode): Watts previously processed. + 146840 [1621652][E](ERG_Mode): Watts previously processed. + 146841 [1621834][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 172, Cad 74, HR 163, Gear 12, Res 48, Current Pos 14292, Target Pos 14292 + 146842 [1622359][E](ERG_Mode): Proportional: -36.000000 + 146843 [1623768][E](PTable): Averaged Entry: watts=178.100006, cad=74.000000, targetPosition=1437.400024, (3)(6) + 146844 [1623770][E](PTData): Cleaned 222 readings + 146845 [1623780][E](PTData): Existing entry averaged (3)(6)(1452), readings(9) + 146846 [1623781][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146847 [1623797][E](PTData): Fit Valid: 1, N: 78, Quad: 1, Time: 6 ms + 146848 [1623803][E](PTable): New Entry Processed in 35 ms + 146849 [1623803][E](PTable): Power Buffer Reset + 146850 [1623804][E](ERG_Mode): Watts previously processed. + 146851 [1625887][E](ERG_Mode): Watts previously processed. + 146852 [1627843][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 160, Cad 74, HR 161, Gear 12, Res 48, Current Pos 14214, Target Pos 14214 + 146853 [1628003][E](ERG_Mode): Watts previously processed. + 146854 [1628004][E](PTable): Using detected travel limits during homing + 146855 [1628719][E](ERG_Mode): Proportional: 3.000000 + 146856 [1630128][E](PTable): Averaged Entry: watts=161.300003, cad=73.500000, targetPosition=1421.300049, (3)(5) + 146857 [1630130][E](PTData): Cleaned 222 readings + 146858 [1630140][E](PTData): Existing entry averaged (3)(5)(1358), readings(6) + 146859 [1630141][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146860 [1630156][E](PTData): Fit Valid: 1, N: 78, Quad: 1, Time: 5 ms + 146861 [1630163][E](PTable): New Entry Processed in 35 ms + 146862 [1630163][E](PTable): Power Buffer Reset + 146863 [1630163][E](ERG_Mode): Watts previously processed. + 146864 [1633654][E](ERG_Mode): Watts previously processed. + 146865 [1633855][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 152, Cad 70, HR 159, Gear 12, Res 48, Current Pos 14340, Target Pos 14340 + 146866 [1634357][E](ERG_Mode): Watts previously processed. + 146867 [1635065][E](ERG_Mode): Proportional: 9.000000 + 146868 [1635772][E](ERG_Mode): Watts previously processed. + 146869 [1636478][E](PTable): Averaged Entry: watts=149.500000, cad=70.500000, targetPosition=1430.099976, (2)(5) + 146870 [1636479][E](PTData): Cleaned 222 readings + 146871 [1636489][E](PTData): Existing entry averaged (2)(5)(1429), readings(20) + 146872 [1636490][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146873 [1636506][E](PTData): Fit Valid: 1, N: 78, Quad: 1, Time: 5 ms + 146874 [1636512][E](PTable): New Entry Processed in 35 ms + 146875 [1636513][E](PTable): Power Buffer Reset + 146876 [1637891][E](ERG_Mode): Watts previously processed. + 146877 [1639871][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 153, Cad 71, HR 157, Gear 12, Res 49, Current Pos 14456, Target Pos 14456 + 146878 [1640003][E](ERG_Mode): Watts previously processed. + 146879 [1640718][E](ERG_Mode): Proportional: 1.000000 + 146880 [1642124][E](ERG_Mode): Watts previously processed. + 146881 [1642832][E](PTable): Averaged Entry: watts=150.899994, cad=70.699997, targetPosition=1443.699951, (2)(5) + 146882 [1642833][E](PTData): Cleaned 222 readings + 146883 [1642843][E](PTData): Existing entry averaged (2)(5)(1429), readings(20) + 146884 [1642844][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146885 [1642860][E](PTData): Fit Valid: 1, N: 78, Quad: 1, Time: 5 ms + 146886 [1642867][E](PTable): New Entry Processed in 36 ms + 146887 [1642867][E](PTable): Power Buffer Reset + 146888 [1644246][E](ERG_Mode): Watts previously processed. + 146889 [1645655][E](ERG_Mode): Watts previously processed. + 146890 [1645886][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 156, Cad 71, HR 155, Gear 12, Res 49, Current Pos 14485, Target Pos 14485 + 146891 [1646361][E](ERG_Mode): Proportional: 7.000000 + 146892 [1647770][E](ERG_Mode): Watts previously processed. + 146893 [1649179][E](PTable): Averaged Entry: watts=152.500000, cad=70.199997, targetPosition=1448.800049, (2)(5) + 146894 [1649181][E](PTData): Cleaned 222 readings + 146895 [1649191][E](PTData): Existing entry averaged (2)(5)(1429), readings(20) + 146896 [1649192][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146897 [1649207][E](PTData): Fit Valid: 1, N: 78, Quad: 1, Time: 5 ms + 146898 [1649214][E](PTable): New Entry Processed in 35 ms + 146899 [1649215][E](PTable): Power Buffer Reset + 146900 [1649885][E](ERG_Mode): Watts previously processed. + 146901 [1651898][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 157, Cad 70, HR 153, Gear 12, Res 49, Current Pos 14549, Target Pos 14549 + 146902 [1651998][E](ERG_Mode): Watts previously processed. + 146903 [1652716][E](ERG_Mode): Proportional: 33.000000 + 146904 [1654135][E](ERG_Mode): Watts previously processed. + 146905 [1655545][E](PTable): Averaged Entry: watts=149.699997, cad=69.199997, targetPosition=1457.099976, (2)(5) + 146906 [1655547][E](PTData): Cleaned 222 readings + 146907 [1655557][E](PTData): Existing entry averaged (2)(5)(1430), readings(20) + 146908 [1655558][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146909 [1655574][E](PTData): Fit Valid: 1, N: 78, Quad: 1, Time: 6 ms + 146910 [1655580][E](PTable): New Entry Processed in 35 ms + 146911 [1655581][E](PTable): Power Buffer Reset + 146912 [1656250][E](ERG_Mode): Watts previously processed. + 146913 [1657661][E](ERG_Mode): Watts previously processed. + 146914 [1657913][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 134, Cad 65, HR 151, Gear 12, Res 50, Current Pos 14843, Target Pos 14843 + 146915 [1658369][E](ERG_Mode): Proportional: 45.000000 + 146916 [1659778][E](ERG_Mode): Watts previously processed. + 146917 [1659823][E](FTMS_SERVER): 11 00 00 04 00 28 33 -> Sim Mode Incline 0.040000. Responding: 80 11 01 + 146918 [1659831][E](DirConManager): Sending response message type 0x04 to client 0 + 146919 [1660825][E](FTMS_SERVER): 11 00 00 03 00 28 33 -> Sim Mode Incline 0.030000. Responding: 80 11 01 + 146920 [1660833][E](DirConManager): Sending response message type 0x04 to client 0 + 146921 [1661830][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 146922 [1661838][E](DirConManager): Sending response message type 0x04 to client 0 + 146923 [1661890][E](PTable): Averaged Entry: watts=144.500000, cad=65.500000, targetPosition=1470.800049, (1)(5) + 146924 [1661892][E](PTData): Cleaned 222 readings + 146925 [1661902][E](PTData): Existing entry averaged (1)(5)(1456), readings(19) + 146926 [1661903][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146927 [1661918][E](PTData): Fit Valid: 1, N: 78, Quad: 1, Time: 5 ms + 146928 [1661927][E](PTable): New Entry Processed in 37 ms + 146929 [1661928][E](PTable): Power Buffer Reset + 146930 [1662846][E](FTMS_SERVER): 11 00 00 fb ff 28 33 -> Sim Mode Incline -0.050000. Responding: 80 11 01 + 146931 [1662853][E](DirConManager): Sending response message type 0x04 to client 0 + 146932 [1663807][E](FTMS_SERVER): 11 00 00 f2 ff 28 33 -> Sim Mode Incline -0.140000. Responding: 80 11 01 + 146933 [1663814][E](DirConManager): Sending response message type 0x04 to client 0 + 146934 [1663928][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 148, Cad 69, HR 147, Gear 12, Res 48, Current Pos 14344, Target Pos 14302 + 146935 [1664009][E](PTable): Using detected travel limits during homing + 146936 [1664826][E](FTMS_SERVER): 11 00 00 e9 ff 28 33 -> Sim Mode Incline -0.230000. Responding: 80 11 01 + 146937 [1664831][E](DirConManager): Sending response message type 0x04 to client 0 + 146938 [1665826][E](FTMS_SERVER): 11 00 00 e6 ff 28 33 -> Sim Mode Incline -0.260000. Responding: 80 11 01 + 146939 [1665830][E](DirConManager): Sending response message type 0x04 to client 0 + 146940 [1666743][E](FTMS_SERVER): 11 00 00 e8 ff 28 33 -> Sim Mode Incline -0.240000. Responding: 80 11 01 + 146941 [1666750][E](DirConManager): Sending response message type 0x04 to client 0 + 146942 [1667770][E](FTMS_SERVER): 11 00 00 ef ff 28 33 -> Sim Mode Incline -0.170000. Responding: 80 11 01 + 146943 [1667778][E](DirConManager): Sending response message type 0x04 to client 0 + 146944 [1668243][E](PTable): Averaged Entry: watts=160.800003, cad=70.199997, targetPosition=1429.400024, (2)(5) + 146945 [1668244][E](PTData): Cleaned 222 readings + 146946 [1668254][E](PTData): Existing entry averaged (2)(5)(1429), readings(20) + 146947 [1668255][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146948 [1668271][E](PTData): Fit Valid: 1, N: 78, Quad: 1, Time: 6 ms + 146949 [1668277][E](PTable): New Entry Processed in 35 ms + 146950 [1668278][E](PTable): Power Buffer Reset + 146951 [1668711][E](FTMS_SERVER): 11 00 00 e8 ff 28 33 -> Sim Mode Incline -0.240000. Responding: 80 11 01 + 146952 [1668718][E](DirConManager): Sending response message type 0x04 to client 0 + 146953 [1669717][E](FTMS_SERVER): 11 00 00 1a 00 28 33 -> Sim Mode Incline 0.260000. Responding: 80 11 01 + 146954 [1669725][E](DirConManager): Sending response message type 0x04 to client 0 + 146955 [1669942][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 158, Cad 72, HR 145, Gear 12, Res 48, Current Pos 14308, Target Pos 14582 + 146956 [1670622][E](FTMS_SERVER): 11 00 00 10 01 28 33 -> Sim Mode Incline 2.720000. Responding: 80 11 01 + 146957 [1670629][E](DirConManager): Sending response message type 0x04 to client 0 + 146958 [1671553][E](FTMS_SERVER): 11 00 00 79 01 28 33 -> Sim Mode Incline 3.770000. Responding: 80 11 01 + 146959 [1671557][E](DirConManager): Sending response message type 0x04 to client 0 + 146960 [1672476][E](PTable): Entry into buffer was outside the range. Clearing buffer. + 146961 [1672477][E](PTable): Power Buffer Reset + 146962 [1672575][E](FTMS_SERVER): 11 00 00 b3 01 28 33 -> Sim Mode Incline 4.350000. Responding: 80 11 01 + 146963 [1672580][E](DirConManager): Sending response message type 0x04 to client 0 + 146964 [1673617][E](FTMS_SERVER): 11 00 00 c9 01 28 33 -> Sim Mode Incline 4.570000. Responding: 80 11 01 + 146965 [1673621][E](DirConManager): Sending response message type 0x04 to client 0 + 146966 [1674636][E](FTMS_SERVER): 11 00 00 cf 01 28 33 -> Sim Mode Incline 4.630000. Responding: 80 11 01 + 146967 [1674640][E](DirConManager): Sending response message type 0x04 to client 0 + 146968 [1675543][E](FTMS_SERVER): 11 00 00 cb 01 28 33 -> Sim Mode Incline 4.590000. Responding: 80 11 01 + 146969 [1675550][E](DirConManager): Sending response message type 0x04 to client 0 + 146970 [1675955][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 197, Cad 61, HR 146, Gear 12, Res 60, Current Pos 17613, Target Pos 17613 + 146971 [1676574][E](FTMS_SERVER): 11 00 00 c0 01 28 33 -> Sim Mode Incline 4.480000. Responding: 80 11 01 + 146972 [1676582][E](DirConManager): Sending response message type 0x04 to client 0 + 146973 [1677526][E](FTMS_SERVER): 11 00 00 af 01 28 33 -> Sim Mode Incline 4.310000. Responding: 80 11 01 + 146974 [1677534][E](DirConManager): Sending response message type 0x04 to client 0 + 146975 [1678524][E](FTMS_SERVER): 11 00 00 90 01 28 33 -> Sim Mode Incline 4.000000. Responding: 80 11 01 + 146976 [1678531][E](DirConManager): Sending response message type 0x04 to client 0 + 146977 [1678837][E](PTable): Averaged Entry: watts=194.199997, cad=62.500000, targetPosition=1750.099976, (0)(6) + 146978 [1678839][E](PTData): Cleaned 222 readings + 146979 [1678849][E](PTData): Existing entry averaged (0)(6)(1649), readings(8) + 146980 [1678850][E](PTData): PAVA iteration done, still converging: cad 1, watt 1, Loop 1 + 146981 [1678865][E](PTData): Fit Valid: 1, N: 78, Quad: 1, Time: 5 ms + 146982 [1678872][E](PTable): New Entry Processed in 35 ms + 146983 [1678873][E](PTable): Power Buffer Reset + 146984 [1679430][E](FTMS_SERVER): 11 00 00 6b 01 28 33 -> Sim Mode Incline 3.630000. Responding: 80 11 01 + 146985 [1679436][E](DirConManager): Sending response message type 0x04 to client 0 + 146986 [1680471][E](FTMS_SERVER): 11 00 00 25 01 28 33 -> Sim Mode Incline 2.930000. Responding: 80 11 01 + 146987 [1680476][E](DirConManager): Sending response message type 0x04 to client 0 + 146988 [1681496][E](FTMS_SERVER): 11 00 00 be 00 28 33 -> Sim Mode Incline 1.900000. Responding: 80 11 01 + 146989 [1681502][E](DirConManager): Sending response message type 0x04 to client 0 + 146990 [1681967][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 165, Cad 55, HR 144, Gear 12, Res 55, Current Pos 16120, Target Pos 15730 + 146991 [1682506][E](FTMS_SERVER): 11 00 00 5f 00 28 33 -> Sim Mode Incline 0.950000. Responding: 80 11 01 + 146992 [1682511][E](DirConManager): Sending response message type 0x04 to client 0 + 146993 [1683532][E](FTMS_SERVER): 11 00 00 ff ff 28 33 -> Sim Mode Incline -0.010000. Responding: 80 11 01 + 146994 [1683536][E](DirConManager): Sending response message type 0x04 to client 0 + 146995 [1684461][E](FTMS_SERVER): 11 00 00 d0 ff 28 33 -> Sim Mode Incline -0.480000. Responding: 80 11 01 + 146996 [1684468][E](DirConManager): Sending response message type 0x04 to client 0 + 146997 [1685478][E](FTMS_SERVER): 11 00 00 bf ff 28 33 -> Sim Mode Incline -0.650000. Responding: 80 11 01 + 146998 [1685486][E](DirConManager): Sending response message type 0x04 to client 0 + 146999 [1686429][E](FTMS_SERVER): 11 00 00 da ff 28 33 -> Sim Mode Incline -0.380000. Responding: 80 11 01 + 147000 [1686437][E](DirConManager): Sending response message type 0x04 to client 0 + 147001 [1687438][E](FTMS_SERVER): 11 00 00 ff ff 28 33 -> Sim Mode Incline -0.010000. Responding: 80 11 01 + 147002 [1687446][E](DirConManager): Sending response message type 0x04 to client 0 + 147003 [1687978][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 86, Cad 50, HR 142, Gear 12, Res 48, Current Pos 14389, Target Pos 14393 + 147004 [1688346][E](FTMS_SERVER): 11 00 00 21 00 28 33 -> Sim Mode Incline 0.330000. Responding: 80 11 01 + 147005 [1688354][E](DirConManager): Sending response message type 0x04 to client 0 + 147006 [1689266][E](FTMS_SERVER): 11 00 00 2f 00 28 33 -> Sim Mode Incline 0.470000. Responding: 80 11 01 + 147007 [1689270][E](DirConManager): Sending response message type 0x04 to client 0 + 147008 [1690300][E](FTMS_SERVER): 11 00 00 34 00 28 33 -> Sim Mode Incline 0.520000. Responding: 80 11 01 + 147009 [1690304][E](DirConManager): Sending response message type 0x04 to client 0 + 147010 [1691939][E](FTMS_SERVER): 11 00 00 32 00 28 33 -> Sim Mode Incline 0.500000. Responding: 80 11 01 + 147011 [1691944][E](DirConManager): Sending response message type 0x04 to client 0 + 147012 [1692866][E](FTMS_SERVER): 11 00 00 2c 00 28 33 -> Sim Mode Incline 0.440000. Responding: 80 11 01 + 147013 [1692873][E](DirConManager): Sending response message type 0x04 to client 0 + 147014 [1693772][E](FTMS_SERVER): 11 00 00 23 00 28 33 -> Sim Mode Incline 0.350000. Responding: 80 11 01 + 147015 [1693779][E](DirConManager): Sending response message type 0x04 to client 0 + 147016 [1693988][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 26, Cad 0, HR 141, Gear 12, Res 49, Current Pos 14654, Target Pos 14645 + 147017 [1694804][E](FTMS_SERVER): 11 00 00 17 00 28 33 -> Sim Mode Incline 0.230000. Responding: 80 11 01 + 147018 [1694811][E](DirConManager): Sending response message type 0x04 to client 0 + 147019 [1695753][E](FTMS_SERVER): 11 00 00 05 00 28 33 -> Sim Mode Incline 0.050000. Responding: 80 11 01 + 147020 [1695760][E](DirConManager): Sending response message type 0x04 to client 0 + 147021 [1696751][E](FTMS_SERVER): 11 00 00 f6 ff 28 33 -> Sim Mode Incline -0.100000. Responding: 80 11 01 + 147022 [1696759][E](DirConManager): Sending response message type 0x04 to client 0 + 147023 [1697668][E](FTMS_SERVER): 11 00 00 b9 ff 28 33 -> Sim Mode Incline -0.710000. Responding: 80 11 01 + 147024 [1697674][E](DirConManager): Sending response message type 0x04 to client 0 + 147025 [1698695][E](FTMS_SERVER): 11 00 00 7f ff 28 33 -> Sim Mode Incline -1.290000. Responding: 80 11 01 + 147026 [1698700][E](DirConManager): Sending response message type 0x04 to client 0 + 147027 [1699720][E](FTMS_SERVER): 11 00 00 2e ff 28 33 -> Sim Mode Incline -2.100000. Responding: 80 11 01 + 147028 [1699725][E](DirConManager): Sending response message type 0x04 to client 0 + 147029 [1699998][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 138, Gear 12, Res 45, Current Pos 13380, Target Pos 12930 + 147030 [1700746][E](FTMS_SERVER): 11 00 00 08 ff 28 33 -> Sim Mode Incline -2.480000. Responding: 80 11 01 + 147031 [1700751][E](DirConManager): Sending response message type 0x04 to client 0 + 147032 [1701655][E](FTMS_SERVER): 11 00 00 ff fe 28 33 -> Sim Mode Incline -2.570000. Responding: 80 11 01 + 147033 [1701663][E](DirConManager): Sending response message type 0x04 to client 0 + 147034 [1702574][E](FTMS_SERVER): 11 00 00 fc fe 28 33 -> Sim Mode Incline -2.600000. Responding: 80 11 01 + 147035 [1702584][E](DirConManager): Sending response message type 0x04 to client 0 + 147036 [1703597][E](FTMS_SERVER): 11 00 00 fb fe 28 33 -> Sim Mode Incline -2.610000. Responding: 80 11 01 + 147037 [1703604][E](DirConManager): Sending response message type 0x04 to client 0 + 147038 [1704558][E](FTMS_SERVER): 11 00 00 fe fe 28 33 -> Sim Mode Incline -2.580000. Responding: 80 11 01 + 147039 [1704565][E](DirConManager): Sending response message type 0x04 to client 0 + 147040 [1705456][E](FTMS_SERVER): 11 00 00 1c ff 28 33 -> Sim Mode Incline -2.280000. Responding: 80 11 01 + 147041 [1705462][E](DirConManager): Sending response message type 0x04 to client 0 + 147042 [1706007][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 135, Gear 12, Res 43, Current Pos 12804, Target Pos 12804 + 147043 [1706478][E](FTMS_SERVER): 11 00 00 8a ff 28 33 -> Sim Mode Incline -1.180000. Responding: 80 11 01 + 147044 [1706482][E](DirConManager): Sending response message type 0x04 to client 0 + 147045 [1707399][E](FTMS_SERVER): 11 00 00 d5 ff 28 33 -> Sim Mode Incline -0.430000. Responding: 80 11 01 + 147046 [1707406][E](DirConManager): Sending response message type 0x04 to client 0 + 147047 [1708305][E](FTMS_SERVER): 11 00 00 f9 ff 28 33 -> Sim Mode Incline -0.070000. Responding: 80 11 01 + 147048 [1708313][E](DirConManager): Sending response message type 0x04 to client 0 + 147049 [1709265][E](FTMS_SERVER): 11 00 00 1b 00 28 33 -> Sim Mode Incline 0.270000. Responding: 80 11 01 + 147050 [1709272][E](DirConManager): Sending response message type 0x04 to client 0 + 147051 [1710265][E](FTMS_SERVER): 11 00 00 36 00 28 33 -> Sim Mode Incline 0.540000. Responding: 80 11 01 + 147052 [1710272][E](DirConManager): Sending response message type 0x04 to client 0 + 147053 [1711185][E](FTMS_SERVER): 11 00 00 40 00 28 33 -> Sim Mode Incline 0.640000. Responding: 80 11 01 + 147054 [1711189][E](DirConManager): Sending response message type 0x04 to client 0 + 147055 [1712017][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 133, Gear 12, Res 50, Current Pos 14848, Target Pos 14848 + 147056 [1712101][E](FTMS_SERVER): 11 00 00 41 00 28 33 -> Sim Mode Incline 0.650000. Responding: 80 11 01 + 147057 [1712109][E](DirConManager): Sending response message type 0x04 to client 0 + 147058 [1713027][E](FTMS_SERVER): 11 00 00 35 00 28 33 -> Sim Mode Incline 0.530000. Responding: 80 11 01 + 147059 [1713035][E](DirConManager): Sending response message type 0x04 to client 0 + 147060 [1713987][E](FTMS_SERVER): 11 00 00 16 00 28 33 -> Sim Mode Incline 0.220000. Responding: 80 11 01 + 147061 [1713994][E](DirConManager): Sending response message type 0x04 to client 0 + 147062 [1714985][E](FTMS_SERVER): 11 00 00 00 00 28 33 -> Sim Mode Incline 0.000000. Responding: 80 11 01 + 147063 [1714992][E](DirConManager): Sending response message type 0x04 to client 0 + 147064 [1717934][E](FTMS_SERVER): 11 00 00 ef ff 28 33 -> Sim Mode Incline -0.170000. Responding: 80 11 01 + 147065 [1717939][E](DirConManager): Sending response message type 0x04 to client 0 + 147066 [1718032][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 127, Gear 12, Res 49, Current Pos 14385, Target Pos 14281 + 147067 [1724048][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 127, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147068 [1730061][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 123, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147069 [1736071][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 116, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147070 [1742084][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 116, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147071 [1748093][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 112, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147072 [1754108][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 109, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147073 [1760119][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 107, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147074 [1766129][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 105, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147075 [1772146][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 103, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147076 [1778160][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 102, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147077 [1784175][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 98, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147078 [1790187][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 99, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147079 [1796205][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 95, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147080 [1802219][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 98, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147081 [1808235][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 98, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147082 [1814245][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 98, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147083 [1820258][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 99, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147084 [1826268][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 98, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147085 [1832277][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 96, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147086 [1838294][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 96, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147087 [1844309][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 97, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147088 [1850326][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 99, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147089 [1856340][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 94, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147090 [1862358][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 95, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147091 [1868376][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 97, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147092 [1874386][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 100, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147093 [1880395][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 95, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147094 [1886407][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 97, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147095 [1892421][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 97, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147096 [1898434][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 97, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147097 [1904450][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 95, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147098 [1910459][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 92, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147099 [1916477][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 94, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147100 [1922487][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 94, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147101 [1928504][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 93, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147102 [1934512][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 94, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147103 [1940527][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 94, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147104 [1946542][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 92, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147105 [1952560][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 94, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147106 [1958570][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 95, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147107 [1964583][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147108 [1970596][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 94, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147109 [1976611][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 90, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147110 [1982622][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 91, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147111 [1988632][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147112 [1994644][E](Main): PM Con 1, CAD con 1, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147113 [1995454][E](BLE_Client): Client e8:fe:6e:91:9f:16 Disconnected, reason = 531 + 147114 [1995454][E](BLE_Client): Detected 0x1818 Disconnect + 147115 [1995455][E](BLE_Client): Deregistered PM on Disconnect + 147116 [1995465][E](BLE_Client): Resetting Device: ASSIOMA17287L 16 + 147117 [2000638][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147118 [2000639][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147119 [2000656][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 91, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147120 [2001062][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 147121 [2001062][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 147122 [2001073][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 147123 [2003157][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147124 [2004663][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147125 [2006683][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 93, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147126 [2006712][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147127 [2006713][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147128 [2007740][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 147129 [2007740][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 147130 [2007751][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 147131 [2009529][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147132 [2010739][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147133 [2012692][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147134 [2012787][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147135 [2012788][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147136 [2013128][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147137 [2014189][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 147138 [2014190][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 147139 [2014201][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 147140 [2016813][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147141 [2018711][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 91, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147142 [2018863][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147143 [2018864][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147144 [2019061][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 147145 [2019061][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 147146 [2019072][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 147147 [2019778][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147148 [2022889][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147149 [2024722][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 91, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147150 [2024938][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147151 [2024939][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147152 [2025204][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 147153 [2025205][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 147154 [2025215][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 147155 [2026150][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147156 [2028963][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147157 [2030732][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 90, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147158 [2031012][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147159 [2031013][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147160 [2031067][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 147161 [2031073][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 147162 [2031084][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 147163 [2032233][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147164 [2035039][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147165 [2036741][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 92, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147166 [2037093][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147167 [2037093][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147168 [2037761][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147169 [2037900][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 147170 [2037901][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 147171 [2037911][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 147172 [2041118][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147173 [2042752][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 92, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147174 [2043165][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147175 [2043166][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147176 [2043631][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 147177 [2043632][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 147178 [2043643][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 147179 [2044116][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147180 [2047190][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147181 [2048763][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 92, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147182 [2049239][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147183 [2049240][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147184 [2049947][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 147185 [2049948][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 147186 [2049958][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 147187 [2052150][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147188 [2053263][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147189 [2054781][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 92, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147190 [2055314][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147191 [2055315][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147192 [2055928][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 147193 [2055928][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 147194 [2055939][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 147195 [2057970][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147196 [2059344][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147197 [2060799][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 94, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147198 [2061390][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147199 [2061391][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147200 [2061564][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147201 [2062073][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 147202 [2062073][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 147203 [2062084][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 147204 [2065416][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147205 [2066811][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 95, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147206 [2067463][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147207 [2067464][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147208 [2067944][E](BLE_Client): Found device CAD-BLE0418789 b1 with services: 0x1816 6a4e3e10-667b-11e3-949a-0800200c9a66 + 147209 [2067945][E](BLE_Client): Supported Device: CAD-BLE0418789 b1 with service Cycling Speed And Cadence Service + 147210 [2067956][E](BLE_Client): PM CAD-BLE0418789 b1 didn't match the saved: ASSIOMA17287L 16 + 147211 [2068761][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147212 [2071484][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147213 [2072823][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 95, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147214 [2073536][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147215 [2073537][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147216 [2074298][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147217 [2077565][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147218 [2078834][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 96, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147219 [2079616][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147220 [2079617][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147221 [2080352][E](BLE_Client): Found device c8:27:52:ec:ec:1c with services: 0xfeaf + 147222 [2080956][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147223 [2083641][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147224 [2084851][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 94, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147225 [2085695][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147226 [2085696][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147227 [2085926][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147228 [2089720][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147229 [2090868][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 94, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147230 [2091770][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147231 [2091770][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147232 [2092307][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147233 [2095794][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147234 [2096885][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 99, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147235 [2097842][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147236 [2097843][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147237 [2099294][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147238 [2101866][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147239 [2102901][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 97, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147240 [2103915][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147241 [2103916][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147242 [2103995][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147243 [2107939][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147244 [2108910][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 92, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147245 [2109988][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147246 [2109989][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147247 [2112015][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147248 [2114017][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147249 [2114928][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 90, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147250 [2116063][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147251 [2116064][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147252 [2116448][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147253 [2120088][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147254 [2120941][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147255 [2122139][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147256 [2122140][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147257 [2122533][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147258 [2126163][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147259 [2126953][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 91, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147260 [2128214][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147261 [2128215][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147262 [2128623][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147263 [2132245][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147264 [2132967][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 93, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147265 [2134288][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147266 [2134289][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147267 [2136389][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147268 [2138313][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147269 [2138981][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147270 [2140364][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147271 [2140364][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147272 [2142755][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147273 [2144388][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147274 [2144998][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147275 [2146441][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147276 [2146442][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147277 [2147013][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147278 [2150471][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147279 [2151011][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 93, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147280 [2152515][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147281 [2152516][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147282 [2152550][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147283 [2156538][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147284 [2157026][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 88, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147285 [2158590][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147286 [2158591][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147287 [2161698][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147288 [2162613][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147289 [2163042][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147290 [2164663][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147291 [2164664][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147292 [2164941][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147293 [2168691][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147294 [2169054][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147295 [2170738][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147296 [2170739][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147297 [2172399][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147298 [2174762][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147299 [2175066][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 88, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147300 [2176816][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147301 [2176817][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147302 [2177387][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147303 [2180840][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147304 [2181079][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 91, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147305 [2182889][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147306 [2182890][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147307 [2182915][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147308 [2186912][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147309 [2187094][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 94, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147310 [2188963][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147311 [2188964][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147312 [2190123][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147313 [2192986][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147314 [2193111][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 90, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147315 [2195036][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147316 [2195037][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147317 [2197038][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147318 [2199058][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147319 [2199127][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 91, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147320 [2201110][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147321 [2201111][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147322 [2202571][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147323 [2205136][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147324 [2205140][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 90, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147325 [2207188][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147326 [2207189][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147327 [2207282][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147328 [2211165][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 91, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147329 [2211213][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147330 [2213262][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147331 [2213263][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147332 [2213934][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147333 [2217179][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 93, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147334 [2217284][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147335 [2219336][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147336 [2219336][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147337 [2219469][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147338 [2223193][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 91, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147339 [2223359][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147340 [2225411][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147341 [2225412][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147342 [2225555][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147343 [2229208][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 93, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147344 [2229437][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147345 [2231487][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147346 [2231488][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147347 [2231919][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147348 [2235220][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147349 [2235516][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147350 [2237561][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147351 [2237562][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147352 [2238760][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147353 [2241235][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 92, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147354 [2241583][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147355 [2243635][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147356 [2243635][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147357 [2245131][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147358 [2247250][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 91, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147359 [2247661][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147360 [2249707][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147361 [2249708][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147362 [2250673][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147363 [2253261][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 93, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147364 [2253734][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147365 [2255781][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147366 [2255782][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147367 [2256222][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147368 [2259278][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 95, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147369 [2259805][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147370 [2261855][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147371 [2261856][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147372 [2262034][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147373 [2265290][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 93, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147374 [2265883][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147375 [2267930][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147376 [2267931][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147377 [2268957][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147378 [2271301][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 92, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147379 [2271952][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147380 [2274003][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147381 [2274004][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147382 [2274487][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147383 [2277317][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 93, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147384 [2278026][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147385 [2280079][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147386 [2280080][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147387 [2280303][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147388 [2283331][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 96, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147389 [2284108][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147390 [2286153][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147391 [2286153][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147392 [2286394][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147393 [2289340][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 88, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147394 [2290176][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147395 [2292225][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147396 [2292226][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147397 [2293335][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147398 [2295356][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 92, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147399 [2296250][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147400 [2298300][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147401 [2298301][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147402 [2298585][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147403 [2301370][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147404 [2302325][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147405 [2304374][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147406 [2304374][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147407 [2304399][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147408 [2307385][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147409 [2308397][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147410 [2310449][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147411 [2310449][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147412 [2311306][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147413 [2313398][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 94, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147414 [2314472][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147415 [2316524][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147416 [2316524][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147417 [2316836][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147418 [2319408][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 94, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147419 [2320547][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147420 [2322600][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147421 [2322601][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147422 [2323751][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147423 [2325423][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 94, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147424 [2326624][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147425 [2328682][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147426 [2328682][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147427 [2329854][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147428 [2331435][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 94, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147429 [2332703][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147430 [2334754][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147431 [2334755][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147432 [2335948][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147433 [2337447][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 90, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147434 [2338781][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147435 [2340828][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147436 [2340829][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147437 [2342610][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147438 [2343460][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147439 [2344850][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147440 [2346905][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147441 [2346906][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147442 [2347863][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147443 [2349476][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 91, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147444 [2350929][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147445 [2352980][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147446 [2352981][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147447 [2354781][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147448 [2355485][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 94, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147449 [2357006][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147450 [2359054][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147451 [2359054][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147452 [2359225][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147453 [2361497][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 91, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147454 [2363075][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147455 [2365126][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147456 [2365127][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147457 [2367509][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147458 [2368833][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147459 [2369152][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147460 [2371200][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147461 [2371201][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147462 [2371331][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147463 [2373518][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 92, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147464 [2375224][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147465 [2377276][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147466 [2377277][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147467 [2377422][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147468 [2379532][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147469 [2380737][E](BLE_Client): Found device c8:27:52:ec:ec:1c with services: 0xfeaf + 147470 [2381302][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147471 [2383351][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147472 [2383352][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147473 [2384072][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147474 [2385545][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 92, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147475 [2387374][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147476 [2389430][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147477 [2389431][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147478 [2390165][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147479 [2391563][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 88, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147480 [2393453][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147481 [2395503][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147482 [2395504][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147483 [2396526][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147484 [2397577][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 90, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147485 [2399527][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147486 [2401577][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147487 [2401578][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147488 [2402346][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147489 [2403588][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147490 [2405601][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147491 [2407650][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147492 [2407651][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147493 [2407887][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147494 [2409605][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 94, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147495 [2411672][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147496 [2413725][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147497 [2413725][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147498 [2415622][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 90, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147499 [2416748][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147500 [2417750][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147501 [2419803][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147502 [2419804][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147503 [2420076][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147504 [2421634][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 90, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147505 [2423827][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147506 [2425877][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147507 [2425878][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147508 [2426703][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147509 [2427645][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147510 [2429899][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147511 [2431953][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147512 [2431954][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147513 [2433658][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 86, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147514 [2434445][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147515 [2435980][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147516 [2438034][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147517 [2438035][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147518 [2438324][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147519 [2439669][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 90, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147520 [2440799][E](BLE_Client): Found device c8:27:52:ec:ec:1c with services: 0xfeaf + 147521 [2442061][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147522 [2444113][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147523 [2444114][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147524 [2444136][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147525 [2445684][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 87, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147526 [2448135][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147527 [2450186][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147528 [2450187][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147529 [2451696][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147530 [2452720][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147531 [2454211][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147532 [2456261][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147533 [2456262][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147534 [2456591][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147535 [2457713][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 90, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147536 [2460286][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147537 [2462335][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147538 [2462336][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147539 [2462456][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147540 [2463723][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 88, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147541 [2466361][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147542 [2468409][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147543 [2468409][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147544 [2469733][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 91, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147545 [2470757][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147546 [2472438][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147547 [2474489][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147548 [2474490][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147549 [2474903][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147550 [2475747][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 91, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147551 [2478512][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147552 [2480562][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147553 [2480563][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147554 [2480983][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147555 [2481759][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 90, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147556 [2484586][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147557 [2486635][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147558 [2486636][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147559 [2486807][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147560 [2487768][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 93, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147561 [2490663][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147562 [2492713][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147563 [2492713][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147564 [2492905][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147565 [2493783][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 92, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147566 [2496737][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147567 [2498788][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147568 [2498789][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147569 [2499800][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 92, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147570 [2500150][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147571 [2502811][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147572 [2504861][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147573 [2504862][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147574 [2505813][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 95, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147575 [2507637][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147576 [2508884][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147577 [2510935][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147578 [2510936][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147579 [2511830][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 98, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147580 [2512889][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147581 [2514959][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147582 [2517010][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147583 [2517010][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147584 [2517581][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147585 [2517841][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 93, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147586 [2521034][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147587 [2523086][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147588 [2523086][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147589 [2523383][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147590 [2523855][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 91, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147591 [2527108][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147592 [2529159][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147593 [2529160][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147594 [2529870][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 90, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147595 [2531689][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147596 [2533183][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147597 [2535236][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147598 [2535237][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147599 [2535880][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 93, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147600 [2536400][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147601 [2539258][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147602 [2541310][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147603 [2541311][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147604 [2541895][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 93, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147605 [2542111][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147606 [2545335][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147607 [2547387][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147608 [2547388][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147609 [2547910][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 91, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147610 [2550413][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147611 [2551411][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147612 [2553462][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147613 [2553463][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147614 [2553924][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 91, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147615 [2554082][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147616 [2557485][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147617 [2559536][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147618 [2559537][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147619 [2559941][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 88, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147620 [2560463][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147621 [2563562][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147622 [2565609][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147623 [2565610][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147624 [2565958][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 95, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147625 [2567111][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147626 [2569636][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147627 [2571684][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147628 [2571685][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147629 [2571827][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147630 [2571975][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147631 [2575711][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147632 [2577758][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147633 [2577759][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147634 [2577992][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 88, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147635 [2581787][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147636 [2583832][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147637 [2583833][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147638 [2583975][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147639 [2584009][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 86, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147640 [2587859][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147641 [2589907][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147642 [2589908][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147643 [2590025][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 87, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147644 [2592275][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147645 [2593934][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147646 [2595982][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147647 [2595983][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147648 [2596040][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 87, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147649 [2596427][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147650 [2600011][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147651 [2602054][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 87, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147652 [2602062][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147653 [2602073][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147654 [2602544][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147655 [2606085][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} + 147656 [2608063][E](Main): PM Con 0, CAD con 0, HRM Con 1, W 0, Cad 0, HR 89, Gear 12, Res 48, Current Pos 14281, Target Pos 14281 + 147657 [2608137][E](BLE_Client): Devices not connected: PM (cfgHRM='Polar OH1 B9B6D624 d6' cfgPM='ASSIOMA17287L 16' cfgRemote='none') + 147658 [2608138][E](BLE_Client): Scanning for BLE servers and putting them into a list... + 147659 [2610015][E](BLE_Client): Found device SHIELD 36 with services: 0x3456 + 147660 [2612161][E](BLE_Client): Found Devices: {"device 0":{"name":"CAD-BLE0418789 b1","UUID":"0x1816"}} \ No newline at end of file diff --git a/test/test_table_fill.cpp b/test/test_table_fill.cpp index 375784ef..1577e0ac 100644 --- a/test/test_table_fill.cpp +++ b/test/test_table_fill.cpp @@ -76,7 +76,7 @@ void TestTableFill::test_fill_incomplete_table(void) { cleanAndCreateDir(outputDir); // Open Ride_Log.txt - std::ifstream rideLog("test/data/ride_log3.txt"); + std::ifstream rideLog("test/data/ride_log4.txt"); // Prepare regex for Averaged Entry lines std::regex entryRegex(R"(\[(\d+)\]\[E\]\(PTable\): Averaged Entry: watts=([\d\.\-]+), cad=([\d\.\-]+), targetPosition=([\d\.\-]+), \((\d+)\)\((\d+)\))"); From 698bc28a0a66c7b6a40b5ebef4e808063b81b07b Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Wed, 7 Jan 2026 18:24:03 -0600 Subject: [PATCH 450/451] Refactor ERG mode logic and improve cadence calculations; add mode struct for clarity --- CHANGELOG.md | 4 + include/ERG_Mode.h | 25 +++-- lib/SS2K/src/sensors/CscSensorData.cpp | 4 +- lib/SS2K/src/sensors/CyclePowerData.cpp | 2 +- .../sensors/FitnessMachineIndoorBikeData.cpp | 2 +- lib/SS2K/src/sensors/PelotonData.cpp | 2 +- src/BLE_Client.cpp | 20 +++- src/ERG_Mode.cpp | 100 +++++++++++------- src/Main.cpp | 8 +- src/PowerTable_Helpers.cpp | 7 +- src/SensorCollector.cpp | 2 +- 11 files changed, 111 insertions(+), 65 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e786337d..8a51b8f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added feed forward, disabled PowerTable for ERG lookup. - Added tests and removal of duplicates in pt column. - Added removal of negative numbers in pt table. +- Refined ERG mode (stateful increase/decrease handling, smarter wait timers, improved PID logging). +- Adjusted FTMS resistance handling: ignore malformed IC Bike ranges, log raw range data, and skip IC Bike resistance samples. +- Rounded cadence/power calculations across CSC, CyclePower, Peloton, FTMS decoding; clamp invalid cadence values. +- Applied rounding for FTMS shift targets/resistance mapping and homing thresholds; use fabs in resistance model and paused duplicate cleanup. ### Hardware diff --git a/include/ERG_Mode.h b/include/ERG_Mode.h index c01c5650..66ea7071 100644 --- a/include/ERG_Mode.h +++ b/include/ERG_Mode.h @@ -14,34 +14,37 @@ #define ERG_MODE_LOG_TAG "ERG_Mode" #define ERG_MODE_DELAY 700 +struct Mode { + static const int MAINTAIN = 0; + static const int DECREASING = 1; + static const int INCREASING = 2; +}; + class ErgMode { public: - // What used to be in the ERGTaskLoop(). This is the main control function for ERG Mode and the powertable operations. + // What used to be in the ERGTaskLoop(). This is the main control function for ERG Mode and the powertable operations. void runERG(); void computeErg(); void _writeLog(float currentIncline, float newIncline, int currentSetPoint, int newSetPoint, int currentWatts, int newWatts, int currentCadence, int newCadence); private: - bool engineStopped = false; - bool initialized = false; - int setPoint = 0; - int offsetMultiplier = 0; - int resistance = 0; - int cadence = 0; + bool engineStopped = false; - Measurement watts; + int mode = Mode::MAINTAIN; + Measurement prevWatts; + Measurement prevCadence; // check if user is spinning, reset incline if user stops spinning bool _userIsSpinning(int cadence, float incline); // calculate incline if setpoint (from Zwift) changes - int32_t _setPointChangeState(int newCadence, Measurement& newWatts); + int32_t _setPointChangeState(); // calculate incline if setpoint is unchanged - int32_t _inSetpointState(int newCadence, Measurement& newWatts); + int32_t _inSetpointState(); // update localvalues + incline, creates a log - void _updateValues(int newCadence, Measurement& newWatts, float newIncline); + void _updateValues(float newIncline); }; extern ErgMode* ergMode; diff --git a/lib/SS2K/src/sensors/CscSensorData.cpp b/lib/SS2K/src/sensors/CscSensorData.cpp index 6e8f24b2..67a6cf05 100644 --- a/lib/SS2K/src/sensors/CscSensorData.cpp +++ b/lib/SS2K/src/sensors/CscSensorData.cpp @@ -88,10 +88,10 @@ void CscSensorData::decode(uint8_t *data, size_t length) { // Time is in 1/1024th of a second float revolutions = crankRevolutions - lastCrankRevolutions; float timeMinutes = (timeDiff / 1024.0f) / 60.0f; - float cadence = revolutions / timeMinutes; + float cadence = std::round(revolutions / timeMinutes); if (cadence > 1) { - if (cadence > 200) { // Human is unlikely producing 200+ cadence + if (cadence > 200 || cadence < 0) { // Human is unlikely producing 200+ cadence // Cadence Error: Could happen if cadence measurements were missed // Leave cadence unchanged cadence = this->cadence; diff --git a/lib/SS2K/src/sensors/CyclePowerData.cpp b/lib/SS2K/src/sensors/CyclePowerData.cpp index 3bfdcb42..3ccff280 100644 --- a/lib/SS2K/src/sensors/CyclePowerData.cpp +++ b/lib/SS2K/src/sensors/CyclePowerData.cpp @@ -122,7 +122,7 @@ void CyclePowerData::decode(uint8_t *data, size_t length) { // This casting behavior makes sure the roll over works correctly. Unit tests confirm const float crankChange = (uint16_t)((this->crankRev - this->lastCrankRev) * 1024); const float timeElapsed = (uint16_t)(this->crankEventTime - this->lastCrankEventTime); - float cadence = (crankChange / timeElapsed) * 60; + float cadence = std::round((crankChange / timeElapsed) * 60); // cadence in RPM if (cadence > 1) { if (cadence > 200) { // Human is unlikely producing 200+ cadence // Cadence Error: Could happen if cadence measurements were missed diff --git a/lib/SS2K/src/sensors/FitnessMachineIndoorBikeData.cpp b/lib/SS2K/src/sensors/FitnessMachineIndoorBikeData.cpp index 4b227708..b3879b75 100644 --- a/lib/SS2K/src/sensors/FitnessMachineIndoorBikeData.cpp +++ b/lib/SS2K/src/sensors/FitnessMachineIndoorBikeData.cpp @@ -81,7 +81,7 @@ void FitnessMachineIndoorBikeData::decode(uint8_t *data, size_t length) { } dataIndex += byteSize; value = convert(value, byteSize, signedFlags[typeIndex]); - double_t result = double_t(static_cast((value * resolutions[typeIndex] * 10) + 0.5)) / 10.0; + double_t result = double_t(static_cast(std::round((value * resolutions[typeIndex] * 10) + 0.5)) / 10.0); values[typeIndex] = result; continue; } diff --git a/lib/SS2K/src/sensors/PelotonData.cpp b/lib/SS2K/src/sensors/PelotonData.cpp index 57c6099e..70baeabe 100644 --- a/lib/SS2K/src/sensors/PelotonData.cpp +++ b/lib/SS2K/src/sensors/PelotonData.cpp @@ -49,7 +49,7 @@ void PelotonData::decode(uint8_t *data, size_t length) { switch (data[1]) { case PELOTON_POW_ID: if (value >= 0) { - power = value / 10; + power = std::round(value / 10); } else { power = 0; } diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index f88ad69c..5a8db07b 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -724,7 +724,11 @@ void SpinBLEClient::postConnect() { } // update resistance range if supported: auto resistanceRangeCharacteristic = pClient->getService(FITNESSMACHINESERVICE_UUID)->getCharacteristic(FITNESSMACHINERESISTANCELEVELRANGE_UUID); - if (resistanceRangeCharacteristic && resistanceRangeCharacteristic->canRead()) { + // Schwinn IC4 bikes don't transmit in the proper format, so we need to ignore this on bikes with names that start with "IC Bike" + if (adevName.startsWith("IC Bike")) { + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Ignoring FTMS Resistance Range characteristic on IC Bike device: %s", _BLEd.uniqueName.c_str()); + resistanceRangeCharacteristic = nullptr; + } else if (resistanceRangeCharacteristic && resistanceRangeCharacteristic->canRead()) { auto rr = resistanceRangeCharacteristic->readValue(); if (rr.size() >= 6) { const uint8_t* b = reinterpret_cast(rr.data()); @@ -749,6 +753,15 @@ void SpinBLEClient::postConnect() { rtConfig->resistance.setMin(minRes); rtConfig->resistance.setMax(maxRes); + // log the entire characteristic info + String rrLog = "FTMS Resistance Range raw data:"; + for (size_t i = 0; i < rr.size(); i++) { + char buf[3]; + snprintf(buf, sizeof(buf), "%02X", static_cast(rr[i])); + rrLog += " " + String(buf); + } + SS2K_LOG(BLE_CLIENT_LOG_TAG, "%s", rrLog.c_str()); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "FTMS Resistance Range: raw min=%.1f raw max=%.1f inc=%.1f -> set %d->%d", minF, maxF, incF, minRes, maxRes); } else { SS2K_LOG(BLE_CLIENT_LOG_TAG, "FTMS Resistance Range characteristic too short (%d bytes)", rr.size()); @@ -931,8 +944,7 @@ void SpinBLEClient::checkBLEReconnect() { } if (offset > 0) { - SS2K_LOG(BLE_CLIENT_LOG_TAG, "Devices not connected: %s (cfgHRM='%s' cfgPM='%s' cfgRemote='%s')", - notConnectedDevices, cfgHRM, cfgPM, cfgRemote); + SS2K_LOG(BLE_CLIENT_LOG_TAG, "Devices not connected: %s (cfgHRM='%s' cfgPM='%s' cfgRemote='%s')", notConnectedDevices, cfgHRM, cfgPM, cfgRemote); this->doScan = true; } } @@ -1086,7 +1098,7 @@ void SpinBLEAdvertisedDevice::set(const NimBLEAdvertisedDevice* device, int id, for (auto& pService : services) { BLEUUID serviceUUID = pService->getUUID(); if (serviceUUID == HEARTSERVICE_UUID) { - this->isHRM = true; + this->isHRM = true; if (cfgHrmIsNone || cfgHrmIsAny || hrmNameMatch || hrmAddrMatch) { spinBLEClient.connectedHRM = true; SS2K_LOG(BLE_CLIENT_LOG_TAG, "Registered HRM on Connect"); diff --git a/src/ERG_Mode.cpp b/src/ERG_Mode.cpp index ba91b702..d9141125 100644 --- a/src/ERG_Mode.cpp +++ b/src/ERG_Mode.cpp @@ -28,9 +28,37 @@ void ErgMode::runERG() { static bool simulationRunning = false; static int loopCounter = 0; + if (mode == Mode::INCREASING) { + if (rtConfig->watts.getValue() > rtConfig->watts.getTarget()) { // Resume PID control + ergTimer = 0; + mode = Mode::MAINTAIN; + SS2K_LOG(ERG_MODE_LOG_TAG, "ERG increasing target reached."); + } else if (rtConfig->watts.getValue() >= this->prevWatts.getValue()) { + // power is still increasing, wait longer + return; + } + } else if (mode == Mode::DECREASING) { + if (rtConfig->watts.getValue() < rtConfig->watts.getTarget()) // Resume PID control + { + ergTimer = 0; + mode = Mode::MAINTAIN; + SS2K_LOG(ERG_MODE_LOG_TAG, "ERG decreasing target reached."); + } else if (rtConfig->watts.getValue() <= this->prevWatts.getValue()) { + // power is still decreasing, wait longer + return; + } + } + if (isDelayed && (ss2k->getCurrentPosition() == ss2k->getTargetPosition())) { + SS2K_LOG(ERG_MODE_LOG_TAG, "ERG delay cleared, %dw, tgt %dw, pos %d, tgt %d", rtConfig->watts.getValue(), rtConfig->watts.getTarget(), ss2k->getCurrentPosition(), + ss2k->getTargetPosition()); + ergTimer = millis() + ERG_MODE_DELAY; + isDelayed = false; + } + if ((millis() > ergTimer)) { if (isDelayed) { - SS2K_LOG(ERG_MODE_LOG_TAG, "ERG wait expired, pos: %d, tgt: %d", ss2k->getCurrentPosition(), rtConfig->getTargetIncline()); + SS2K_LOG(ERG_MODE_LOG_TAG, "ERG wait expired, %dw, tgt %dw, pos %d, tgt %d", rtConfig->watts.getValue(), rtConfig->watts.getTarget(), ss2k->getCurrentPosition(), + ss2k->getTargetPosition()); isDelayed = false; } @@ -51,7 +79,7 @@ void ErgMode::runERG() { } } // Load power table if not yet loaded this session - if(!powerTable->_hasBeenLoadedThisSession) { + if (!powerTable->_hasBeenLoadedThisSession) { powerTable->_manageSaveState(); } @@ -123,46 +151,46 @@ void ErgMode::runERG() { // as a note, Trainer Road sends 50w target whenever the app is connected. void ErgMode::computeErg() { - Measurement newWatts = rtConfig->watts; - int newCadence = rtConfig->cad.getValue(); - int32_t result = RETURN_ERROR; + int32_t result = RETURN_ERROR; - bool isUserSpinning = this->_userIsSpinning(newCadence, ss2k->getCurrentPosition()); + bool isUserSpinning = this->_userIsSpinning(rtConfig->cad.getValue(), ss2k->getCurrentPosition()); if (!isUserSpinning) { SS2K_LOG(ERG_MODE_LOG_TAG, "ERG Mode but no User Spin"); return; } // set minimum set point to minimum bike watts if app sends set point lower than minimum bike watts. - if (newWatts.getTarget() < userConfig->getMinWatts()) { + if (rtConfig->watts.getTarget() < userConfig->getMinWatts()) { SS2K_LOG(ERG_MODE_LOG_TAG, "ERG Target Below Minumum Value."); - newWatts.setTarget(userConfig->getMinWatts()); + rtConfig->watts.setTarget(userConfig->getMinWatts()); } // check for new torque value or new set point, if watts < 0 treat as faulty - if ((this->watts.getTimestamp() == newWatts.getTimestamp() && this->setPoint == newWatts.getTarget()) || newWatts.getValue() < 0) { + if ((this->prevWatts.getTimestamp() == rtConfig->watts.getTimestamp() && this->prevWatts.getTarget() == rtConfig->watts.getTarget()) || rtConfig->watts.getValue() < 0) { SS2K_LOG(ERG_MODE_LOG_TAG, "Watts previously processed."); return; } #ifdef ERG_MODE_USE_POWER_TABLE - if (abs(this->setPoint - newWatts.getTarget()) > ERG_MODE_PID_WINDOW && rtConfig->getHomed()) { - result = _setPointChangeState(newCadence, newWatts); + if (abs(this->prevWatts.getTarget() - rtConfig->watts.getTarget()) > POWERTABLE_CAD_INCREMENT && rtConfig->getHomed()) { + result = _setPointChangeState(); } #endif #ifdef ERG_MODE_USE_PID // Setpoint unchanged if (result == INT32_MIN) { - result = _inSetpointState(newCadence, newWatts); + result = _inSetpointState(); } #endif - _updateValues(newCadence, newWatts, result); + _updateValues(result); } -int32_t ErgMode::_setPointChangeState(int newCadence, Measurement& newWatts) { +int32_t ErgMode::_setPointChangeState() { + mode = (rtConfig->watts.getTarget() > rtConfig->watts.getValue()) ? Mode::INCREASING : Mode::DECREASING; // It's better to undershoot increasing watts and overshoot decreasing watts, so lets set the lookup target to the nearest side of POWERTABLE_WATT_INCREMENT - int adjustedWattTarget = newWatts.getTarget() >= newWatts.getValue() ? newWatts.getTarget() - POWERTABLE_WATT_INCREMENT : newWatts.getTarget() + POWERTABLE_WATT_INCREMENT; - int32_t tableResult = powerTable->lookup(adjustedWattTarget, newCadence); + int adjustedWattTarget = (mode == Mode::INCREASING) ? rtConfig->watts.getTarget() - POWERTABLE_WATT_INCREMENT : rtConfig->watts.getTarget() + POWERTABLE_WATT_INCREMENT; + int32_t tableResult = powerTable->lookup(adjustedWattTarget, + (mode == Mode::INCREASING) ? rtConfig->cad.getValue() + POWERTABLE_CAD_INCREMENT : rtConfig->cad.getValue() - POWERTABLE_CAD_INCREMENT); // Sanity check - with homing enabled, we should never have a negative result. If we do, something went wrong. if (rtConfig->getHomed() && tableResult < 0) { @@ -172,11 +200,11 @@ int32_t ErgMode::_setPointChangeState(int newCadence, Measurement& newWatts) { // Test current watts against the table result. If We're already lower or higher than target, flag the result as a return error. if (tableResult != RETURN_ERROR) { - if (adjustedWattTarget > newWatts.getValue() && tableResult < ss2k->getCurrentPosition()) { + if (adjustedWattTarget > rtConfig->watts.getValue() && tableResult < ss2k->getCurrentPosition()) { SS2K_LOG(ERG_MODE_LOG_TAG, "Table Result Failed increasing Test: %d", tableResult); tableResult = RETURN_ERROR; } - if ((adjustedWattTarget < newWatts.getValue()) && tableResult > ss2k->getCurrentPosition()) { + if ((adjustedWattTarget < rtConfig->watts.getValue()) && tableResult > ss2k->getCurrentPosition()) { SS2K_LOG(ERG_MODE_LOG_TAG, "Table Result Failed decreasing Test: %d", tableResult); tableResult = RETURN_ERROR; } @@ -185,18 +213,18 @@ int32_t ErgMode::_setPointChangeState(int newCadence, Measurement& newWatts) { // Handle return errors if (tableResult == RETURN_ERROR) { SS2K_LOG(ERG_MODE_LOG_TAG, "Lookup Error. Using PID"); - tableResult = _inSetpointState(newCadence, newWatts); + tableResult = _inSetpointState(); } else { if (tableResult != ss2k->getCurrentPosition()) { // add some time to wait while the knob moves to target position. isDelayed = true; long int stepDistance = abs(ss2k->getCurrentPosition() - tableResult); // Calculate time to add based on step distance and stepper speed - long int timeToAdd = round(((double)stepDistance * 1000.0) / (double)userConfig->getStepperSpeed() + ERG_MODE_DELAY); + long int timeToAdd = round((((double)stepDistance * 1000.0) / (double)userConfig->getStepperSpeed()) * 2); if (timeToAdd > 10000) { // 10 seconds SS2K_LOG(ERG_MODE_LOG_TAG, "Capping ERG seek time to 10 seconds"); timeToAdd = 10000; } - SS2K_LOG(ERG_MODE_LOG_TAG, "SetPoint changed:%dw Waiting:%dms PowerTable Result: %d", adjustedWattTarget, timeToAdd, tableResult); + SS2K_LOG(ERG_MODE_LOG_TAG, "Adjusted setpoint returned: %dw %drpm Waiting:%dms PowerTable Result: %d", adjustedWattTarget, rtConfig->cad.getValue(), timeToAdd, tableResult); ergTimer += timeToAdd; } ergTimer += (ERG_MODE_DELAY); // Wait for power meter to register new watts @@ -212,19 +240,19 @@ int32_t ErgMode::_setPointChangeState(int newCadence, Measurement& newWatts) { // Derivative term: rate of change of error // PrevError -int32_t ErgMode::_inSetpointState(int newCadence, Measurement& newWatts) { +int32_t ErgMode::_inSetpointState() { // Setting Gains For PID Loop double Kp = userConfig->getERGSensitivity(); // Proportional gain based on user sensitivity // retrieves the current Watt output - int watts = newWatts.getValue(); + int watts = rtConfig->watts.getValue(); // retrieves target Watt output - int target = newWatts.getTarget(); + int target = rtConfig->watts.getTarget(); // subtracting target from current watts int error = target - watts; // modifying gains based on error - if (abs(error) < 10) { + if (abs(error) < 10 || (mode != Mode::MAINTAIN)) { Kp = Kp * 0.25; // decrease further for tiny errors } else if (abs(error) < 50) { Kp = Kp * 0.75; // Moderate for medium errors @@ -232,9 +260,11 @@ int32_t ErgMode::_inSetpointState(int newCadence, Measurement& newWatts) { Kp = Kp * 1.25; // Aggressive for large errors } + mode = Mode::MAINTAIN; + // Defining proportional term double proportional = Kp * error; - if (newWatts.getValue() < userConfig->getMinWatts()) { + if (rtConfig->watts.getValue() < userConfig->getMinWatts()) { proportional = proportional * userConfig->getERGSensitivity(); // increase proportional term when at very low watts. Prevents Zwift from timeout on initial interval. } @@ -245,7 +275,7 @@ int32_t ErgMode::_inSetpointState(int newCadence, Measurement& newWatts) { static unsigned long lastTime = 0; if (millis() - lastTime > 5000) { lastTime = millis(); - SS2K_LOG(ERG_MODE_LOG_TAG, "Proportional: %f", proportional); + SS2K_LOG(ERG_MODE_LOG_TAG, "%dw, Target %dw, Proportional: %f", rtConfig->watts.getValue(), rtConfig->watts.getTarget(), proportional); } // Cap the change to no more than we can move until the next reading @@ -261,24 +291,20 @@ int32_t ErgMode::_inSetpointState(int newCadence, Measurement& newWatts) { return newIncline; } -void ErgMode::_updateValues(int newCadence, Measurement& newWatts, float newIncline) { +void ErgMode::_updateValues(float newIncline) { rtConfig->setTargetIncline(newIncline); - _writeLog(ss2k->getCurrentPosition(), newIncline, this->setPoint, newWatts.getTarget(), this->watts.getValue(), newWatts.getValue(), this->cadence, newCadence); + _writeLog(ss2k->getCurrentPosition(), newIncline, this->prevWatts.getTarget(), rtConfig->watts.getTarget(), this->prevWatts.getValue(), rtConfig->watts.getValue(), + this->prevCadence.getValue(), rtConfig->cad.getValue()); - this->watts = newWatts; - this->setPoint = newWatts.getTarget(); - this->cadence = newCadence; + this->prevWatts = rtConfig->watts; + this->prevCadence = rtConfig->cad; } bool ErgMode::_userIsSpinning(int cadence, float incline) { if (cadence <= MIN_ERG_CADENCE) { - if (!this->engineStopped) { // Test so motor stop command only happens once. // release tension - rtConfig->setTargetIncline(0); // release incline - this->engineStopped = true; - } + rtConfig->setFTMSMode(FitnessMachineControlPointProcedure::SetIndoorBikeSimulationParameters); return false; // Cadence too low, nothing to do here } - this->engineStopped = false; return true; } diff --git a/src/Main.cpp b/src/Main.cpp index 28a9eed6..10207861 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -349,7 +349,7 @@ void SS2K::FTMSModeShiftModifier() { SS2K_LOG(MAIN_LOG_TAG, "ERG Shift. New Target: %dw", rtConfig->watts.getTarget()); // Format output for FTMS passthrough #ifndef INTERNAL_ERG_4EXT_FTMS - int adjustedTarget = rtConfig->watts.getTarget() / userConfig->getPowerCorrectionFactor(); + int adjustedTarget = round(rtConfig->watts.getTarget() / userConfig->getPowerCorrectionFactor()); const uint8_t translated[] = {FitnessMachineControlPointProcedure::SetTargetPower, (uint8_t)(adjustedTarget & 0xff), (uint8_t)(adjustedTarget >> 8)}; spinBLEClient.FTMSControlPointWrite(translated, 3); #endif @@ -525,7 +525,7 @@ void SS2K::_resistanceMove() { if (resistancePercent < 0) resistancePercent = 0; if (resistancePercent > 100) resistancePercent = 100; int64_t span = (int64_t)maxPos - (int64_t)minPos; - int32_t pos = minPos + (int32_t)((span * resistancePercent) / 100); + int32_t pos = minPos + (int32_t)round((span * resistancePercent) / 100.0f); if (usePwr) { // fallback to using ERG rtConfig->watts.setTarget(pos); rtConfig->setFTMSMode(FitnessMachineControlPointProcedure::SetTargetPower); @@ -654,7 +654,7 @@ void SS2K::_findEndStop(bool moveForward) { totalSgResult += driver.SG_RESULT(); delay(10); // Small delay between samples } - threshold = totalSgResult / SAMPLES_TO_AVERAGE; + threshold = round(totalSgResult / (float)SAMPLES_TO_AVERAGE); SS2K_LOG(MAIN_LOG_TAG, "Homing %s. Stable Threshold: %d, Sensitivity: %d", moveForward ? "forward (max)" : "backward (min)", threshold, userConfig->getHomingSensitivity()); @@ -756,7 +756,7 @@ void SS2K::_findFTMSHome(bool bothDirections) { ss2k->updateStepperSpeed(1500); // Use a slow-medium speed for homing // first back off of the stop if we're already there - int midTarget = (rtConfig->resistance.getMax() - rtConfig->resistance.getMin()) / 4; + int midTarget = round((rtConfig->resistance.getMax() - rtConfig->resistance.getMin()) / 4.0f); rtConfig->resistance.setTarget(midTarget); runHomingSweep(midTarget, nullptr, false); runHomingSweep(rtConfig->resistance.getMin(), "Homing to Min Resistance... Current: %d, Target: %d", false); diff --git a/src/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp index 9b2ca5b0..5e41663a 100644 --- a/src/PowerTable_Helpers.cpp +++ b/src/PowerTable_Helpers.cpp @@ -223,9 +223,9 @@ int ResistanceModel::predictWatts(int32_t resistance, float cadence) { } // 3. Solve - if (abs(QA) < 1e-9) { + if (std::fabs(QA) < 1e-9) { // --- Linear Solve --- - if (abs(QB) < 1e-9) return 0; + if (std::fabs(QB) < 1e-9) return 0; predictedNormWatts = -QC / QB; } else { // --- Quadratic Solve --- @@ -596,6 +596,7 @@ void PTHelpers::clean(PTData& ptData) { } } + /* // Second pass: remove duplicate values in columns (same resistance for multiple cadences) // For each column, track all unique values and remove duplicates for (int j = 0; j < POWERTABLE_WATT_SIZE; j++) { @@ -629,7 +630,7 @@ void PTHelpers::clean(PTData& ptData) { } } } - } + }*/ if (removed > 0) { SS2K_LOG(PTDATA_LOG_TAG, "Cleaned %d readings", removed); diff --git a/src/SensorCollector.cpp b/src/SensorCollector.cpp index 2b21c2bc..a18befe3 100644 --- a/src/SensorCollector.cpp +++ b/src/SensorCollector.cpp @@ -93,7 +93,7 @@ void collectAndSet(NimBLEUUID charUUID, NimBLEUUID serviceUUID, std::string& uni logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " SD(%.2f)", fmodf(sensorData->getSpeed(), 1000.0)); } - if (sensorData->hasResistance()) { + if (sensorData->hasResistance() && !uniqueName.starts_with("IC Bike")) { // Blacklist IC Bike resistance due to non-standard compliance rtConfig->resistance.setSimulate(false); // Mark as real data if ((ss2k->pelotonIsConnected) && (charUUID != PELOTON_DATA_UUID)) { // Peloton connected but using BLE Power Meter. So skip resistance for UUID's that aren't Peloton. From 55995e753f34e2896be2c345d88db9b3d8b084b6 Mon Sep 17 00:00:00 2001 From: Anthony Doud Date: Fri, 9 Jan 2026 19:45:00 -0600 Subject: [PATCH 451/451] testing complete --- include/BLE_Custom_Characteristic.h | 1 + src/BLE_Custom_Characteristic.cpp | 19 ++++++++++ src/Main.cpp | 59 ++++++++++++++++++----------- src/PowerTable_Helpers.cpp | 10 ++++- 4 files changed, 64 insertions(+), 25 deletions(-) diff --git a/include/BLE_Custom_Characteristic.h b/include/BLE_Custom_Characteristic.h index 20d0d3ad..441fe4ad 100644 --- a/include/BLE_Custom_Characteristic.h +++ b/include/BLE_Custom_Characteristic.h @@ -62,6 +62,7 @@ const uint8_t BLE_hMin = 0x2A; // Minimum homing value const uint8_t BLE_hMax = 0x2B; // Maximum homing value const uint8_t BLE_homingSensitivity = 0x2C; // Homing sensitivity value const uint8_t BLE_pTab4Pwr = 0x2D; // Use power values for power table +const uint8_t BLE_UDPLogging = 0x2E; // Enable or disable UDP logging class BLE_ss2kCustomCharacteristic { public: diff --git a/src/BLE_Custom_Characteristic.cpp b/src/BLE_Custom_Characteristic.cpp index f4d92dca..ecef6582 100644 --- a/src/BLE_Custom_Characteristic.cpp +++ b/src/BLE_Custom_Characteristic.cpp @@ -814,6 +814,20 @@ void BLE_ss2kCustomCharacteristic::process(std::string rxValue) { } break; + case BLE_UDPLogging: // 0x2E + LOG_BUF_APPEND("<-UDPLogging"); + if (rxValue[0] == cc_read) { + returnValue[0] = cc_success; + returnValue[2] = (uint8_t)(userConfig->getUdpLogEnabled()); + returnLength += 1; + } + if (rxValue[0] == cc_write) { + returnValue[0] = cc_success; + userConfig->setUdpLogEnabled(rxValue[2]); + LOG_BUF_APPEND("(%s)", userConfig->getUdpLogEnabled() ? "true" : "false"); + } + break; + default: LOG_BUF_APPEND("<-Unknown Characteristic"); returnValue[0] = cc_error; @@ -996,4 +1010,9 @@ void BLE_ss2kCustomCharacteristic::parseNemit() { } return; } + if (userConfig->getUdpLogEnabled() != _oldParams.getUdpLogEnabled()) { + _oldParams.setUdpLogEnabled(userConfig->getUdpLogEnabled()); + BLE_ss2kCustomCharacteristic::notify(BLE_UDPLogging); + return; + } } diff --git a/src/Main.cpp b/src/Main.cpp index 10207861..5dd92226 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -458,36 +458,49 @@ void SS2K::moveStepper() { ss2k->syncMode = false; } + bool _closeToTarget = (abs(stepper->getCurrentPosition() - rtConfig->getMinStep()) <= (userConfig->getShiftStep() / 2)) || + (abs(stepper->getCurrentPosition() - rtConfig->getMaxStep()) <= (userConfig->getShiftStep() / 2)); + if (ss2k->pelotonIsConnected && !rtConfig->getHomed()) { - if ((rtConfig->resistance.getValue() > rtConfig->getMinResistance()) && (rtConfig->resistance.getValue() < rtConfig->getMaxResistance())) { - stepper->moveTo(ss2k->targetPosition); - } else if (rtConfig->resistance.getValue() <= rtConfig->getMinResistance()) { // Limit Stepper to Min Resistance - if (rtConfig->resistance.getValue() != rtConfig->getMinResistance()) { - stepper->moveTo(stepper->getCurrentPosition() + 20); - } - // Let the user Shift Out of this Position - if (ss2k->targetPosition > stepper->getCurrentPosition()) { - stepper->moveTo(ss2k->targetPosition); - } - } else { // Limit Stepper to Max Resistance - if (rtConfig->resistance.getValue() != rtConfig->getMaxResistance()) { - stepper->moveTo(stepper->getCurrentPosition() - 20); + // Peloton + not homed: gently walk away from the edges unless the user is actively shifting past them + if (rtConfig->resistance.getValue() < rtConfig->getMinResistance()) { // Below allowed resistance + // Nudge upward unless the user already asked to move higher + if (ss2k->targetPosition <= ss2k->getCurrentPosition()) { + ss2k->targetPosition = ss2k->getCurrentPosition() + 20; } - // Let the user Shift Out of this Position - if (ss2k->targetPosition < stepper->getCurrentPosition()) { - stepper->moveTo(ss2k->targetPosition); + } + if (rtConfig->resistance.getValue() > rtConfig->getMaxResistance()) { + // Nudge downward unless the user already asked to move lower + if (ss2k->targetPosition > ss2k->getCurrentPosition()) { + ss2k->targetPosition = ss2k->getCurrentPosition() - 20; } } - } else { // Normal move code for non-Peloton - if ((ss2k->targetPosition >= rtConfig->getMinStep()) && (ss2k->targetPosition <= rtConfig->getMaxStep())) { - stepper->moveTo(ss2k->targetPosition); - } else if (ss2k->targetPosition <= rtConfig->getMinStep()) { // Limit Stepper to Min Position - stepper->moveTo(rtConfig->getMinStep() + 1); - } else { // Limit Stepper to Max Position - stepper->moveTo(rtConfig->getMaxStep() - 1); + } else if (!rtConfig->getHomed()) { // Not homed: keep target inside the provisional range and learn bounds when power looks valid + // Flag when current position is within half a shift step of either bound + bool _closeToTarget = (abs(ss2k->getCurrentPosition() - rtConfig->getMinStep()) <= (userConfig->getShiftStep() / 2)) || + (abs(ss2k->getCurrentPosition() - rtConfig->getMaxStep()) <= (userConfig->getShiftStep() / 2)); + + if (ss2k->targetPosition < rtConfig->getMinStep()) { + // if (_closeToTarget && rtConfig->cad.getValue() > 0 && rtConfig->watts.getValue() > userConfig->getMinWatts() + POWERTABLE_WATT_INCREMENT) { + // rtConfig->setMinStep(ss2k->targetPosition); // Learn a tighter min bound from real effort + // } + ss2k->targetPosition = rtConfig->getMinStep() + 1; + } else if (ss2k->targetPosition > rtConfig->getMaxStep()) { + // if (_closeToTarget && rtConfig->cad.getValue() > 0 && rtConfig->watts.getValue() < userConfig->getMaxWatts() - POWERTABLE_WATT_INCREMENT) { + // rtConfig->setMaxStep(ss2k->targetPosition); // Learn a tighter max bound from real effort + // } + ss2k->targetPosition = rtConfig->getMaxStep() - 1; + } + } else { // Homed: simple clamp to the known good range + if (ss2k->targetPosition < rtConfig->getMinStep()) { + ss2k->targetPosition = rtConfig->getMinStep() + 1; + } else if (ss2k->targetPosition > rtConfig->getMaxStep()) { + ss2k->targetPosition = rtConfig->getMaxStep() - 1; } } + stepper->moveTo(ss2k->targetPosition); + if (rtConfig->cad.getValue() > 1) { stepper->enableOutputs(); stepper->setAutoEnable(false); diff --git a/src/PowerTable_Helpers.cpp b/src/PowerTable_Helpers.cpp index 5e41663a..3ba57c85 100644 --- a/src/PowerTable_Helpers.cpp +++ b/src/PowerTable_Helpers.cpp @@ -168,6 +168,7 @@ int16_t ResistanceModel::predict(double watts, double rpm) { // Normalize inputs using the bounds found during training double x = normW(watts); double y = normR(rpm); + double overPeakDelta = 0.0; // Preserve how far past the peak we are // If the model is quadratic and 'b[3]' (the x^2 term) is negative, // the curve is a downward-facing parabola (concave down). @@ -183,7 +184,9 @@ int16_t ResistanceModel::predict(double watts, double rpm) { // If the requested x is to the right of the peak, clamp it to the peak. if (x > x_vertex) { - x = x_vertex; + overPeakDelta = x - x_vertex; + overPeakDelta = (overPeakDelta * TABLE_DIVISOR) * (watts/rpm); + x = x_vertex; } } @@ -193,6 +196,9 @@ int16_t ResistanceModel::predict(double watts, double rpm) { res += b[3] * x * x + b[4] * y * y + b[5] * x * y; } + // Allow a gentle linear rise past the peak instead of flattening + res += overPeakDelta; + // Clamp to int16 range if (res > 32767.0) return 32767; if (res < -32768.0) return -32768; @@ -403,7 +409,7 @@ int32_t PTHelpers::lookup(int watts, int cad, PTData& ptData) { if (!resistanceModel.getIsValid()) { resistanceModel.fit(ptData); } - return resistanceModel.predict(watts, cad) * TABLE_DIVISOR; + return (resistanceModel.predict(watts, cad)) == INT16_MIN ? INT32_MIN : resistanceModel.predict(watts, cad) * TABLE_DIVISOR; } // returns the total number of readings in the power table
CAD/WATTS" << col * POWERTABLE_WATT_INCREMENT << "W