diff --git a/lib/obp60task/PageCompass.cpp b/lib/obp60task/PageCompass.cpp new file mode 100644 index 0000000..003577c --- /dev/null +++ b/lib/obp60task/PageCompass.cpp @@ -0,0 +1,262 @@ +#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3 + +#include "Pagedata.h" +#include "OBP60Extensions.h" + +// these constants have to match the declaration below in : +// PageDescription registerPageCompass( +// {"COG","HDT", "HDM"}, // Bus values we need in the page +const int HowManyValues = 6; + +const int AverageValues = 4; + +const int ShowHDM = 0; +const int ShowHDT = 1; +const int ShowCOG = 2; +const int ShowSTW = 3; +const int ShowSOG = 4; +const int ShowDBS = 5; + +const int Compass_X0 = 200; // center point of compass band +const int Compass_Y0 = 220; // position of compass lines +const int Compass_LineLength = 22; // length of compass lines +const float Compass_LineDelta = 8.0; // compass band: 1deg = 5 Pixels, 10deg = 50 Pixels + +class PageCompass : public Page +{ + int WhichDataCompass = ShowHDM; + int WhichDataDisplay = ShowHDM; + + public: + PageCompass(CommonData &common){ + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageCompass"); + } + + virtual void setupKeys(){ + Page::setupKeys(); + commonData->keydata[0].label = "CMP"; + commonData->keydata[1].label = "SRC"; + } + + virtual int handleKey(int key){ + // Code for keylock + + if ( key == 1 ) { + WhichDataCompass += 1; + if ( WhichDataCompass > ShowCOG) + WhichDataCompass = ShowHDM; + return 0; + } + if ( key == 2 ) { + WhichDataDisplay += 1; + if ( WhichDataDisplay > ShowDBS) + WhichDataDisplay = ShowHDM; + } + + if(key == 11){ + commonData->keylock = !commonData->keylock; + return 0; // Commit the key + } + return key; + } + + virtual void displayPage(PageData &pageData){ + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; + + + // Old values for hold function + static String OldDataText[HowManyValues] = {"", "", "","", "", ""}; + static String OldDataUnits[HowManyValues] = {"", "", "","", "", ""}; + + // Get config data + String lengthformat = config->getString(config->lengthFormat); + // bool simulation = config->getBool(config->useSimuData); + bool holdvalues = config->getBool(config->holdvalues); + String flashLED = config->getString(config->flashLED); + String backlightMode = config->getString(config->backlight); + + GwApi::BoatValue *bvalue; + String DataName[HowManyValues]; + double DataValue[HowManyValues]; + bool DataValid[HowManyValues]; + String DataText[HowManyValues]; + String DataUnits[HowManyValues]; + String DataFormat[HowManyValues]; + FormatedData TheFormattedData; + + for (int i = 0; i < HowManyValues; i++){ + bvalue = pageData.values[i]; + TheFormattedData = formatValue(bvalue, *commonData); + DataName[i] = xdrDelete(bvalue->getName()); + DataName[i] = DataName[i].substring(0, 6); // String length limit for value name + DataUnits[i] = formatValue(bvalue, *commonData).unit; + DataText[i] = TheFormattedData.svalue; // Formatted value as string including unit conversion and switching decimal places + DataValue[i] = TheFormattedData.value; // Value as double in SI unit + DataValid[i] = bvalue->valid; + DataFormat[i] = bvalue->getFormat(); // Unit of value + LOG_DEBUG(GwLog::LOG,"Drawing at PageCompass: %d %s %f %s %s", i, DataName[i], DataValue[i], DataFormat[i], DataText[i] ); + } + + // Optical warning by limit violation (unused) + if(String(flashLED) == "Limit Violation"){ + setBlinkingLED(false); + setFlashLED(false); + } + + if (bvalue == NULL) return; + + //*********************************************************** + + // Set display in partial refresh mode + getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + getdisplay().setTextColor(commonData->fgcolor); + + // Horizontal line 3 pix top & bottom + // print Data on top half + getdisplay().fillRect(0, 23, 400, 3, commonData->fgcolor); + getdisplay().setFont(&Ubuntu_Bold20pt7b); + getdisplay().setCursor(10, 70); + getdisplay().print(DataName[WhichDataDisplay]); // Page name + // Show unit + getdisplay().setFont(&Ubuntu_Bold12pt7b); + getdisplay().setCursor(10, 120); + getdisplay().print(DataUnits[WhichDataDisplay]); + getdisplay().setCursor(200, 120); + getdisplay().setFont(&DSEG7Classic_BoldItalic42pt7b); + + if(holdvalues == false){ + getdisplay().print(DataText[WhichDataDisplay]); // Real value as formated string + } + else{ + getdisplay().print(OldDataText[WhichDataDisplay]); // Old value as formated string + } + if(DataValid[WhichDataDisplay] == true){ + OldDataText[WhichDataDisplay] = DataText[WhichDataDisplay]; // Save the old value + OldDataUnits[WhichDataDisplay] = DataUnits[WhichDataDisplay]; // Save the old unit + } + // now draw compass band + // get the data + double TheAngle = DataValue[WhichDataCompass]; + static double AvgAngle = 0; + AvgAngle = ( AvgAngle * AverageValues + TheAngle ) / (AverageValues + 1 ); + + int TheTrend = round( ( TheAngle - AvgAngle) * 180.0 / M_PI ); + + static const int bsize = 30; + char buffer[bsize+1]; + buffer[0]=0; + + getdisplay().setFont(&Ubuntu_Bold16pt7b); + getdisplay().setCursor(10, Compass_Y0-60); + getdisplay().print(DataName[WhichDataCompass]); // Page name + + + // draw compass base line and pointer + getdisplay().fillRect(0, Compass_Y0, 400, 3, commonData->fgcolor); + getdisplay().fillTriangle(Compass_X0,Compass_Y0-40,Compass_X0-10,Compass_Y0-80,Compass_X0+10,Compass_Y0-80,commonData->fgcolor); +// draw trendlines + for ( int i = 1; i < abs(TheTrend) / 2; i++){ + int x1; + if ( TheTrend < 0 ) + x1 = Compass_X0 + 20 * i; + else + x1 = Compass_X0 - 20 * ( i + 1 ); + + getdisplay().fillRect(x1, Compass_Y0 -60, 10, 6, commonData->fgcolor); + } +// central line + satellite lines + double NextSector = round(TheAngle / ( M_PI / 9 )) * ( M_PI / 9 ); // get the next 20degree value + double Offset = - ( NextSector - TheAngle); // offest of the center line compared to TheAngle in Radian + + int Delta_X = int ( Offset * 180.0 / M_PI * Compass_LineDelta ); + for ( int i = 0; i <=4; i++ ) + { + int x0; + x0 = Compass_X0 + Delta_X + 2 * i * 5 * Compass_LineDelta; + getdisplay().fillRect(x0-1, Compass_Y0 - 2 * Compass_LineLength,3, 2 * Compass_LineLength, commonData->fgcolor); + x0 = Compass_X0 + Delta_X + ( 2 * i + 1 ) * 5 * Compass_LineDelta; + getdisplay().fillRect(x0-1, Compass_Y0 - Compass_LineLength,3, Compass_LineLength, commonData->fgcolor); + + x0 = Compass_X0 + Delta_X - 2 * i * 5 * Compass_LineDelta; + getdisplay().fillRect(x0-1, Compass_Y0 - 2 * Compass_LineLength,3, 2 * Compass_LineLength, commonData->fgcolor); + x0 = Compass_X0 + Delta_X - ( 2 * i + 1 ) * 5 * Compass_LineDelta; + getdisplay().fillRect(x0-1, Compass_Y0 - Compass_LineLength,3, Compass_LineLength, commonData->fgcolor); + } + + getdisplay().fillRect(0, Compass_Y0, 400, 3, commonData->fgcolor); + // add the numbers to the compass band + int x0; + float AngleToDisplay = NextSector * 180.0 / M_PI; + + x0 = Compass_X0 + Delta_X; + getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b); + + do { + getdisplay().setCursor(x0 - 40, Compass_Y0 + 40); + snprintf(buffer,bsize,"%03.0f", AngleToDisplay); + getdisplay().print(buffer); + AngleToDisplay += 20; + if ( AngleToDisplay >= 360.0 ) + AngleToDisplay -= 360.0; + x0 -= 4 * 5 * Compass_LineDelta; + } while ( x0 >= 0 - 60 ); + + AngleToDisplay = NextSector * 180.0 / M_PI - 20; + if ( AngleToDisplay < 0 ) + AngleToDisplay += 360.0; + + x0 = Compass_X0 + Delta_X + 4 * 5 * Compass_LineDelta; + do { + getdisplay().setCursor(x0 - 40, Compass_Y0 + 40); + snprintf(buffer,bsize,"%03.0f", AngleToDisplay); + // quick and dirty way to prevent wrapping text in next line + if ( ( x0 - 40 ) > 380 ) + buffer[0] = 0; + else if ( ( x0 - 40 ) > 355 ) + buffer[1] = 0; + else if ( ( x0 - 40 ) > 325 ) + buffer[2] = 0; + + getdisplay().print(buffer); + + AngleToDisplay -= 20; + if ( AngleToDisplay < 0 ) + AngleToDisplay += 360.0; + x0 += 4 * 5 * Compass_LineDelta; + } while (x0 < ( 400 - 20 -40 ) ); + + // static int x_test = 320; + // x_test += 2; + + // snprintf(buffer,bsize,"%03d", x_test); + // getdisplay().setCursor(x_test, Compass_Y0 - 60); + // getdisplay().print(buffer); + // if ( x_test > 390) + // x_test = 320; + + // Update display + getdisplay().nextPage(); // Partial update (fast) + + }; + + }; +static Page *createPage(CommonData &common){ + return new PageCompass(common); +}/** + * 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 define which function is to be called + * and we provide the number of user parameters we expect + * this will be number of BoatValue pointers in pageData.values + */ +PageDescription registerPageCompass( + "Compass", // Page name + createPage, // Action + 0, // Number of bus values depends on selection in Web configuration + {"HDM","HDT", "COG", "STW", "SOG", "DBS"}, // Bus values we need in the page + true // Show display header on/off +); + +#endif diff --git a/lib/obp60task/config.json b/lib/obp60task/config.json index c1801af..6bd401a 100644 --- a/lib/obp60task/config.json +++ b/lib/obp60task/config.json @@ -686,189 +686,6 @@ "obp60":"true" } }, - { - "name": "calInstance1", - "label": "Calibration Data Instance 1", - "type": "list", - "default": "---", - "description": "Data instance for calibration", - "list": [ - "---", - "AWA", - "AWS", - "DBT", - "HDM", - "PRPOS", - "RPOS", - "STW", - "TWA", - "TWS", - "TWD", - "WTemp" - ], - "category": "OBP60 Calibrations", - "capabilities": { - "obp60":"true" - } - }, - { - "name": "calOffset1", - "label": "Data Instance 1 Calibration Offset", - "type": "number", - "default": "0.00", - "description": "Offset for data instance 1", - "category": "OBP60 Calibrations", - "capabilities": { - "obp60":"true" - } - }, - { - "name": "calSlope1", - "label": "Data Instance 1 Calibration Slope", - "type": "number", - "default": "1.00", - "description": "Slope for data instance 1", - "category": "OBP60 Calibrations", - "capabilities": { - "obp60":"true" - } - }, - { - "name": "calSmooth1", - "label": "Data Instance 1 Smoothing", - "type": "number", - "default": "0", - "check": "checkMinMax", - "min": 0, - "max": 10, - "description": "Smoothing factor 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", - "DBT", - "HDM", - "PRPOS", - "RPOS", - "STW", - "TWA", - "TWS", - "TWD", - "WTemp" - ], - "category": "OBP60 Calibrations", - "capabilities": { - "obp60":"true" - } - }, - { - "name": "calOffset2", - "label": "Data Instance 2 Calibration Offset", - "type": "number", - "default": "0.00", - "description": "Offset for data instance 2", - "category": "OBP60 Calibrations", - "capabilities": { - "obp60":"true" - } - }, - { - "name": "calSlope2", - "label": "Data Instance 2 Calibration Slope", - "type": "number", - "default": "1.00", - "description": "Slope for data instance 2", - "category": "OBP60 Calibrations", - "capabilities": { - "obp60":"true" - } - }, - { - "name": "calSmooth2", - "label": "Data Instance 2 Smoothing", - "type": "number", - "default": "0", - "check": "checkMinMax", - "min": 0, - "max": 10, - "description": "Smoothing factor for data instance 2", - "category": "OBP60 Calibrations", - "capabilities": { - "obp60":"true" - } - }, - { - "name": "calInstance3", - "label": "Calibration Data Instance 3", - "type": "list", - "default": "---", - "description": "Data instance for calibration", - "list": [ - "---", - "AWA", - "AWS", - "DBT", - "HDM", - "PRPOS", - "RPOS", - "STW", - "TWA", - "TWS", - "TWD", - "WTemp" - ], - "category": "OBP60 Calibrations", - "capabilities": { - "obp60":"true" - } - }, - { - "name": "calOffset3", - "label": "Data Instance 3 Calibration Offset", - "type": "number", - "default": "0.00", - "description": "Offset for data instance 3", - "category": "OBP60 Calibrations", - "capabilities": { - "obp60":"true" - } - }, - { - "name": "calSlope3", - "label": "Data Instance 3 Calibration Slope", - "type": "number", - "default": "1.00", - "description": "Slope for data instance 3", - "category": "OBP60 Calibrations", - "capabilities": { - "obp60":"true" - } - }, - { - "name": "calSmooth3", - "label": "Data Instance 3 Smoothing", - "type": "number", - "default": "0", - "check": "checkMinMax", - "min": 0, - "max": 10, - "description": "Smoothing factor for data instance 3", - "category": "OBP60 Calibrations", - "capabilities": { - "obp60":"true" - } - }, { "name": "display", "label": "Display Mode", @@ -1152,6 +969,7 @@ } }, + { "name": "page1type", "label": "Type", @@ -1163,6 +981,7 @@ "Battery", "Battery2", "Clock", + "Compass", "DST810", "Fluid", "FourValues", @@ -1442,6 +1261,7 @@ "Battery", "Battery2", "Clock", + "Compass", "DST810", "Fluid", "FourValues", @@ -1718,6 +1538,7 @@ "Battery", "Battery2", "Clock", + "Compass", "DST810", "Fluid", "FourValues", @@ -1991,6 +1812,7 @@ "Battery", "Battery2", "Clock", + "Compass", "DST810", "Fluid", "FourValues", @@ -2261,6 +2083,7 @@ "Battery", "Battery2", "Clock", + "Compass", "DST810", "Fluid", "FourValues", @@ -2528,6 +2351,7 @@ "Battery", "Battery2", "Clock", + "Compass", "DST810", "Fluid", "FourValues", @@ -2792,6 +2616,7 @@ "Battery", "Battery2", "Clock", + "Compass", "DST810", "Fluid", "FourValues", @@ -3053,6 +2878,7 @@ "Battery", "Battery2", "Clock", + "Compass", "DST810", "Fluid", "FourValues", @@ -3311,6 +3137,7 @@ "Battery", "Battery2", "Clock", + "Compass", "DST810", "Fluid", "FourValues", @@ -3566,6 +3393,7 @@ "Battery", "Battery2", "Clock", + "Compass", "DST810", "Fluid", "FourValues", diff --git a/lib/obp60task/gen_set.py b/lib/obp60task/gen_set.py index 69809fa..71485fa 100755 --- a/lib/obp60task/gen_set.py +++ b/lib/obp60task/gen_set.py @@ -15,6 +15,7 @@ no_of_fields_per_page = { "Battery": 0, "BME280": 0, "Clock": 0, + "Compass" : 0, "DST810": 0, "Fluid": 1, "FourValues2": 4, @@ -24,6 +25,7 @@ no_of_fields_per_page = { "OneValue": 1, "RollPitch": 2, "RudderPosition": 0, + "SixValues" : 6, "Solar": 0, "ThreeValues": 3, "TwoValues": 2, @@ -31,7 +33,6 @@ no_of_fields_per_page = { "WhitePage": 0, "WindRose": 0, "WindRoseFlex": 6, - "SixValues" : 6, } # No changes needed beyond this point