Initial commit - principle working

This commit is contained in:
Ulrich Meine 2025-05-10 01:59:19 +02:00
parent 309d55cdb4
commit a5494ccee4
9 changed files with 271 additions and 0 deletions

View File

@ -0,0 +1,123 @@
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
#include "BoatDataCalibration.h"
CalibrationDataList calibrationData;
void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger)
// Initial load of calibration data into internal list
// This function is called once at init phase of <OBP60task> to read the configuration values
{
// Load user configuration values
String lengthFormat = config->getString(config->lengthFormat); // [m|ft]
String distanceFormat = config->getString(config->distanceFormat); // [m|km|nm]
String speedFormat = config->getString(config->speedFormat); // [m/s|km/h|kn]
String windspeedFormat = config->getString(config->windspeedFormat); // [m/s|km/h|kn|bft]
String tempFormat = config->getString(config->tempFormat); // [K|°C|°F]
// Read calibration settings for DBT
calibrationData.list[0].instance = "DBT";
calibrationData.list[0].offset = (config->getString(config->calOffsetDBT)).toFloat();
if (lengthFormat == "ft") { // Convert DBT to SI standard meters
calibrationData.list[0].offset *= 0.3048;
}
calibrationData.list[0].slope = 1.0; // No slope for DBT
calibrationData.list[0].isCalibrated = false;
// Read calibration settings for other data instances
for (int i = 1; i < maxCalibrationData; i++) {
String instance = "calInstance" + String(i);
String offset = "calOffset" + String(i);
String slope = "calSlope" + String(i);
// calibrationData = new CalibrationDataList;
calibrationData.list[i].instance = config->getString(instance, "");
calibrationData.list[i].offset = (config->getString(offset, "")).toFloat();
calibrationData.list[i].slope = (config->getString(slope, "")).toFloat();
if (calibrationData.list[i].instance == "AWA" || calibrationData.list[i].instance == "AWS") {
if (windspeedFormat == "m/s") { // Convert calibration values to SI standard m/s
// No conversion needed
} else if (windspeedFormat == "km/h") {
calibrationData.list[i].offset /= 3.6; // Convert km/h to m/s
calibrationData.list[i].slope /= 3.6; // Convert km/h to m/s
} else if (windspeedFormat == "kn") {
calibrationData.list[i].offset /= 1.94384; // Convert kn to m/s
calibrationData.list[i].slope /= 1.94384; // Convert kn to m/s
} else if (windspeedFormat == "bft") {
calibrationData.list[i].offset *= 0.5; // Convert Bft to m/s (approx) -> to be improved
calibrationData.list[i].slope *= 0.5; // Convert km/h to m/s
}
} else if (calibrationData.list[i].instance == "STW") {
if (speedFormat == "m/s") {
// No conversion needed
} else if (speedFormat == "km/h") {
calibrationData.list[i].offset /= 3.6; // Convert km/h to m/s
calibrationData.list[i].slope /= 3.6; // Convert km/h to m/s
} else if (speedFormat == "kn") {
calibrationData.list[i].offset /= 1.94384; // Convert kn to m/s
calibrationData.list[i].slope /= 1.94384; // Convert kn to m/s
}
} else if (calibrationData.list[i].instance == "WTemp") {
if (tempFormat == "K" || tempFormat == "C") {
// No conversion needed
} else if (tempFormat == "F") {
calibrationData.list[i].offset *= 5.0 / 9.0; // Convert °F to K
calibrationData.list[i].slope *= 5.0 / 9.0; // Convert °F to K
}
}
calibrationData.list[i].isCalibrated = false;
LOG_DEBUG(GwLog::LOG, "stored calibration data: %s, offset: %f, slope: %f", calibrationData.list[i].instance.c_str(), calibrationData.list[i].offset, calibrationData.list[i].slope);
}
}
int CalibrationDataList::getInstanceListNo(String instance)
// Function to get the index of the requested instance in the list
{
// Check if instance is in the list
for (int i = 0; i < maxCalibrationData; i++) {
if (calibrationData.list[i].instance == instance) {
return i;
}
}
return -1; // instance not found
}
/* void CalibrationDataList::updateBoatDataValidity(String instance)
{
for (int i = 0; i < maxCalibrationData; i++) {
if (calibrationData.list[i].instance == instance) {
// test for boat data value validity - to be implemented
calibrationData.list[i].isValid = true;
return;
}
}
} */
void CalibrationDataList::calibrateInstance(String instance, GwApi::BoatValue* boatDataValue, GwLog* logger)
// Function to calibrate the boat data value
{
double offset = 0;
double slope = 1.0;
int listNo = getInstanceListNo(instance);
if (listNo >= 0) {
offset = calibrationData.list[listNo].offset;
slope = calibrationData.list[listNo].slope;
if (!boatDataValue->valid) { // no valid boat data value, so we don't want to apply calibration data
return;
} else {
boatDataValue->value = (boatDataValue->value * slope) + offset;
calibrationData.list[listNo].value = boatDataValue->value;
calibrationData.list[listNo].isCalibrated = true;
LOG_DEBUG(GwLog::LOG, "BoatDataCalibration: %s: Offset: %f Slope: %f Result: %f", instance.c_str(), offset, slope, boatDataValue->value);
}
} else {
LOG_DEBUG(GwLog::LOG, "BoatDataCalibration: %s not found in calibration data list", instance.c_str());
}
}
#endif

View File

@ -0,0 +1,33 @@
// Functions lib for data instance calibration
#ifndef _BOATDATACALIBRATION_H
#define _BOATDATACALIBRATION_H
#include "Pagedata.h"
#include "WString.h"
typedef struct {
String instance; // data type/instance to be calibrated
double offset; // calibration offset
double slope; // calibration slope
double value; // calibrated data value
bool isCalibrated; // is data instance value calibrated?
} CalibData;
const int maxCalibrationData = 3; // maximum number of calibration data instances
class CalibrationDataList {
public:
CalibData list[maxCalibrationData]; // list of calibration data instances
static void readConfig(GwConfigHandler* config, GwLog* logger);
static int getInstanceListNo(String instance);
static void calibrateInstance(String instance, GwApi::BoatValue* boatDataValue, GwLog* logger);
private:
// GwLog* logger;
};
extern CalibrationDataList calibrationData; // this list holds all calibration data
#endif

View File

@ -2,6 +2,7 @@
#include "Pagedata.h"
#include "OBP60Extensions.h"
#include "BoatDataCalibration.h"
class PageFourValues : public Page
{
@ -47,6 +48,7 @@ class PageFourValues : public Page
name1 = name1.substring(0, 6); // String length limit for value name
double value1 = bvalue1->value; // Value as double in SI unit
bool valid1 = bvalue1->valid; // Valid information
CalibrationDataList::calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated
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
@ -56,6 +58,7 @@ class PageFourValues : public Page
name2 = name2.substring(0, 6); // String length limit for value name
double value2 = bvalue2->value; // Value as double in SI unit
bool valid2 = bvalue2->valid; // Valid information
CalibrationDataList::calibrateInstance(name2, bvalue2, logger); // Check if boat data value is to be calibrated
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
@ -65,6 +68,7 @@ class PageFourValues : public Page
name3 = name3.substring(0, 6); // String length limit for value name
double value3 = bvalue3->value; // Value as double in SI unit
bool valid3 = bvalue3->valid; // Valid information
CalibrationDataList::calibrateInstance(name3, bvalue3, logger); // Check if boat data value is to be calibrated
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
@ -74,6 +78,7 @@ class PageFourValues : public Page
name4 = name4.substring(0, 6); // String length limit for value name
double value4 = bvalue4->value; // Value as double in SI unit
bool valid4 = bvalue4->valid; // Valid information
CalibrationDataList::calibrateInstance(name4, bvalue4, logger); // Check if boat data value is to be calibrated
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

View File

@ -2,6 +2,7 @@
#include "Pagedata.h"
#include "OBP60Extensions.h"
#include "BoatDataCalibration.h"
class PageFourValues2 : public Page
{
@ -47,6 +48,7 @@ class PageFourValues2 : public Page
name1 = name1.substring(0, 6); // String length limit for value name
double value1 = bvalue1->value; // Value as double in SI unit
bool valid1 = bvalue1->valid; // Valid information
CalibrationDataList::calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated
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
@ -56,6 +58,7 @@ class PageFourValues2 : public Page
name2 = name2.substring(0, 6); // String length limit for value name
double value2 = bvalue2->value; // Value as double in SI unit
bool valid2 = bvalue2->valid; // Valid information
CalibrationDataList::calibrateInstance(name2, bvalue2, logger); // Check if boat data value is to be calibrated
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
@ -65,6 +68,7 @@ class PageFourValues2 : public Page
name3 = name3.substring(0, 6); // String length limit for value name
double value3 = bvalue3->value; // Value as double in SI unit
bool valid3 = bvalue3->valid; // Valid information
CalibrationDataList::calibrateInstance(name3, bvalue3, logger); // Check if boat data value is to be calibrated
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
@ -74,6 +78,7 @@ class PageFourValues2 : public Page
name4 = name4.substring(0, 6); // String length limit for value name
double value4 = bvalue4->value; // Value as double in SI unit
bool valid4 = bvalue4->valid; // Valid information
CalibrationDataList::calibrateInstance(name4, bvalue4, logger); // Check if boat data value is to be calibrated
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

View File

@ -2,6 +2,7 @@
#include "Pagedata.h"
#include "OBP60Extensions.h"
#include "BoatDataCalibration.h"
class PageOneValue : public Page
{
@ -41,6 +42,7 @@ class PageOneValue : public Page
name1 = name1.substring(0, 6); // String length limit for value name
double value1 = bvalue1->value; // Value as double in SI unit
bool valid1 = bvalue1->valid; // Valid information
CalibrationDataList::calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated
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

View File

@ -2,6 +2,7 @@
#include "Pagedata.h"
#include "OBP60Extensions.h"
#include "BoatDataCalibration.h"
class PageThreeValues : public Page
{
@ -45,6 +46,7 @@ class PageThreeValues : public Page
name1 = name1.substring(0, 6); // String length limit for value name
double value1 = bvalue1->value; // Value as double in SI unit
bool valid1 = bvalue1->valid; // Valid information
CalibrationDataList::calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated
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
@ -54,6 +56,7 @@ class PageThreeValues : public Page
name2 = name2.substring(0, 6); // String length limit for value name
double value2 = bvalue2->value; // Value as double in SI unit
bool valid2 = bvalue2->valid; // Valid information
CalibrationDataList::calibrateInstance(name2, bvalue2, logger); // Check if boat data value is to be calibrated
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
@ -63,6 +66,7 @@ class PageThreeValues : public Page
name3 = name3.substring(0, 6); // String length limit for value name
double value3 = bvalue3->value; // Value as double in SI unit
bool valid3 = bvalue3->valid; // Valid information
CalibrationDataList::calibrateInstance(name3, bvalue3, logger); // Check if boat data value is to be calibrated
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

View File

@ -2,6 +2,7 @@
#include "Pagedata.h"
#include "OBP60Extensions.h"
#include "BoatDataCalibration.h"
class PageTwoValues : public Page
{
@ -43,6 +44,7 @@ class PageTwoValues : public Page
name1 = name1.substring(0, 6); // String length limit for value name
double value1 = bvalue1->value; // Value as double in SI unit
bool valid1 = bvalue1->valid; // Valid information
CalibrationDataList::calibrateInstance(name1, bvalue1, logger); // Check if boat data value is to be calibrated
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
@ -52,6 +54,7 @@ class PageTwoValues : public Page
name2 = name2.substring(0, 6); // String length limit for value name
double value2 = bvalue2->value; // Value as double in SI unit
bool valid2 = bvalue2->valid; // Valid information
CalibrationDataList::calibrateInstance(name2, bvalue2, logger); // Check if boat data value is to be calibrated
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

View File

@ -219,6 +219,17 @@
"obp60":"true"
}
},
{
"name": "calOffsetDBT",
"label": "Offset DBT",
"type": "number",
"default": "0.00",
"description": "Offset for depth transducer; positive for depth from surface, negative for depth below keel",
"category": "OBP60 Settings",
"capabilities": {
"obp60":"true"
}
},
{
"name": "lengthFormat",
"label": "Length Format",
@ -687,6 +698,86 @@
}
},
{
"name": "calInstance1",
"label": "Calibration Data Instance 1",
"type": "list",
"default": "",
"description": "Data instance for calibration",
"list": [
"AWA",
"AWS",
"HDM",
"STW",
"WTemp"
],
"category": "OBP60 Calibrations",
"capabilities": {
"obp60":"true"
}
},
{
"name": "calOffset1",
"label": "Calibration Data Instance 1 Offset",
"type": "number",
"default": "0.00",
"description": "Offset for data instance 1",
"category": "OBP60 Calibrations",
"capabilities": {
"obp60":"true"
}
},
{
"name": "calSlope1",
"label": "Calibration Data Instance 1 Slope",
"type": "number",
"default": "1.00",
"description": "Slope for data instance 1",
"category": "OBP60 Calibrations",
"capabilities": {
"obp60":"true"
}
},
{
"name": "calInstance2",
"label": "Calibration Data Instance 2",
"type": "list",
"default": "",
"description": "Data instance for calibration",
"list": [
"AWA",
"AWS",
"HDM",
"STW",
"WTemp"
],
"category": "OBP60 Calibrations",
"capabilities": {
"obp60":"true"
}
},
{
"name": "calOffset2",
"label": "Calibration Data Instance 2 Offset",
"type": "number",
"default": "0.00",
"description": "Offset for data instance 2",
"category": "OBP60 Calibrations",
"capabilities": {
"obp60":"true"
}
},
{
"name": "calSlope2",
"label": "Calibration Data Instance 2 Slope",
"type": "number",
"default": "1.00",
"description": "Slope for data instance 2",
"category": "OBP60 Calibrations",
"capabilities": {
"obp60":"true"
}
},
{
"name": "display",
"label": "Display Mode",
"type": "list",

View File

@ -12,6 +12,7 @@
#include <GxEPD2_BW.h> // GxEPD2 lib for b/w E-Ink displays
#include "OBP60Extensions.h" // Functions lib for extension board
#include "OBP60Keypad.h" // Functions for keypad
#include "BoatDataCalibration.h" // Functions lib for data instance calibration
#ifdef BOARD_OBP40S3
#include "driver/rtc_io.h" // Needs for weakup from deep sleep
@ -385,6 +386,10 @@ void OBP60Task(GwApi *api){
commonData.logger=logger;
commonData.config=config;
// Read all calibration data settings from config
CalibrationDataList::readConfig(config, logger);
LOG_DEBUG(GwLog::LOG,"Calibration data read from config");
#ifdef HARDWARE_V21
// Keyboard coordinates for page footer
initKeys(commonData);