Merge remote-tracking branch 'upstream/master' into PageWindPlot

This commit is contained in:
Ulrich Meine 2025-08-23 11:58:14 +02:00
commit c6c2ad537a
6 changed files with 202 additions and 186 deletions

View File

@ -439,21 +439,34 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
//######################################################## //########################################################
else if (value->getFormat() == "formatXte"){ else if (value->getFormat() == "formatXte"){
double xte = 0; double xte = 0;
if (!usesimudata) { if(usesimudata == false) {
xte = abs(value->value); xte = value->value;
rawvalue = value->value; rawvalue = value->value;
} else { }
else{
rawvalue = 6.0 + float(random(0, 4)); rawvalue = 6.0 + float(random(0, 4));
xte = rawvalue; xte = rawvalue;
} }
if (xte >= 100) { if(String(distanceFormat) == "km"){
snprintf(buffer, bsize, fmt_dec_100, value->value); xte = xte * 0.001;
} else if (xte >= 10) { result.unit = "km";
snprintf(buffer, bsize, fmt_dec_10, value->value); }
} else { else if(String(distanceFormat) == "nm"){
snprintf(buffer, bsize, fmt_dec_1, value->value); xte = xte * 0.000539957;
result.unit = "nm";
}
else{;
result.unit = "m";
}
if(xte < 10){
snprintf(buffer,bsize,"%3.2f",xte);
}
if(xte >= 10 && xte < 100){
snprintf(buffer,bsize,"%3.1f",xte);
}
if(xte >= 100){
snprintf(buffer,bsize,"%3.0f",xte);
} }
result.unit = "nm";
} }
//######################################################## //########################################################
else if (value->getFormat() == "kelvinToC"){ else if (value->getFormat() == "kelvinToC"){

View File

@ -7,15 +7,33 @@
class PageWindRoseFlex : public Page class PageWindRoseFlex : public Page
{ {
int16_t lp = 80; // Pointer length int16_t lp = 80; // Pointer length
char source = 'A'; // data source (A)pparent | (T)rue
String ssource="App."; // String for Data Source
public: public:
PageWindRoseFlex(CommonData &common){ PageWindRoseFlex(CommonData &common){
commonData = &common; commonData = &common;
common.logger->logDebug(GwLog::LOG,"Instantiate PageWindRoseFlex"); common.logger->logDebug(GwLog::LOG,"Instantiate PageWindRoseFlex");
} }
virtual void setupKeys(){
Page::setupKeys();
commonData->keydata[1].label = "SRC";
}
// Key functions // Key functions
virtual int handleKey(int key){ virtual int handleKey(int key){
if(key == 2){
// Code for set source
if(source == 'A'){
source = 'T';
ssource = "True"; // String to display
} else {
source = 'A';
ssource = "App."; // String to display
}
}
return key; // Commit the key
// Code for keylock // Code for keylock
if(key == 11){ if(key == 11){
commonData->keylock = !commonData->keylock; commonData->keylock = !commonData->keylock;
@ -48,42 +66,57 @@ public:
String flashLED = config->getString(config->flashLED); String flashLED = config->getString(config->flashLED);
String backlightMode = config->getString(config->backlight); String backlightMode = config->getString(config->backlight);
// Get boat values #1 GwApi::BoatValue *bvalue1; // Value 1 for angle
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue) GwApi::BoatValue *bvalue2; // Value 2 for speed
String name1 = xdrDelete(bvalue1->getName()); // Value name
// Get boat value for wind angle (AWA/TWA), shown by pointer
if (source == 'A') {
bvalue1 = pageData.values[4];
} else {
bvalue1 = pageData.values[6];
}
String name1 = bvalue1->getName().c_str(); // Value name
name1 = name1.substring(0, 6); // String length limit for value name name1 = name1.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
double value1 = bvalue1->value; // Value as double in SI unit double value1 = bvalue1->value; // Value as double in SI unit
bool valid1 = bvalue1->valid; // Valid information bool valid1 = bvalue1->valid; // Valid information
value1 = formatValue(bvalue1, *commonData).value;// Format only nesaccery for simulation data for pointer
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
if(valid1 == true){ if(valid1 == true){
svalue1old = svalue1; // Save old value svalue1old = svalue1; // Save old value
unit1old = unit1; // Save old unit unit1old = unit1; // Save old unit
} }
// Get boat values #2 // Get boat value for wind speed (AWS/TWS), shown in top left corner
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list if (source == 'A') {
String name2 = xdrDelete(bvalue2->getName()); // Value name bvalue2 =pageData.values[5];
} else {
bvalue2 = pageData.values[7];
}
String name2 = bvalue2->getName().c_str(); // Value name
name2 = name2.substring(0, 6); // String length limit for value name name2 = name2.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated
double value2 = bvalue2->value; // Value as double in SI unit double value2 = bvalue2->value; // Value as double in SI unit
bool valid2 = bvalue2->valid; // Valid information bool valid2 = bvalue2->valid; // Valid information
if (simulation) {
value2 = 0.62731; // some random value
}
String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
if(valid2 == true){ if(valid2 == true){
svalue2old = svalue2; // Save old value svalue2old = svalue2; // Save old value
unit2old = unit2; // Save old unit unit2old = unit2; // Save old unit
} }
// Get boat values #3
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Third element in list
// Get boat value for bottom left corner
GwApi::BoatValue *bvalue3 = pageData.values[0];
String name3 = xdrDelete(bvalue3->getName()); // Value name String name3 = xdrDelete(bvalue3->getName()); // Value name
name3 = name3.substring(0, 6); // String length limit for value name name3 = name3.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated
double value3 = bvalue3->value; // Value as double in SI unit double value3 = bvalue3->value; // Value as double in SI unit
bool valid3 = bvalue3->valid; // Valid information bool valid3 = bvalue3->valid; // Valid information
String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value
if(valid3 == true){ if(valid3 == true){
@ -91,13 +124,13 @@ public:
unit3old = unit3; // Save old unit unit3old = unit3; // Save old unit
} }
// Get boat values #4 // Get boat value for top right corner
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Fourth element in list GwApi::BoatValue *bvalue4 = pageData.values[1];
String name4 = xdrDelete(bvalue4->getName()); // Value name String name4 = xdrDelete(bvalue4->getName()); // Value name
name4 = name4.substring(0, 6); // String length limit for value name name4 = name4.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue4, logger); // Check if boat data value is to be calibrated calibrationData.calibrateInstance(bvalue4, logger); // Check if boat data value is to be calibrated
double value4 = bvalue4->value; // Value as double in SI unit double value4 = bvalue4->value; // Value as double in SI unit
bool valid4 = bvalue4->valid; // Valid information bool valid4 = bvalue4->valid; // Valid information
String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
String unit4 = formatValue(bvalue4, *commonData).unit; // Unit of value String unit4 = formatValue(bvalue4, *commonData).unit; // Unit of value
if(valid4 == true){ if(valid4 == true){
@ -105,13 +138,13 @@ public:
unit4old = unit4; // Save old unit unit4old = unit4; // Save old unit
} }
// Get boat values #5 // Get boat value bottom right corner
GwApi::BoatValue *bvalue5 = pageData.values[4]; // Fifth element in list GwApi::BoatValue *bvalue5 = pageData.values[2];
String name5 = xdrDelete(bvalue5->getName()); // Value name String name5 = xdrDelete(bvalue5->getName()); // Value name
name5 = name5.substring(0, 6); // String length limit for value name name5 = name5.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue5, logger); // Check if boat data value is to be calibrated calibrationData.calibrateInstance(bvalue5, logger); // Check if boat data value is to be calibrated
double value5 = bvalue5->value; // Value as double in SI unit double value5 = bvalue5->value; // Value as double in SI unit
bool valid5 = bvalue5->valid; // Valid information bool valid5 = bvalue5->valid; // Valid information
String svalue5 = formatValue(bvalue5, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String svalue5 = formatValue(bvalue5, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
String unit5 = formatValue(bvalue5, *commonData).unit; // Unit of value String unit5 = formatValue(bvalue5, *commonData).unit; // Unit of value
if(valid5 == true){ if(valid5 == true){
@ -119,13 +152,13 @@ public:
unit5old = unit5; // Save old unit unit5old = unit5; // Save old unit
} }
// Get boat values #5 // Get boat value for center
GwApi::BoatValue *bvalue6 = pageData.values[5]; // Sixth element in list GwApi::BoatValue *bvalue6 = pageData.values[3];
String name6 = xdrDelete(bvalue6->getName()); // Value name String name6 = xdrDelete(bvalue6->getName()); // Value name
name6 = name6.substring(0, 6); // String length limit for value name name6 = name6.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue6, logger); // Check if boat data value is to be calibrated calibrationData.calibrateInstance(bvalue6, logger); // Check if boat data value is to be calibrated
double value6 = bvalue6->value; // Value as double in SI unit double value6 = bvalue6->value; // Value as double in SI unit
bool valid6 = bvalue6->valid; // Valid information bool valid6 = bvalue6->valid; // Valid information
String svalue6 = formatValue(bvalue6, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places String svalue6 = formatValue(bvalue6, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
String unit6 = formatValue(bvalue6, *commonData).unit; // Unit of value String unit6 = formatValue(bvalue6, *commonData).unit; // Unit of value
if(valid6 == true){ if(valid6 == true){
@ -133,6 +166,7 @@ public:
unit6old = unit6; // Save old unit unit6old = unit6; // Save old unit
} }
// Optical warning by limit violation (unused) // Optical warning by limit violation (unused)
if(String(flashLED) == "Limit Violation"){ if(String(flashLED) == "Limit Violation"){
setBlinkingLED(false); setBlinkingLED(false);
@ -151,7 +185,7 @@ public:
getdisplay().setTextColor(commonData->fgcolor); getdisplay().setTextColor(commonData->fgcolor);
// Show value 2 at position of value 1 (top left) // Show AWS or TWS top left
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
getdisplay().setCursor(10, 65); getdisplay().setCursor(10, 65);
getdisplay().print(svalue2); // Value getdisplay().print(svalue2); // Value
@ -171,7 +205,7 @@ public:
// Horizintal separator left // Horizintal separator left
getdisplay().fillRect(0, 149, 60, 3, commonData->fgcolor); getdisplay().fillRect(0, 149, 60, 3, commonData->fgcolor);
// Show value 3 at bottom left // Show value 3 (=first user-configured parameter) at bottom left
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
getdisplay().setCursor(10, 270); getdisplay().setCursor(10, 270);
getdisplay().print(svalue3); // Value getdisplay().print(svalue3); // Value
@ -188,11 +222,10 @@ public:
getdisplay().print(unit3old); // Unit getdisplay().print(unit3old); // Unit
} }
// Show value 4 at top right // Show value 4 (=second user-configured parameter) at top right
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
getdisplay().setCursor(295, 65); getdisplay().setCursor(295, 65);
if(valid3 == true){ if(valid3 == true){
// getdisplay().print(abs(value3 * 180 / M_PI), 0); // Value
getdisplay().print(svalue4); // Value getdisplay().print(svalue4); // Value
} }
else{ else{
@ -214,7 +247,7 @@ public:
// Horizintal separator right // Horizintal separator right
getdisplay().fillRect(340, 149, 80, 3, commonData->fgcolor); getdisplay().fillRect(340, 149, 80, 3, commonData->fgcolor);
// Show value 5 at bottom right // Show value 5 (=third user-configured parameter) at bottom right
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
getdisplay().setCursor(295, 270); getdisplay().setCursor(295, 270);
getdisplay().print(svalue5); // Value getdisplay().print(svalue5); // Value
@ -329,26 +362,49 @@ public:
//******************************************************************************************* //*******************************************************************************************
// Show value6, so that it does not collide with the wind pointer // Show value6 (=fourth user-configured parameter) and ssource, so that they do not collide with the wind pointer
getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b); if ( cos(value1) > 0){
if (cos(value1) > 0){ getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b);
getdisplay().setCursor(160, 200); getdisplay().setCursor(160, 200);
getdisplay().print(svalue6); // Value getdisplay().print(svalue6); // Value
getdisplay().setFont(&Ubuntu_Bold8pt8b); getdisplay().setFont(&Ubuntu_Bold8pt8b);
getdisplay().setCursor(190, 215); getdisplay().setCursor(190, 215);
} else{ getdisplay().print(" ");
getdisplay().setCursor(160, 130); if(holdvalues == false){
getdisplay().print(svalue6); // Value getdisplay().print(unit6); // Unit
getdisplay().setFont(&Ubuntu_Bold8pt8b); }
getdisplay().setCursor(190, 90); else{
} getdisplay().print(unit6old); // Unit
getdisplay().print(" "); }
if(holdvalues == false){ if (sin(value1)>0){
getdisplay().print(unit6); // Unit getdisplay().setCursor(160, 130);
} }
else{ else{
getdisplay().print(unit6old); // Unit getdisplay().setCursor(220, 130);
} }
getdisplay().print(ssource); // true or app.
}
else{
getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b);
getdisplay().setCursor(160, 130);
getdisplay().print(svalue6); // Value
getdisplay().setFont(&Ubuntu_Bold8pt8b);
getdisplay().setCursor(190, 90);
getdisplay().print(" ");
if(holdvalues == false){
getdisplay().print(unit6); // Unit
}
else{
getdisplay().print(unit6old); // Unit
}
if (sin(value1)>0){
getdisplay().setCursor(160, 130);
}
else{
getdisplay().setCursor(220, 130);
}
getdisplay().print(ssource); //true or app.
}
return PAGE_UPDATE; return PAGE_UPDATE;
}; };
@ -361,13 +417,14 @@ static Page *createPage(CommonData &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
* and we provide the number of user parameters we expect (0 here) * and we provide the number of user parameters we expect (4 here)
* and will will provide the names of the fixed values we need * and will will provide the names of the fixed values we need
*/ */
PageDescription registerPageWindRoseFlex( PageDescription registerPageWindRoseFlex(
"WindRoseFlex", // Page name "WindRoseFlex", // Page name
createPage, // Action createPage, // Action
6, // Number of bus values depends on selection in Web configuration; was zero 4, // Number of bus values depends on selection in Web configuration
{"AWA", "AWS", "TWA", "TWS"}, // fixed values we need in the page. They are inserted AFTER the web-configured values.
true // Show display header on/off true // Show display header on/off
); );

View File

@ -1521,9 +1521,6 @@
"condition": [ "condition": [
{ {
"page1type": "SixValues" "page1type": "SixValues"
},
{
"page1type": "WindRoseFlex"
} }
] ]
}, },
@ -1540,9 +1537,6 @@
"condition": [ "condition": [
{ {
"page1type": "SixValues" "page1type": "SixValues"
},
{
"page1type": "WindRoseFlex"
} }
] ]
}, },
@ -1799,9 +1793,6 @@
"condition": [ "condition": [
{ {
"page2type": "SixValues" "page2type": "SixValues"
},
{
"page2type": "WindRoseFlex"
} }
] ]
}, },
@ -1818,9 +1809,6 @@
"condition": [ "condition": [
{ {
"page2type": "SixValues" "page2type": "SixValues"
},
{
"page2type": "WindRoseFlex"
} }
] ]
}, },
@ -2074,9 +2062,6 @@
"condition": [ "condition": [
{ {
"page3type": "SixValues" "page3type": "SixValues"
},
{
"page3type": "WindRoseFlex"
} }
] ]
}, },
@ -2093,9 +2078,6 @@
"condition": [ "condition": [
{ {
"page3type": "SixValues" "page3type": "SixValues"
},
{
"page3type": "WindRoseFlex"
} }
] ]
}, },
@ -2346,9 +2328,6 @@
"condition": [ "condition": [
{ {
"page4type": "SixValues" "page4type": "SixValues"
},
{
"page4type": "WindRoseFlex"
} }
] ]
}, },
@ -2365,9 +2344,6 @@
"condition": [ "condition": [
{ {
"page4type": "SixValues" "page4type": "SixValues"
},
{
"page4type": "WindRoseFlex"
} }
] ]
}, },
@ -2615,9 +2591,6 @@
"condition": [ "condition": [
{ {
"page5type": "SixValues" "page5type": "SixValues"
},
{
"page5type": "WindRoseFlex"
} }
] ]
}, },
@ -2634,9 +2607,6 @@
"condition": [ "condition": [
{ {
"page5type": "SixValues" "page5type": "SixValues"
},
{
"page5type": "WindRoseFlex"
} }
] ]
}, },
@ -2881,9 +2851,6 @@
"condition": [ "condition": [
{ {
"page6type": "SixValues" "page6type": "SixValues"
},
{
"page6type": "WindRoseFlex"
} }
] ]
}, },
@ -2900,9 +2867,6 @@
"condition": [ "condition": [
{ {
"page6type": "SixValues" "page6type": "SixValues"
},
{
"page6type": "WindRoseFlex"
} }
] ]
}, },
@ -3144,9 +3108,6 @@
"condition": [ "condition": [
{ {
"page7type": "SixValues" "page7type": "SixValues"
},
{
"page7type": "WindRoseFlex"
} }
] ]
}, },
@ -3163,9 +3124,6 @@
"condition": [ "condition": [
{ {
"page7type": "SixValues" "page7type": "SixValues"
},
{
"page7type": "WindRoseFlex"
} }
] ]
}, },
@ -3404,9 +3362,6 @@
"condition": [ "condition": [
{ {
"page8type": "SixValues" "page8type": "SixValues"
},
{
"page8type": "WindRoseFlex"
} }
] ]
}, },
@ -3423,9 +3378,6 @@
"condition": [ "condition": [
{ {
"page8type": "SixValues" "page8type": "SixValues"
},
{
"page8type": "WindRoseFlex"
} }
] ]
}, },
@ -3661,9 +3613,6 @@
"condition": [ "condition": [
{ {
"page9type": "SixValues" "page9type": "SixValues"
},
{
"page9type": "WindRoseFlex"
} }
] ]
}, },
@ -3680,9 +3629,6 @@
"condition": [ "condition": [
{ {
"page9type": "SixValues" "page9type": "SixValues"
},
{
"page9type": "WindRoseFlex"
} }
] ]
}, },
@ -3915,9 +3861,6 @@
"condition": [ "condition": [
{ {
"page10type": "SixValues" "page10type": "SixValues"
},
{
"page10type": "WindRoseFlex"
} }
] ]
}, },
@ -3934,9 +3877,6 @@
"condition": [ "condition": [
{ {
"page10type": "SixValues" "page10type": "SixValues"
},
{
"page10type": "WindRoseFlex"
} }
] ]
}, },
@ -3987,4 +3927,3 @@
] ]
} }
] ]

View File

@ -1,10 +1,12 @@
// Add a new register card in web configuration interface
// This is a Java Script!
(function(){ (function(){
const api=window.esp32nmea2k; const api=window.esp32nmea2k;
if (! api) return; if (! api) return;
const tabName="OBP60"; const tabName="Screen";
api.registerListener((id, data) => { api.registerListener((id, data) => {
// if (!data.testboard) return; //do nothing if we are not active // if (!data.testboard) return; //do nothing if we are not active
let page = api.addTabPage(tabName, "OBP60"); let page = api.addTabPage(tabName, "Screen");
api.addEl('button', '', page, 'Screenshot').addEventListener('click', function (ev) { api.addEl('button', '', page, 'Screenshot').addEventListener('click', function (ev) {
window.open('/api/user/OBP60Task/screenshot', 'screenshot'); window.open('/api/user/OBP60Task/screenshot', 'screenshot');
}) })

View File

@ -20,9 +20,6 @@
#include <SPI.h> #include <SPI.h>
#endif #endif
// True type character sets includes
// See OBP60ExtensionPort.cpp
// Pictures // Pictures
//#include GxEPD_BitmapExamples // Example picture //#include GxEPD_BitmapExamples // Example picture
#include "MFD_OBP60_400x300_sw.h" // MFD with logo #include "MFD_OBP60_400x300_sw.h" // MFD with logo
@ -150,7 +147,7 @@ void keyboardTask(void *param){
vTaskDelete(NULL); vTaskDelete(NULL);
} }
// Scorgan: moved class declaration to header file <obp60task.h> to make class available for other functions // Scorgan: moved class declaration to header file <obp60task.h> to make class available to other functions
// --- Class BoatValueList -------------- // --- Class BoatValueList --------------
bool BoatValueList::addValueToList(GwApi::BoatValue *v){ bool BoatValueList::addValueToList(GwApi::BoatValue *v){
for (int i=0;i<numValues;i++){ for (int i=0;i<numValues;i++){
@ -181,7 +178,6 @@ GwApi::BoatValue *BoatValueList::findValueOrCreate(String name){
//this way each page can easily be added here //this way each page can easily be added here
//needs some minor tricks for the safe static initialization //needs some minor tricks for the safe static initialization
typedef std::vector<PageDescription*> Pages; typedef std::vector<PageDescription*> Pages;
//the page list class
class PageList{ class PageList{
public: public:
Pages pages; Pages pages;
@ -265,64 +261,64 @@ void registerAllPages(PageList &list){
} }
// Undervoltage detection for shutdown display // Undervoltage detection for shutdown display
void underVoltageDetection(GwApi *api, CommonData &common){ void underVoltageError(CommonData &common) {
// Read settings #if defined VOLTAGE_SENSOR && defined LIPO_ACCU_1200
double voffset = (api->getConfig()->getConfigItem(api->getConfig()->vOffset,true)->asString()).toFloat(); // Switch off all power lines
double vslope = (api->getConfig()->getConfigItem(api->getConfig()->vSlope,true)->asString()).toFloat(); setPortPin(OBP_BACKLIGHT_LED, false); // Backlight Off
setFlashLED(false); // Flash LED Off
buzzer(TONE4, 20); // Buzzer tone 4kHz 20ms
// Shutdown EInk display
getdisplay().setFullWindow(); // Set full Refresh
//getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
getdisplay().fillScreen(common.bgcolor);// Clear screen
getdisplay().setTextColor(common.fgcolor);
getdisplay().setFont(&Ubuntu_Bold20pt8b);
getdisplay().setCursor(65, 150);
getdisplay().print("Undervoltage");
getdisplay().setFont(&Ubuntu_Bold8pt8b);
getdisplay().setCursor(65, 175);
getdisplay().print("Charge battery and restart system");
getdisplay().nextPage(); // Partial update
getdisplay().powerOff(); // Display power off
setPortPin(OBP_POWER_EPD, false); // Power off ePaper display
setPortPin(OBP_POWER_SD, false); // Power off SD card
#else
// Switch off all power lines
setPortPin(OBP_BACKLIGHT_LED, false); // Backlight Off
setFlashLED(false); // Flash LED Off
buzzer(TONE4, 20); // Buzzer tone 4kHz 20ms
setPortPin(OBP_POWER_50, false); // Power rail 5.0V Off
// Shutdown EInk display
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
getdisplay().fillScreen(common.bgcolor);// Clear screen
getdisplay().setTextColor(common.fgcolor);
getdisplay().setFont(&Ubuntu_Bold20pt8b);
getdisplay().setCursor(65, 150);
getdisplay().print("Undervoltage");
getdisplay().setFont(&Ubuntu_Bold8pt8b);
getdisplay().setCursor(65, 175);
getdisplay().print("To wake up repower system");
getdisplay().nextPage(); // Partial update
getdisplay().powerOff(); // Display power off
#endif
// Stop system
while (true) {
esp_deep_sleep_start(); // Deep Sleep without wakeup. Wakeup only after power cycle (restart).
}
}
inline bool underVoltageDetection(float voffset, float vslope) {
// Read supply voltage // Read supply voltage
#if defined VOLTAGE_SENSOR && defined LIPO_ACCU_1200 #if defined VOLTAGE_SENSOR && defined LIPO_ACCU_1200
float actVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.53) * 2; // Vin = 1/2 for OBP40 float actVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.53) * 2; // Vin = 1/2 for OBP40
float minVoltage = 3.65; // Absolut minimum volatge for 3,7V LiPo accu float minVoltage = 3.65; // Absolut minimum volatge for 3,7V LiPo accu
#else #else
float actVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.17) * 20; // Vin = 1/20 for OBP60 float actVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.17) * 20; // Vin = 1/20 for OBP60
float minVoltage = MIN_VOLTAGE; float minVoltage = MIN_VOLTAGE;
#endif #endif
double calVoltage = actVoltage * vslope + voffset; // Calibration // TODO Why double here?
if(calVoltage < minVoltage){ float calVoltage = actVoltage * vslope + voffset; // Calibration
#if defined VOLTAGE_SENSOR && defined LIPO_ACCU_1200 return (calVoltage < minVoltage);
// Switch off all power lines
setPortPin(OBP_BACKLIGHT_LED, false); // Backlight Off
setFlashLED(false); // Flash LED Off
buzzer(TONE4, 20); // Buzzer tone 4kHz 20ms
// Shutdown EInk display
getdisplay().setFullWindow(); // Set full Refresh
//getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
getdisplay().fillScreen(common.bgcolor);// Clear screen
getdisplay().setTextColor(common.fgcolor);
getdisplay().setFont(&Ubuntu_Bold20pt8b);
getdisplay().setCursor(65, 150);
getdisplay().print("Undervoltage");
getdisplay().setFont(&Ubuntu_Bold8pt8b);
getdisplay().setCursor(65, 175);
getdisplay().print("Charge battery and restart system");
getdisplay().nextPage(); // Partial update
getdisplay().powerOff(); // Display power off
setPortPin(OBP_POWER_EPD, false); // Power off ePaper display
setPortPin(OBP_POWER_SD, false); // Power off SD card
#else
// Switch off all power lines
setPortPin(OBP_BACKLIGHT_LED, false); // Backlight Off
setFlashLED(false); // Flash LED Off
buzzer(TONE4, 20); // Buzzer tone 4kHz 20ms
setPortPin(OBP_POWER_50, false); // Power rail 5.0V Off
// Shutdown EInk display
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
getdisplay().fillScreen(common.bgcolor);// Clear screen
getdisplay().setTextColor(common.fgcolor);
getdisplay().setFont(&Ubuntu_Bold20pt8b);
getdisplay().setCursor(65, 150);
getdisplay().print("Undervoltage");
getdisplay().setFont(&Ubuntu_Bold8pt8b);
getdisplay().setCursor(65, 175);
getdisplay().print("To wake up repower system");
getdisplay().nextPage(); // Partial update
getdisplay().powerOff(); // Display power off
#endif
// Stop system
while(true){
esp_deep_sleep_start(); // Deep Sleep without weakup. Weakup only after power cycle (restart).
}
}
} }
// OBP60 Task // OBP60 Task
@ -527,7 +523,9 @@ void OBP60Task(GwApi *api){
commonData.backlight.brightness = 2.55 * uint(config->getConfigItem(config->blBrightness,true)->asInt()); commonData.backlight.brightness = 2.55 * uint(config->getConfigItem(config->blBrightness,true)->asInt());
commonData.powermode = api->getConfig()->getConfigItem(api->getConfig()->powerMode,true)->asString(); commonData.powermode = api->getConfig()->getConfigItem(api->getConfig()->powerMode,true)->asString();
bool uvoltage = api->getConfig()->getConfigItem(api->getConfig()->underVoltage,true)->asBoolean(); bool uvoltage = config->getConfigItem(config->underVoltage, true)->asBoolean();
float voffset = (config->getConfigItem(config->vOffset,true)->asString()).toFloat();
float vslope = (config->getConfigItem(config->vSlope,true)->asString()).toFloat();
String cpuspeed = api->getConfig()->getConfigItem(api->getConfig()->cpuSpeed,true)->asString(); String cpuspeed = api->getConfig()->getConfigItem(api->getConfig()->cpuSpeed,true)->asString();
uint hdopAccuracy = uint(api->getConfig()->getConfigItem(api->getConfig()->hdopAccuracy,true)->asInt()); uint hdopAccuracy = uint(api->getConfig()->getConfigItem(api->getConfig()->hdopAccuracy,true)->asInt());
@ -576,8 +574,10 @@ void OBP60Task(GwApi *api){
bool keypressed = false; bool keypressed = false;
// Undervoltage detection // Undervoltage detection
if(uvoltage == true){ if (uvoltage == true) {
underVoltageDetection(api, commonData); if (underVoltageDetection(voffset, vslope)) {
underVoltageError(commonData);
}
} }
// Set CPU speed after boot after 1min // Set CPU speed after boot after 1min

View File

@ -41,7 +41,12 @@
#ifdef BOARD_OBP40S3 #ifdef BOARD_OBP40S3
DECLARE_CAPABILITY(obp40,true) DECLARE_CAPABILITY(obp40,true)
#endif #endif
DECLARE_STRING_CAPABILITY(HELP_URL, "https://obp60-v2-docu.readthedocs.io/de/latest/"); // Link to help pages #ifdef BOARD_OBP60S3
DECLARE_STRING_CAPABILITY(HELP_URL, "https://obp60-v2-docu.readthedocs.io/en/latest/"); // Link to help pages
#endif
#ifdef BOARD_OBP40S3
DECLARE_STRING_CAPABILITY(HELP_URL, "https://obp40-v1-docu.readthedocs.io/en/latest/"); // Link to help pages
#endif
class BoatValueList{ class BoatValueList{
public: public: