More work on page anchor

This commit is contained in:
Thomas Hooge 2025-07-28 20:44:34 +02:00
parent b9086148e2
commit 4b4d8c2531
4 changed files with 207 additions and 30 deletions

View File

@ -6,16 +6,37 @@
/* /*
Anchor overview with additional associated data Anchor overview with additional associated data
This page is in experimental stage so be warned! This page is in experimental stage so be warned!
North is up.
Boatdata used
DBS - Water depth DBS - Water depth
HDT - Boat heading HDT - Boat heading
TWS - Wind strength AWS - Wind strength; Boat not moving so we assume AWS=TWS and AWD=TWD
TWD - Wind direction AWD - Wind direction
LAT/LON - Boat position, current
HDOP - Position error
This is the fist page to contain a configuration page with This is the fist page to contain a configuration page with
data entry option. data entry option.
Also it will make use of the new alarm function. Also it will make use of the new alarm function.
Data
Anchor position lat/lon
Depth at anchor position
Chain length used
Boat position current
Depth at boat position
Boat heading
Wind direction
Wind strength
Alarm j/n
Alarm radius
GPS position error
Timestamp while dropping anchor
Drop / raise function in device OBP40 has to be done inside
config mode because of limited number of buttons.
*/ */
#define anchor_width 16 #define anchor_width 16
@ -27,54 +48,180 @@ static unsigned char anchor_bits[] = {
class PageAnchor : public Page class PageAnchor : public Page
{ {
private:
GwConfigHandler *config;
GwLog *logger;
bool simulation = false; bool simulation = false;
bool holdvalues = false; bool holdvalues = false;
String flashLED; String flashLED;
String backlightMode; String backlightMode;
bool alarm = false;
bool alarm_enabled = false;
uint8_t alarm_range;
uint8_t chain_length;
uint8_t chain;
bool anchor_set = false;
double anchor_lat;
double anchor_lon;
double anchor_depth;
int anchor_ts; // time stamp anchor dropped
char mode = 'N'; // (N)ormal, (C)onfig
void displayModeNormal(PageData &pageData) {
// Boatvalues: DBS, HDT, AWS, AWD, LAT, LON, HDOP
GwApi::BoatValue *bv_dbs = pageData.values[0]; // DBS
String sval_dbs = formatValue(bv_dbs, *commonData).svalue;
GwApi::BoatValue *bv_hdt = pageData.values[1]; // HDT
String sval_hdt = formatValue(bv_hdt, *commonData).svalue;
GwApi::BoatValue *bv_aws = pageData.values[2]; // AWS
String sval_aws = formatValue(bv_aws, *commonData).svalue;
GwApi::BoatValue *bv_awd = pageData.values[3]; // AWD
String sval_awd = formatValue(bv_awd, *commonData).svalue;
GwApi::BoatValue *bv_lat = pageData.values[4]; // LAT
String sval_lat = formatValue(bv_lat, *commonData).svalue;
GwApi::BoatValue *bv_lon = pageData.values[5]; // LON
String sval_lon = formatValue(bv_lon, *commonData).svalue;
GwApi::BoatValue *bv_hdop = pageData.values[6]; // HDOP
String sval_hdop = formatValue(bv_hdop, *commonData).svalue;
Point c = {200, 150}; // center = anchor position
uint16_t r = 125;
Point b = {200, 180}; // boat position while dropping anchor
std::vector<Point> pts_boat = { // polygon lines
{b.x - 5, b.y},
{b.x - 5, b.y - 10},
{b.x, b.y - 16},
{b.x + 5, b.y - 10}
};
//rotatePoints und dann Linien zeichnen
// TODO rotate boat according to current heading
//fillPoly4(rotatePoints(c, pts, RadToDeg(value2)), commonData->fgcolor);
// Draw wind arrow
/*
if self._bd.awa.value:
p = ((cx, cy - r + 25), (cx - 12, cy - r - 4), (cx, cy - r + 6), (cx + 12, cy - r - 4), (cx, cy - r + 25))
wind = self.rotate((cx, cy), p, self._bd.awa.value)
ctx.move_to(*wind[0])
for point in wind[1:]:
ctx.line_to(*point)
ctx.fill()
*/
// Title and corner value headings
getdisplay().setTextColor(commonData->fgcolor);
getdisplay().setFont(&Ubuntu_Bold10pt8b);
getdisplay().setCursor(8, 48);
getdisplay().print("Anchor");
getdisplay().setCursor(8, 200);
getdisplay().print("Depth");
drawTextRalign(392, 50, "Chain");
drawTextRalign(392, 200, "Wind");
// Corner values
getdisplay().setFont(&Ubuntu_Bold8pt8b);
getdisplay().setCursor(2, 70);
getdisplay().print("Alarm: ");
getdisplay().print(alarm_enabled ? "On" : "Off");
// Units
// Values
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
// Depth
getdisplay().setCursor(8, 250);
//getdisplay().print(sval_dbs);
getdisplay().print("6.4");
// Wind
getdisplay().setCursor(320, 250);
//getdisplay().print(sval_aws);
getdisplay().print("12");
getdisplay().drawCircle(c.x, c.y, r, commonData->fgcolor);
// draw anchor symbol (as bitmap)
getdisplay().drawXBitmap(c.x - anchor_width / 2, c.y - anchor_height / 2,
anchor_bits, anchor_width, anchor_height, commonData->fgcolor);
}
void displayModeConfig() {
getdisplay().setTextColor(commonData->fgcolor);
getdisplay().setFont(&Ubuntu_Bold12pt8b);
getdisplay().setCursor(8, 48);
getdisplay().print("Anchor configuration");
}
public: public:
PageAnchor(CommonData &common){ PageAnchor(CommonData &common){
commonData = &common; commonData = &common;
common.logger->logDebug(GwLog::LOG,"Instantiate PageAnchor"); config = commonData->config;
logger = commonData->logger;
logger->logDebug(GwLog::LOG,"Instantiate PageAnchor");
// preload configuration data // preload configuration data
simulation = common.config->getBool(common.config->useSimuData); simulation = config->getBool(config->useSimuData);
holdvalues = common.config->getBool(common.config->holdvalues); holdvalues = config->getBool(config->holdvalues);
flashLED = common.config->getString(common.config->flashLED); flashLED = config->getString(config->flashLED);
backlightMode = common.config->getString(common.config->backlight); backlightMode = config->getString(config->backlight);
chainLength = config->getInt(config->chainLength);
chain = 0;
anchor_set = false;
} }
virtual int handleKey(int key){ void setupKeys(){
// Code for keylock Page::setupKeys();
if (key == 11) { commonData->keydata[0].label = "MODE";
commonData->keydata[1].label = "ALARM";
}
int handleKey(int key){
if (key == 1) { // Switch between normal and config mode
if (mode == 'N') {
mode = 'C';
} else {
mode = 'N';
}
return 0;
}
if (key == 2) { // Toggle alarm
alarm_enabled = !alarm_enabled;
return 0;
}
if (key == 11) { // Code for keylock
commonData->keylock = !commonData->keylock; commonData->keylock = !commonData->keylock;
return 0; // Commit the key return 0;
} }
return key; return key;
} }
void displayNew(PageData &pageData){ void displayNew(PageData &pageData){
} };
int displayPage(PageData &pageData){ int displayPage(PageData &pageData){
GwConfigHandler *config = commonData->config;
GwLog *logger = commonData->logger;
// Logging boat values // Logging boat values
LOG_DEBUG(GwLog::LOG,"Drawing at PageAnchor"); LOG_DEBUG(GwLog::LOG,"Drawing at PageAnchor");
LOG_DEBUG(GwLog::LOG,"Drawing at PageAnchor; Mode=%c", mode);
// Set display in partial refresh mode // Set display in partial refresh mode
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
uint16_t cx = 200; // center = anchor position if (mode == 'N') {
uint16_t cy = 150; displayModeNormal(pageData);
} else if (mode == 'C') {
// draw anchor symbol (as bitmap) displayModeConfig();
getdisplay().drawXBitmap(cx - anchor_width / 2, cy - anchor_height / 2, }
anchor_bits, anchor_width, anchor_height, commonData->fgcolor);
getdisplay().setTextColor(commonData->fgcolor);
return PAGE_UPDATE; return PAGE_UPDATE;
}; };
@ -82,7 +229,9 @@ class PageAnchor : public Page
static Page *createPage(CommonData &common){ static Page *createPage(CommonData &common){
return new PageAnchor(common); return new PageAnchor(common);
}/** }
/**
* with the code below we make this page known to the PageTask * with the code below we make this page known to the PageTask
* we give it a type (name) that can be selected in the config * we give it a type (name) that can be selected in the config
* we define which function is to be called * we define which function is to be called
@ -93,7 +242,7 @@ PageDescription registerPageAnchor(
"Anchor", // Page name "Anchor", // Page name
createPage, // Action createPage, // Action
0, // Number of bus values depends on selection in Web configuration 0, // Number of bus values depends on selection in Web configuration
{"DBS", "HDT", "TWS", "TWD"}, // Names of bus values undepends on selection in Web configuration (refer GwBoatData.h) {"DBS", "HDT", "AWS", "AWD", "LAT", "LON", "HDOP"}, // Names of bus values undepends on selection in Web configuration (refer GwBoatData.h)
true // Show display header on/off true // Show display header on/off
); );

View File

@ -75,6 +75,20 @@
"obp60":"true" "obp60":"true"
} }
}, },
{
"name": "chainLength",
"label": "Anchor Chain Length [m]",
"type": "number",
"default": 0,
"check": "checkMinMax",
"min": 0,
"max": 255,
"description": "The length of the anchor chain [0...255m]",
"category": "OBP60 Settings",
"capabilities": {
"obp60":"true"
}
},
{ {
"name": "fuelTank", "name": "fuelTank",
"label": "Fuel Tank [l]", "label": "Fuel Tank [l]",

View File

@ -75,6 +75,20 @@
"obp40": "true" "obp40": "true"
} }
}, },
{
"name": "chainLength",
"label": "Anchor Chain Length [m]",
"type": "number",
"default": "0",
"check": "checkMinMax",
"min": 0,
"max": 255,
"description": "The length of the anchor chain [0...255m]",
"category": "OBP40 Settings",
"capabilities": {
"obp40":"true"
}
},
{ {
"name": "fuelTank", "name": "fuelTank",
"label": "Fuel Tank [l]", "label": "Fuel Tank [l]",

View File

@ -17,7 +17,7 @@
#include "OBPDataOperations.h" // Functions lib for data operations such as true wind calculation #include "OBPDataOperations.h" // Functions lib for data operations such as true wind calculation
#ifdef BOARD_OBP40S3 #ifdef BOARD_OBP40S3
#include "driver/rtc_io.h" // Needs for weakup from deep sleep #include "driver/rtc_io.h" // Needs for wakeup from deep sleep
#include <FS.h> // SD-Card access #include <FS.h> // SD-Card access
#include <SD.h> #include <SD.h>
#include <SPI.h> #include <SPI.h>