From 92a6266d71307eaa729d1893aa5e9bc1f76a8936 Mon Sep 17 00:00:00 2001 From: Ulrich Meine Date: Mon, 18 May 2026 21:43:12 +0200 Subject: [PATCH 1/4] Fix typo in config_obp60 --- lib/obp60task/config_obp60.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/obp60task/config_obp60.json b/lib/obp60task/config_obp60.json index 31c2e9b..a9e2595 100644 --- a/lib/obp60task/config_obp60.json +++ b/lib/obp60task/config_obp60.json @@ -276,7 +276,7 @@ "description": "Print chart lines with a smoothed gradient", "category": "OBP60 Settings", "capabilities": { - "obp40": "true" + "obp60": "true" } }, { From 1425297ef4bd1ce96bfcb7c1d31f76a2fb34ffe7 Mon Sep 17 00:00:00 2001 From: Ulrich Meine Date: Thu, 21 May 2026 23:00:24 +0200 Subject: [PATCH 2/4] Adjust chart axis labelling for better intervals --- lib/obp60task/OBPcharts.cpp | 80 +++++++++++++++++-------------------- lib/obp60task/OBPcharts.h | 2 +- 2 files changed, 38 insertions(+), 44 deletions(-) diff --git a/lib/obp60task/OBPcharts.cpp b/lib/obp60task/OBPcharts.cpp index 3e55dcf..afccb67 100644 --- a/lib/obp60task/OBPcharts.cpp +++ b/lib/obp60task/OBPcharts.cpp @@ -3,11 +3,13 @@ #include "OBPDataOperations.h" #include "OBPRingBuffer.h" +// Default ranges for various boat data types: 1st value default range, 2nd value step for range adjustment +// should be multiple of 4 for full integer chart labels w/o decimals std::map Chart::dfltChrtDta = { - { "formatWind", { 60.0 * DEG_TO_RAD, 10.0 * DEG_TO_RAD } }, // default course range 60 degrees + { "formatWind", { 60.0 * DEG_TO_RAD, 10.0 * DEG_TO_RAD } }, // default wind range 60 degrees { "formatCourse", { 60.0 * DEG_TO_RAD, 10.0 * DEG_TO_RAD } }, // default course range 60 degrees { "formatKnots", { 2.57, 2.57 } }, // default speed range in m/s - { "formatDepth", { 10.0, 5.0 } }, // default depth range in m + { "formatDepth", { 15.0, 5.0 } }, // default depth range in m { "kelvinToC", { 20.0, 5.0 } } // default temp range in °C/K }; @@ -80,8 +82,8 @@ Chart::Chart(RingBuffer& dataBuf, double dfltRng, CommonData& common, dfltRng = dfltChrtDta[dbFormat].range; rngStep = dfltChrtDta[dbFormat].step; } else { - dfltRng = 15.0; - rngStep = 5.0; + dfltRng = 16.0; + rngStep = 4.0; } // Initialize chart range values @@ -538,6 +540,7 @@ void Chart::drawChrtValAxis(const char chrtDir, const int8_t chrtSz, bool prntNa } // for any other data formats print multiple axis value lines on full charts + font = &Ubuntu_Bold10pt8b; prntHorizChartMultiValueAxisLabel(font); return; @@ -561,12 +564,9 @@ void Chart::drawChrtValAxis(const char chrtDir, const int8_t chrtSz, bool prntNa font = &Ubuntu_Bold12pt8b; getdisplay().setFont(font); // use larger font drawTextRalign(cRoot.x + (valAxis * 0.42), cRoot.y - 2, dbName.substring(0, 6)); // print buffer data name (max. size 5 characters) - - } else { - - font = &Ubuntu_Bold10pt8b; } + font = &Ubuntu_Bold10pt8b; prntVerticChartThreeValueAxisLabel(font); } } @@ -689,13 +689,13 @@ void Chart::prntHorizChartThreeValueAxisLabel(const GFXfont* font) double axLabel; double chrtMin, chrtMid, chrtMax; int xOffset, yOffset; // offset for text position of x axis label for different font sizes - String sVal; + char sVal[11]; if (font == &Ubuntu_Bold10pt8b) { - xOffset = 39; + xOffset = 32; yOffset = 16; } else if (font == &Ubuntu_Bold12pt8b) { - xOffset = 51; + xOffset = 42; yOffset = 18; } getdisplay().setFont(font); @@ -704,26 +704,23 @@ void Chart::prntHorizChartThreeValueAxisLabel(const GFXfont* font) chrtMin = convertValue(this->chrtMin, dbName, dbFormat, *commonData); chrtMid = convertValue(this->chrtMid, dbName, dbFormat, *commonData); chrtMax = convertValue(this->chrtMax, dbName, dbFormat, *commonData); - chrtMin = std::round(chrtMin * 100.0) / 100.0; - chrtMid = std::round(chrtMid * 100.0) / 100.0; - chrtMax = std::round(chrtMax * 100.0) / 100.0; // print top axis label axLabel = (chrtDataFmt == SPEED || chrtDataFmt == TEMPERATURE) ? chrtMax : chrtMin; - sVal = formatLabel(axLabel); + snprintf(sVal, sizeof(sVal), "%3.0f", axLabel); getdisplay().fillRect(cRoot.x, cRoot.y + 2, xOffset + 3, yOffset, bgColor); // Clear small area to remove potential chart lines drawTextRalign(cRoot.x + xOffset, cRoot.y + yOffset, sVal); // range value // print mid axis label axLabel = chrtMid; - sVal = formatLabel(axLabel); + formatLabel(axLabel).toCharArray(sVal, 11); // print mid label with 1 decimal for small numbers, if required getdisplay().fillRect(cRoot.x, cRoot.y + (valAxis / 2) - 8, xOffset + 3, 16, bgColor); // Clear small area to remove potential chart lines drawTextRalign(cRoot.x + xOffset, cRoot.y + (valAxis / 2) + 6, sVal); // range value getdisplay().drawLine(cRoot.x + xOffset + 3, cRoot.y + (valAxis / 2), cRoot.x + timAxis, cRoot.y + (valAxis / 2), fgColor); // print bottom axis label axLabel = (chrtDataFmt == SPEED || chrtDataFmt == TEMPERATURE) ? chrtMin : chrtMax; - sVal = formatLabel(axLabel); + snprintf(sVal, sizeof(sVal), "%3.0f", axLabel); getdisplay().fillRect(cRoot.x, cRoot.y + valAxis - 14, xOffset + 3, 15, bgColor); // Clear small area to remove potential chart lines drawTextRalign(cRoot.x + xOffset, cRoot.y + valAxis, sVal); // range value getdisplay().drawLine(cRoot.x + xOffset + 3, cRoot.y + valAxis, cRoot.x + timAxis, cRoot.y + valAxis, fgColor); @@ -733,45 +730,43 @@ void Chart::prntHorizChartThreeValueAxisLabel(const GFXfont* font) void Chart::prntHorizChartMultiValueAxisLabel(const GFXfont* font) { double chrtMin, chrtMax, chrtRng; - double axSlots, axIntv, axLabel; +// int axSlots = 5; // no. of axis labels int xOffset; // offset for text position of x axis label for different font sizes - String sVal; + char sVal[11]; if (font == &Ubuntu_Bold10pt8b) { - xOffset = 38; + xOffset = 32; } else if (font == &Ubuntu_Bold12pt8b) { - xOffset = 50; + xOffset = 42; } getdisplay().setFont(font); chrtMin = convertValue(this->chrtMin, dbName, dbFormat, *commonData); - // chrtMin = std::floor(chrtMin / rngStep) * rngStep; - chrtMin = std::round(chrtMin * 100.0) / 100.0; chrtMax = convertValue(this->chrtMax, dbName, dbFormat, *commonData); - // chrtMax = std::ceil(chrtMax / rngStep) * rngStep; - chrtMax = std::round(chrtMax * 100.0) / 100.0; - chrtRng = std::round((chrtMax - chrtMin) * 100) / 100; + chrtRng = chrtMax - chrtMin; - axSlots = valAxis / static_cast(VALAXIS_STEP); // number of axis labels (and we want to have a double calculation, no integer) - axIntv = chrtRng / axSlots; - axLabel = chrtMin + axIntv; - // LOG_DEBUG(GwLog::DEBUG, "Chart::printHorizMultiValueAxisLabel: chrtRng: %.2f, th-chrtRng: %.2f, axSlots: %.2f, axIntv: %.2f, axLabel: %.2f, chrtMin: %.2f, chrtMid: %.2f, chrtMax: %.2f", chrtRng, this->chrtRng, axSlots, axIntv, axLabel, this->chrtMin, chrtMid, chrtMax); + double axIntv = chrtRng / VALAXIS_SLOTS; // axis label interval + double axLabel = chrtMin + axIntv; // current axis label + double chrtScale = double(valAxis) / chrtRng; // Chart scale: pixels per value step + double valAxisStep = axIntv * chrtScale; // pixel per axis label interval + + // LOG_DEBUG(GwLog::DEBUG, "Chart::printHorizMultiValueAxisLabel: chrtRng: %.2f, th-chrtRng: %.2f, axSlots: %.2f, axIntv: %.2f, axLabel: %.2f, chrtMin: %.2f, chrtMid: %.2f, chrtMax: %.2f", chrtRng, this->chrtRng, VALAXIS_SLOTS, axIntv, axLabel, this->chrtMin, chrtMid, chrtMax); int loopStrt, loopEnd, loopStp; if (chrtDataFmt == SPEED || chrtDataFmt == TEMPERATURE || chrtDataFmt == OTHER) { - // High value at top - loopStrt = valAxis - VALAXIS_STEP; - loopEnd = VALAXIS_STEP / 2; - loopStp = VALAXIS_STEP * -1; + loopStrt = valAxis - valAxisStep; + loopEnd = valAxisStep / 2; + loopStp = valAxisStep * -1; } else { // Low value at top - loopStrt = VALAXIS_STEP; - loopEnd = valAxis - (VALAXIS_STEP / 2); - loopStp = VALAXIS_STEP; + loopStrt = valAxisStep; + loopEnd = valAxis - (valAxisStep / 2); + loopStp = valAxisStep; } for (int j = loopStrt; (loopStp > 0) ? (j < loopEnd) : (j > loopEnd); j += loopStp) { - sVal = formatLabel(axLabel); + // sVal = formatLabel(axLabel); + snprintf(sVal, sizeof(sVal), "%3.0f", axLabel); getdisplay().fillRect(cRoot.x, cRoot.y + j - 11, xOffset + 3, 21, bgColor); // Clear small area to remove potential chart lines drawTextRalign(cRoot.x + xOffset, cRoot.y + j + 7, sVal); // range value getdisplay().drawLine(cRoot.x + xOffset + 3, cRoot.y + j, cRoot.x + timAxis, cRoot.y + j, fgColor); @@ -821,16 +816,15 @@ String Chart::formatLabel(const double& label) // Format 3 numbers with prefix zero snprintf(sVal, sizeof(sVal), "%03.0f", label); - } else if (dbFormat == "formatRot") { +/* } else if (dbFormat == "formatRot") { if (label > -10 && label < 10) { snprintf(sVal, sizeof(sVal), "%3.2f", label); } else { snprintf(sVal, sizeof(sVal), "%3.0f", label); - } - } + } */ - else { - if (label < 10) { + } else { + if (label < 9.95) { snprintf(sVal, sizeof(sVal), "%3.1f", label); } else { snprintf(sVal, sizeof(sVal), "%3.0f", label); diff --git a/lib/obp60task/OBPcharts.h b/lib/obp60task/OBPcharts.h index 8978fd3..0b6ddd7 100644 --- a/lib/obp60task/OBPcharts.h +++ b/lib/obp60task/OBPcharts.h @@ -40,7 +40,7 @@ protected: static constexpr int8_t MIN_FREE_VALUES = 60; // free 60 values when chart line reaches chart end static constexpr int8_t THRESHOLD_NO_DATA = 3; // max. seconds of invalid values in a row - static constexpr int8_t VALAXIS_STEP = 60; // pixels between two chart value axis labels + static constexpr int8_t VALAXIS_SLOTS = 5; // no. of value axis labels static constexpr bool NO_SIMUDATA = true; // switch off simulation feature of function From a218da894846f5d92074941da43c783f8f92cd7f Mon Sep 17 00:00:00 2001 From: Ulrich Meine Date: Fri, 22 May 2026 23:10:51 +0200 Subject: [PATCH 3/4] fix calculate AWD conditionless --- lib/obp60task/OBPDataOperations.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/obp60task/OBPDataOperations.cpp b/lib/obp60task/OBPDataOperations.cpp index 171e507..1ed7662 100644 --- a/lib/obp60task/OBPDataOperations.cpp +++ b/lib/obp60task/OBPDataOperations.cpp @@ -467,10 +467,6 @@ bool WindUtils::handleWinds(bool calcWinds) double twd, tws, twa, awd; bool twCalculated = false; - if (!calcWinds) { // don't calculate anything if true wind calculation has not been set in configuration - return twCalculated; - } - double awaVal = awaBVal->valid ? awaBVal->value : DBL_MAX; double awsVal = awsBVal->valid ? awsBVal->value : DBL_MAX; double cogVal = cogBVal->valid ? cogBVal->value : DBL_MAX; @@ -504,6 +500,10 @@ bool WindUtils::handleWinds(bool calcWinds) } } + if (!calcWinds) { // don't calculate true winds if not set in configuration + return twCalculated; + } + // calculate TWD if not existing and if possible if (!twdBVal->valid) { // calculate TWD if it does not exist yet and TWA is available From 80800c32a3cc468903986e3b626094dea9adb022 Mon Sep 17 00:00:00 2001 From: Ulrich Meine Date: Fri, 22 May 2026 23:24:09 +0200 Subject: [PATCH 4/4] Adjust default ranges for charts once more --- lib/obp60task/OBPcharts.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/obp60task/OBPcharts.cpp b/lib/obp60task/OBPcharts.cpp index afccb67..fbd7fd0 100644 --- a/lib/obp60task/OBPcharts.cpp +++ b/lib/obp60task/OBPcharts.cpp @@ -8,8 +8,8 @@ std::map Chart::dfltChrtDta = { { "formatWind", { 60.0 * DEG_TO_RAD, 10.0 * DEG_TO_RAD } }, // default wind range 60 degrees { "formatCourse", { 60.0 * DEG_TO_RAD, 10.0 * DEG_TO_RAD } }, // default course range 60 degrees - { "formatKnots", { 2.57, 2.57 } }, // default speed range in m/s - { "formatDepth", { 15.0, 5.0 } }, // default depth range in m + { "formatKnots", { 2.572, 2.572 } }, // default speed range in m/s + { "formatDepth", { 10.0, 5.0 } }, // default depth range in m { "kelvinToC", { 20.0, 5.0 } } // default temp range in °C/K }; @@ -82,8 +82,8 @@ Chart::Chart(RingBuffer& dataBuf, double dfltRng, CommonData& common, dfltRng = dfltChrtDta[dbFormat].range; rngStep = dfltChrtDta[dbFormat].step; } else { - dfltRng = 16.0; - rngStep = 4.0; + dfltRng = 10.0; + rngStep = 5.0; } // Initialize chart range values