diff --git a/lib/obp60task/OBPDataOperations.cpp b/lib/obp60task/OBPDataOperations.cpp index ad04e50..72c5a8d 100644 --- a/lib/obp60task/OBPDataOperations.cpp +++ b/lib/obp60task/OBPDataOperations.cpp @@ -86,7 +86,7 @@ bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal, double minSogVal = 0.1; // SOG below this value (m/s) is assumed to be data noise from GPS sensor static const double DBL_MIN = std::numeric_limits::lowest(); - Serial.println("\ncalcTrueWind: HDT: " + String(*hdtVal) + ", HDM: " + String(*hdmVal) + ", VAR: " + String(*varVal) + ", SOG: " + String(*sogVal) + ", COG: " + String(*cogVal)); + // Serial.println("\ncalcTrueWind: HDT: " + String(*hdtVal) + ", HDM: " + String(*hdmVal) + ", VAR: " + String(*varVal) + ", SOG: " + String(*sogVal) + ", COG: " + String(*cogVal)); if (*hdtVal != DBL_MIN) { hdt = *hdtVal; // Use HDT if available } else { @@ -100,7 +100,7 @@ bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal, } } - if (*cogVal != DBL_MIN && *sogVal >= minSogVal ) { // if SOG is data noise, we don't trust COG + if (*cogVal != DBL_MIN && *sogVal >= minSogVal) { // if SOG is data noise, we don't trust COG ctw = *cogVal; // Use COG for CTW if available } else { @@ -115,7 +115,7 @@ bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal, // If STW and SOG are not available, we cannot calculate true wind return false; } - Serial.println("\ncalcTrueWind: HDT: " + String(hdt) + ", CTW: " + String(ctw) + ", STW: " + String(stw)); + // Serial.println("\ncalcTrueWind: HDT: " + String(hdt) + ", CTW: " + String(ctw) + ", STW: " + String(stw)); if ((*awaVal == DBL_MIN) || (*awsVal == DBL_MIN)) { // Cannot calculate true wind without valid AWA, AWS; other checks are done earlier @@ -128,30 +128,4 @@ bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal, return true; } -} - -void HstryBuf::fillWndBufSimData(tBoatHstryData& hstryBufs) -// Fill most part of TWD and TWS history buffer with simulated data -{ - double value = 20.0; - int16_t value2 = 0; - for (int i = 0; i < 900; i++) { - value += random(-20, 20); - value = WindUtils::to360(value); - value2 = static_cast(value * DEG_TO_RAD * 1000); - hstryBufs.twdHstry->add(value2); - } -} - -/* void HstryBuf::simWndDir(double &wndDir) -{ - wndDir += random(-20, 20); - wndDir = WindUtils::to360(wndDir); - - int16_t z = static_cast(DegToRad(wndDir) * 1000.0); - pageData.boatHstry.twdHstry->add(z); // Fill the buffer with some test data - - simTws += random(-200, 150) / 10.0; // TWS value in knots - simTws = constrain(simTws, 0.0f, 50.0f); // Ensure TWS is between 0 and 50 knots - twsValue = simTws; -}*/ +} \ No newline at end of file diff --git a/lib/obp60task/OBPDataOperations.h b/lib/obp60task/OBPDataOperations.h index c9e4386..7994057 100644 --- a/lib/obp60task/OBPDataOperations.h +++ b/lib/obp60task/OBPDataOperations.h @@ -12,7 +12,7 @@ typedef struct { class HstryBuf { public: - void fillWndBufSimData(tBoatHstryData& hstryBufs); // Fill most part of the TWD and TWS history buffer with simulated data + }; class WindUtils { diff --git a/lib/obp60task/PageWindPlot.cpp b/lib/obp60task/PageWindPlot.cpp index f1f056a..acac0fc 100644 --- a/lib/obp60task/PageWindPlot.cpp +++ b/lib/obp60task/PageWindPlot.cpp @@ -6,15 +6,42 @@ #include "Pagedata.h" #include -static const double radToDeg = 180.0 / M_PI; // Conversion factor from radians to degrees +static const double radToDeg = 180.0 / PI; // Conversion factor from radians to degrees + +// Get maximum difference of last of TWD ringbuffer values to center chart +int getCntr(const RingBuffer& windDirHstry, size_t amount) +{ + int minVal = windDirHstry.getMinVal(); + size_t count = windDirHstry.getCurrentSize(); + + if (windDirHstry.isEmpty() || amount <= 0) { + return minVal; + } + if (amount > count) + amount = count; + + int16_t midWndDir, minWndDir, maxWndDir = 0; + int wndCenter = 0; + + midWndDir = windDirHstry.getMid(amount); + if (midWndDir != INT16_MIN) { + midWndDir = midWndDir / 1000.0 * radToDeg; + wndCenter = int((midWndDir + (midWndDir >= 0 ? 5 : -5)) / 10) * 10; // Set new center value; round to nearest 10 degree value + minWndDir = windDirHstry.getMin(amount) / 1000.0 * radToDeg; + maxWndDir = windDirHstry.getMax(amount) / 1000.0 * radToDeg; + if ((maxWndDir - minWndDir) > 180 && !(minWndDir > maxWndDir)) { // if wind range is > 180 and no 0° crossover, adjust wndCenter to smaller wind range end + wndCenter = WindUtils::to360(wndCenter + 180); + } + } + + return wndCenter; +} // Get maximum difference of last of TWD ringbuffer values to center chart int getRng(const RingBuffer& windDirHstry, int center, size_t amount) { int minVal = windDirHstry.getMinVal(); size_t count = windDirHstry.getCurrentSize(); - // size_t capacity = windDirHstry.getCapacity(); - // size_t last = windDirHstry.getLastIdx(); if (windDirHstry.isEmpty() || amount <= 0) { return minVal; @@ -118,7 +145,7 @@ public: GwConfigHandler* config = commonData->config; GwLog* logger = commonData->logger; -// float twsValue; // TWS value in chart area + float twsValue; // TWS value in chart area static String twdName, twdUnit; // TWD name and unit static int updFreq; // Update frequency for TWD static int16_t twdLowest, twdHighest; // TWD range @@ -137,8 +164,8 @@ public: static bool isInitialized = false; // Flag to indicate that page is initialized static bool wndDataValid = false; // Flag to indicate if wind data is valid static int numNoData; // Counter for multiple invalid data values in a row - static bool simulation = false; - static bool holdValues = false; + // static bool useSimuData = false; + // static bool holdValues = false; static int width; // Screen width static int height; // Screen height @@ -163,8 +190,8 @@ public: int diffRng; // Difference between mid and current wind value static const int dfltRng = 60; // Default range for chart int midWndDir; // New value for wndCenter after chart start / shift - static int simTwd; // Simulation value for TWD - static float simTws; // Simulation value for TWS + // static int simTwd; // Simulation value for TWD + // static float simTws; // Simulation value for TWS int x, y; // x and y coordinates for drawing static int prevX, prevY; // Last x and y coordinates for drawing @@ -175,8 +202,8 @@ public: LOG_DEBUG(GwLog::LOG, "Display page WindPlot"); // Get config data - simulation = config->getBool(config->useSimuData); - holdValues = config->getBool(config->holdvalues); + bool useSimuData = config->getBool(config->useSimuData); + // holdValues = config->getBool(config->holdvalues); String flashLED = config->getString(config->flashLED); String backlightMode = config->getString(config->backlight); @@ -187,9 +214,9 @@ public: cHeight = height - yOffset - 22; bufSize = pageData.boatHstry.twdHstry->getCapacity(); numNoData = 0; - simTwd = pageData.boatHstry.twdHstry->getLast() / 1000.0 * radToDeg; - simTws = 0; -// twsValue = 0; + // simTwd = pageData.boatHstry.twdHstry->getLast() / 1000.0 * radToDeg; + // simTws = 0; + twsValue = 0; bufStart = 0; oldDataIntv = 0; numAddedBufVals, currIdx, lastIdx = 0; @@ -246,15 +273,9 @@ public: // Set wndCenter from 1st real buffer value if (wndCenter == INT_MIN || (wndCenter == 0 && count == 1)) { - midWndDir = pageData.boatHstry.twdHstry->getMid(numWndVals); - if (midWndDir != INT16_MIN) { - midWndDir = midWndDir / 1000.0 * radToDeg; - wndCenter = int((midWndDir + (midWndDir >= 0 ? 5 : -5)) / 10) * 10; // Set new center value; round to nearest 10 degree value - } else { - wndCenter = 0; - } - LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Range Init: count: %d, TWD: %.0f, wndCenter: %d, diffRng: %d, chrtRng: %d", count, pageData.boatHstry.twdHstry->getLast() / 1000.0 * radToDeg, - wndCenter, diffRng, chrtRng); + wndCenter = getCntr(*pageData.boatHstry.twdHstry, numWndVals); + LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Range Init: count: %d, TWD: %.0f, wndCenter: %d, diffRng: %d, chrtRng: %d, Min: %.0f, Max: %.0f", count, pageData.boatHstry.twdHstry->getLast() / 1000.0 * radToDeg, + wndCenter, diffRng, chrtRng, pageData.boatHstry.twdHstry->getMin(numWndVals) / 1000.0 * radToDeg, pageData.boatHstry.twdHstry->getMax(numWndVals) / 1000.0 * radToDeg); } else { // check and adjust range between left, center, and right chart limit diffRng = getRng(*pageData.boatHstry.twdHstry, wndCenter, numWndVals); @@ -263,8 +284,8 @@ public: chrtRng = int((diffRng + (diffRng >= 0 ? 9 : -1)) / 10) * 10; // Round up to next 10 degree value } else if (diffRng + 10 < chrtRng) { // Reduce chart range for higher resolution if possible chrtRng = max(dfltRng, int((diffRng + (diffRng >= 0 ? 9 : -1)) / 10) * 10); + LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Range adjust: wndCenter: %d, diffRng: %d, chrtRng: %d, Min: %.0f, Max: %.0f", wndCenter, diffRng, chrtRng, pageData.boatHstry.twdHstry->getMin(numWndVals) / 1000.0 * radToDeg, pageData.boatHstry.twdHstry->getMax(numWndVals) / 1000.0 * radToDeg); } - LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Range adjust: wndCenter: %d, diffRng: %d, chrtRng: %d", wndCenter, diffRng, chrtRng); } chrtScl = float(width) / float(chrtRng) / 2.0; // Chart scale: pixels per degree wndLeft = wndCenter - chrtRng; @@ -308,8 +329,8 @@ public: if (pageData.boatHstry.twdHstry->getMax() == pageData.boatHstry.twdHstry->getMinVal()) { // only values in buffer -> no valid wind data available wndDataValid = false; - } else if (!BDataValid[0]) { - // currently no valid TWD data available + } else if (!BDataValid[0] && !useSimuData) { + // currently no valid TWD data available and no simulation mode numNoData++; wndDataValid = true; if (numNoData > 3) { @@ -332,7 +353,7 @@ public: x = ((chrtVal - wndLeft + 360) % 360) * chrtScl; y = yOffset + cHeight - i; // Position in chart area - if (i >= (numWndVals / dataIntv) - 1) // log chart data for 1 or more lines + if (i >= (numWndVals / dataIntv) - 1) // log chart data of 1 line (adjust for test purposes) LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Chart: i: %d, chrtVal: %d, bufStart: %d, count: %d, linesToShow: %d", i, chrtVal, bufStart, count, (numWndVals / dataIntv)); if ((i == 0) || (chrtPrevVal == INT16_MIN)) { @@ -368,21 +389,59 @@ public: int maxWndDir = pageData.boatHstry.twdHstry->getMax(numWndVals) / 1000.0 * radToDeg; LOG_DEBUG(GwLog::DEBUG, "PageWindPlot FreeTop: Minimum: %d, Maximum: %d, OldwndCenter: %d", minWndDir, maxWndDir, wndCenter); // if (((minWndDir - wndCenter >= 0) && (minWndDir - wndCenter < 180)) || ((maxWndDir - wndCenter <= 0) && (maxWndDir - wndCenter >=180))) { - if ((wndRight > wndCenter && (minWndDir >= wndCenter && minWndDir <= wndRight)) || - (wndRight <= wndCenter && (minWndDir >= wndCenter || minWndDir <= wndRight)) || - (wndLeft < wndCenter && (maxWndDir <= wndCenter && maxWndDir >= wndLeft)) || - (wndLeft >= wndCenter && (maxWndDir <= wndCenter || maxWndDir >= wndLeft))) { - // Check if all wind value are left or right of center value -> optimize chart range - midWndDir = pageData.boatHstry.twdHstry->getMid(numWndVals) / 1000.0 * radToDeg; - if (midWndDir != INT16_MIN) { - wndCenter = int((midWndDir + (midWndDir >= 0 ? 5 : -5)) / 10) * 10; // Set new center value; round to nearest 10 degree value - } + if ((wndRight > wndCenter && (minWndDir >= wndCenter && minWndDir <= wndRight)) || (wndRight <= wndCenter && (minWndDir >= wndCenter || minWndDir <= wndRight)) || (wndLeft < wndCenter && (maxWndDir <= wndCenter && maxWndDir >= wndLeft)) || (wndLeft >= wndCenter && (maxWndDir <= wndCenter || maxWndDir >= wndLeft))) { + // Check if all wind value are left or right of center value -> optimize chart center + wndCenter = getCntr(*pageData.boatHstry.twdHstry, numWndVals); } LOG_DEBUG(GwLog::DEBUG, "PageWindPlot FreeTop: cHeight: %d, bufStart: %d, numWndVals: %d, wndCenter: %d", cHeight, bufStart, numWndVals, wndCenter); break; } } + // Print TWS value + if (showTWS) { + int currentZone; + static int lastZone = 0; + static bool flipTws = false; + int xPosTws; + static const int yPosTws = yOffset + 40; + + xPosTws = flipTws ? 20 : width - 145; + currentZone = (y >= yPosTws - 38) && (y <= yPosTws + 6) && (x >= xPosTws - 4) && (x <= xPosTws + 146) ? 1 : 0; // Define current zone for TWS value + if (currentZone != lastZone) { + // Only flip when x moves to a different zone + if ((y >= yPosTws - 38) && (y <= yPosTws + 6) && (x >= xPosTws - 4) && (x <= xPosTws + 146)) { + flipTws = !flipTws; + xPosTws = flipTws ? 20 : width - 145; + } + } + lastZone = currentZone; + + twsValue = pageData.boatHstry.twsHstry->getLast(); + getdisplay().fillRect(xPosTws - 4, yPosTws - 38, 142, 44, commonData->bgcolor); // Clear area for TWS value + getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b); + getdisplay().setCursor(xPosTws, yPosTws); + if (twsValue == pageData.boatHstry.twsHstry->getMinVal()) { + getdisplay().print("--.-"); + } else { + twsValue = twsValue / 10.0 * 1.94384; // TWS value in knots + if (twsValue < 10.0) { + getdisplay().printf("!%3.1f", twsValue); // Value, round to 1 decimal + } else { + getdisplay().printf("%4.1f", twsValue); // Value, round to 1 decimal + } + } + getdisplay().setFont(&Ubuntu_Bold12pt8b); + getdisplay().setCursor(xPosTws + 82, yPosTws - 14); + // getdisplay().print("TWS"); // Name + getdisplay().print(BDataName[1]); // Name + getdisplay().setFont(&Ubuntu_Bold8pt8b); + // getdisplay().setCursor(xPosTws + 78, yPosTws + 1); + getdisplay().setCursor(xPosTws + 82, yPosTws + 1); + // getdisplay().printf(" kn"); // Unit + getdisplay().print(BDataUnit[1]); // Unit + } + } else { // No valid data available LOG_DEBUG(GwLog::LOG, "PageWindPlot: No valid data available"); @@ -391,51 +450,6 @@ public: drawTextCenter(xCenter, height / 2 - 10, "No data"); } - // Print TWS value - if (showTWS) { - int currentZone; - static int lastZone = 0; - static bool flipTws = false; - int xPosTws; - static const int yPosTws = yOffset + 40; - -// twsValue = pageData.boatHstry.twsHstry->getLast() / 10.0 * 1.94384; // TWS value in knots - - xPosTws = flipTws ? 20 : width - 138; - currentZone = (y >= yPosTws - 38) && (y <= yPosTws + 6) && (x >= xPosTws - 4) && (x <= xPosTws + 146) ? 1 : 0; // Define current zone for TWS value - if (currentZone != lastZone) { - // Only flip when x moves to a different zone - if ((y >= yPosTws - 38) && (y <= yPosTws + 6) && (x >= xPosTws - 4) && (x <= xPosTws + 146)) { - flipTws = !flipTws; - xPosTws = flipTws ? 20 : width - 145; - } - } - lastZone = currentZone; - - getdisplay().fillRect(xPosTws - 4, yPosTws - 38, 142, 44, commonData->bgcolor); // Clear area for TWS value - getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b); - getdisplay().setCursor(xPosTws, yPosTws); - if (!BDataValid[1]) { - getdisplay().print("--.-"); - } else { - double dbl = BDataValue[1] * 3.6 / 1.852; - if (dbl < 10.0) { - getdisplay().printf("!%3.1f", dbl); // Value, round to 1 decimal - } else { - getdisplay().printf("%4.1f", dbl); // Value, round to 1 decimal - } - } - getdisplay().setFont(&Ubuntu_Bold12pt8b); - getdisplay().setCursor(xPosTws + 82, yPosTws - 14); - // getdisplay().print("TWS"); // Name - getdisplay().print(BDataName[1]); // Name - getdisplay().setFont(&Ubuntu_Bold8pt8b); - // getdisplay().setCursor(xPosTws + 78, yPosTws + 1); - getdisplay().setCursor(xPosTws + 82, yPosTws + 1); - // getdisplay().printf(" kn"); // Unit - getdisplay().print(BDataUnit[1]); // Unit - } - // chart Y axis labels; print at last to overwrite potential chart lines in label area int yPos; int chrtLbl; diff --git a/lib/obp60task/obp60task.cpp b/lib/obp60task/obp60task.cpp index 3c65cf0..c27ec9a 100644 --- a/lib/obp60task/obp60task.cpp +++ b/lib/obp60task/obp60task.cpp @@ -376,7 +376,6 @@ void underVoltageDetection(GwApi *api, CommonData &common){ } } -//bool addTrueWind(GwApi* api, BoatValueList* boatValues, double *twd, double *tws, double *twa) { bool addTrueWind(GwApi* api, BoatValueList* boatValues) { // Calculate true wind data and add to obp60task boat data list @@ -423,7 +422,7 @@ bool addTrueWind(GwApi* api, BoatValueList* boatValues) { twaBVal->valid = true; } } - api->getLogger()->logDebug(GwLog::DEBUG,"obp60task addTrueWind: TWD_isValid %d, isCalculated %d, TWD %.1f, TWA %.1f, TWS %.1f", twdBVal->valid, isCalculated, twdBVal->value * RAD_TO_DEG, + api->getLogger()->logDebug(GwLog::DEBUG,"obp60task addTrueWind: isCalculated %d, TWD %.1f, TWA %.1f, TWS %.1f", isCalculated, twdBVal->value * RAD_TO_DEG, twaBVal->value * RAD_TO_DEG, twsBVal->value * 3.6 / 1.852); return isCalculated; @@ -447,7 +446,7 @@ void initHstryBuf(GwApi* api, BoatValueList* boatValues, tBoatHstryData hstryBuf GwApi::BoatValue *twaBVal = boatValues->findValueOrCreate("TWA"); } -void handleHstryBuf(GwApi* api, BoatValueList* boatValues, tBoatHstryData hstryBufList) { +void handleHstryBuf(GwApi* api, BoatValueList* boatValues, tBoatHstryData hstryBufList, bool useSimuData) { // Handle history buffers for TWD, TWS GwLog *logger = api->getLogger(); @@ -456,18 +455,18 @@ void handleHstryBuf(GwApi* api, BoatValueList* boatValues, tBoatHstryData hstryB int16_t twdHstryMax = hstryBufList.twdHstry->getMaxVal(); int16_t twsHstryMin = hstryBufList.twsHstry->getMinVal(); int16_t twsHstryMax = hstryBufList.twsHstry->getMaxVal(); - int16_t twdBuf, twsBuf; + static int16_t twdBuf, twsBuf = 20; //initial value only relevant if we use simulation data GwApi::BoatValue *calBVal; // temp variable just for data calibration -> we don't want to calibrate the original data here GwApi::BoatValue *twdBVal = boatValues->findValueOrCreate(hstryBufList.twdHstry->getName()); GwApi::BoatValue *twsBVal = boatValues->findValueOrCreate(hstryBufList.twsHstry->getName()); GwApi::BoatValue *twaBVal = boatValues->findValueOrCreate("TWA"); - api->getLogger()->logDebug(GwLog::DEBUG,"obp60task handleHstryBuf: TWD_isValid? %d, twdBVal: %.1f, twaBVal: %.1f, twsBVal: %.1f", twdBVal->valid, twdBVal->value * RAD_TO_DEG, twaBVal->value * RAD_TO_DEG, twsBVal->value * 3.6 / 1.852); - calBVal = new GwApi::BoatValue("TWD"); // temporary solution for calibration of history buffer values - calBVal->setFormat(twdBVal->getFormat()); + if (twdBVal->valid) { + calBVal = new GwApi::BoatValue("TWD"); // temporary solution for calibration of history buffer values + calBVal->setFormat(twdBVal->getFormat()); calBVal->value = twdBVal->value; calBVal->valid = twdBVal->valid; calibrationData.calibrateInstance(calBVal, logger); // Check if boat data value is to be calibrated @@ -475,13 +474,18 @@ void handleHstryBuf(GwApi* api, BoatValueList* boatValues, tBoatHstryData hstryB if (twdBuf >= twdHstryMin && twdBuf <= twdHstryMax) { hstryBufList.twdHstry->add(twdBuf); } + delete calBVal; + calBVal = nullptr; + } else if (useSimuData) { + twdBuf += random(-20, 20); + twdBuf = WindUtils::to360(twdBuf); + api->getLogger()->logDebug(GwLog::DEBUG,"obp60task Simu: twdBVal: %d", twdBuf); + hstryBufList.twdHstry->add(static_cast(DegToRad(twdBuf) * 1000.0)); } - delete calBVal; - calBVal = nullptr; - calBVal = new GwApi::BoatValue("TWS"); // temporary solution for calibration of history buffer values - calBVal->setFormat(twsBVal->getFormat()); if (twsBVal->valid) { + calBVal = new GwApi::BoatValue("TWS"); // temporary solution for calibration of history buffer values + calBVal->setFormat(twsBVal->getFormat()); calBVal->value = twsBVal->value; calBVal->valid = twsBVal->valid; calibrationData.calibrateInstance(calBVal, logger); // Check if boat data value is to be calibrated @@ -489,9 +493,14 @@ void handleHstryBuf(GwApi* api, BoatValueList* boatValues, tBoatHstryData hstryB if (twsBuf >= twsHstryMin && twsBuf <= twsHstryMax) { hstryBufList.twsHstry->add(twsBuf); } + delete calBVal; + calBVal = nullptr; + } else if (useSimuData) { + twsBuf += random(-50, 50); // TWS value in m/s; expands to 1 decimal + twsBuf = constrain(twsBuf, 0, 250); // Limit TWS to [0..25] m/s + api->getLogger()->logDebug(GwLog::DEBUG,"obp60task Simu: twsBVal: %d", twsBuf); + hstryBufList.twsHstry->add(twsBuf); } - delete calBVal; - calBVal = nullptr; } // OBP60 Task @@ -663,7 +672,7 @@ void OBP60Task(GwApi *api){ // Check user setting for true wind calculation bool calcTrueWnds = api->getConfig()->getBool(api->getConfig()->calcTrueWnds, false); - // bool simulation = api->getConfig()->getBool(api->getConfig()->useSimuData, false); + bool useSimuData = api->getConfig()->getBool(api->getConfig()->useSimuData, false); // Initialize history buffer for certain boat data initHstryBuf(api, &boatValues, hstryBufList); @@ -974,7 +983,7 @@ void OBP60Task(GwApi *api){ addTrueWind(api, &boatValues); } // Handle history buffers for TWD, TWS for wind plot page and other usage - handleHstryBuf(api, &boatValues, hstryBufList); + handleHstryBuf(api, &boatValues, hstryBufList, useSimuData); // Clear display // getdisplay().fillRect(0, 0, getdisplay().width(), getdisplay().height(), commonData.bgcolor);