From 99404991a3a60d9bbc3a2ff841a47a15ad8fbfac Mon Sep 17 00:00:00 2001 From: Norbert Walter Date: Sun, 8 Feb 2026 12:40:20 +0000 Subject: [PATCH] Add rudder bargraf --- lib/obp60task/OBP60Extensions.cpp | 63 ++++++++++++++++++++++++++++++- lib/obp60task/OBP60Extensions.h | 3 ++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/lib/obp60task/OBP60Extensions.cpp b/lib/obp60task/OBP60Extensions.cpp index 76c6334..57471d4 100644 --- a/lib/obp60task/OBP60Extensions.cpp +++ b/lib/obp60task/OBP60Extensions.cpp @@ -923,7 +923,7 @@ void solarGraphic(uint x, uint y, int pcolor, int bcolor){ } -// Generator graphic with fill level +// Generator graphic void generatorGraphic(uint x, uint y, int pcolor, int bcolor){ // Show battery int xb = x; // X position @@ -940,6 +940,67 @@ void generatorGraphic(uint x, uint y, int pcolor, int bcolor){ getdisplay().print("G"); } +// Display rudder position as horizontal bargraph +/-30 degrees +void displayRudderPosition(int rudderPosition, uint16_t cx, uint16_t cy, uint16_t fg, uint16_t bg){ + const int w = 300; + const int h = 20; + const int t = 3; // Line thickness + const int halfw = w/2; + const int halfh = h/2; + // Calculate top-left of bar (cx,cy are center of 0°) + int left = int(cx) - halfw; + int top = int(cy) - halfh; + + // Pixels per degree for +/-30° -> 60° span + const float pxPerDeg = float(w) / 60.0f; // =5.0 + + // Draw outer border (thickness t) + for (int i = 0; i < t; i++) { + getdisplay().drawRect(left + i, top + i, w - 2 * i, h - 2 * i, fg); + } + + // Fill inner area with background + getdisplay().fillRect(left + t, top + t, w - 2 * t, h - 2 * t, bg); + + // Clamp rudder position to -30..30 + if (rudderPosition > 30) rudderPosition = 30; + if (rudderPosition < -30) rudderPosition = -30; + + // Compute fill width in pixels + int fillPx = int(round(rudderPosition * pxPerDeg)); // positive -> right + + // Fill area from center to position (if non-zero) + int centerx = cx; + int innerTop = top + t; + int innerH = h - 2 * t; + if (fillPx > 0) { + // Right side + getdisplay().fillRect(centerx, innerTop, fillPx, innerH, fg); + } else if (fillPx < 0) { + // Left side + getdisplay().fillRect(centerx + fillPx, innerTop, -fillPx, innerH, fg); + } + + // Draw tick marks every 5° and labels outside the bar + getdisplay().setTextColor(fg); + getdisplay().setFont(&Ubuntu_Bold8pt8b); + for (int angle = -30; angle <= 30; angle += 5) { + int xpos = int(round(centerx + angle * pxPerDeg)); + // Vertical tick inside bar + getdisplay().drawLine(xpos, top, xpos, top + h, fg); + // Label outside: below the bar + String lbl = String(angle); + lbl += "\u00B0"; // Degree symbol + int16_t bx, by; + uint16_t bw, bh; + getdisplay().getTextBounds(lbl, 0, 0, &bx, &by, &bw, &bh); + int16_t tx = xpos - bw/2; + int16_t ty = top + h + bh + 2; // A little spacing + getdisplay().setCursor(tx, ty); + getdisplay().print(lbl); + } +} + // Function to handle HTTP image request // http://192.168.15.1/api/user/OBP60Task/screenshot void doImageRequest(GwApi *api, int *pageno, const PageStruct pages[MAX_PAGE_NUMBER], AsyncWebServerRequest *request) { diff --git a/lib/obp60task/OBP60Extensions.h b/lib/obp60task/OBP60Extensions.h index 604c356..de6db20 100644 --- a/lib/obp60task/OBP60Extensions.h +++ b/lib/obp60task/OBP60Extensions.h @@ -128,6 +128,9 @@ void solarGraphic(uint x, uint y, int pcolor, int bcolor); // S void generatorGraphic(uint x, uint y, int pcolor, int bcolor); // Generator graphic void startLedTask(GwApi *api); +// Display rudder position as horizontal bargraph +/-30 degrees +void displayRudderPosition(int rudderPosition, uint16_t x, uint16_t y, uint16_t fg, uint16_t bg); + void doImageRequest(GwApi *api, int *pageno, const PageStruct pages[MAX_PAGE_NUMBER], AsyncWebServerRequest *request); // Icons