mirror of
https://github.com/thooge/esp32-nmea2000-obp60.git
synced 2025-12-28 13:13:07 +01:00
Compare commits
11 Commits
system
...
8373d49c4f
| Author | SHA1 | Date | |
|---|---|---|---|
| 8373d49c4f | |||
| c6608bf669 | |||
| 5cac293431 | |||
| e7a55bd374 | |||
| 4b4d8c2531 | |||
| b9086148e2 | |||
| 2e797644db | |||
| fbe5e343b4 | |||
| 1637bdf9ee | |||
| c7a580612e | |||
| a311f2f164 |
@@ -192,13 +192,3 @@ Rect ConfigMenu::getItemRect(int8_t index) {
|
||||
return {static_cast<double>(x), static_cast<double>(y + index * h),
|
||||
static_cast<double>(w), static_cast<double>(h)};
|
||||
}
|
||||
|
||||
void ConfigMenu::setCallback(void (*callback)()) {
|
||||
fptrCallback = callback;
|
||||
}
|
||||
|
||||
void ConfigMenu::storeValues() {
|
||||
if (fptrCallback) {
|
||||
fptrCallback();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,6 @@ private:
|
||||
uint16_t y;
|
||||
uint16_t w;
|
||||
uint16_t h;
|
||||
void (*fptrCallback)();
|
||||
|
||||
public:
|
||||
ConfigMenu(String title, uint16_t menu_x, uint16_t menu_y);
|
||||
@@ -61,6 +60,4 @@ public:
|
||||
Point getXY();
|
||||
Rect getRect();
|
||||
Rect getItemRect(int8_t index);
|
||||
void setCallback(void (*callback)());
|
||||
void storeValues();
|
||||
};
|
||||
|
||||
@@ -14,30 +14,6 @@ https://controllerstech.com/ws2812-leds-using-spi/
|
||||
|
||||
*/
|
||||
|
||||
String Color::toHex() {
|
||||
char hexColor[8];
|
||||
sprintf(hexColor, "#%02X%02X%02X", r, g, b);
|
||||
return String(hexColor);
|
||||
}
|
||||
|
||||
String Color::toName() {
|
||||
static std::map<int, String> const names = {
|
||||
{0xff0000, "Red"},
|
||||
{0x00ff00, "Green"},
|
||||
{0x0000ff, "Blue",},
|
||||
{0xff9900, "Orange"},
|
||||
{0xffff00, "Yellow"},
|
||||
{0x3366ff, "Aqua"},
|
||||
{0xff0066, "Violet"},
|
||||
{0xffffff, "White"}
|
||||
};
|
||||
int color = (r << 16) + (g << 8) + b;
|
||||
auto it = names.find(color);
|
||||
if (it == names.end()) {
|
||||
return toHex();
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
static uint8_t mulcolor(uint8_t f1, uint8_t f2){
|
||||
uint16_t rt=f1;
|
||||
|
||||
@@ -10,7 +10,7 @@ class Color{
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
Color():r(0),g(0),b(0){}
|
||||
Color(uint8_t cr, uint8_t cg, uint8_t cb):
|
||||
Color(uint8_t cr, uint8_t cg,uint8_t cb):
|
||||
b(cb),g(cg),r(cr){}
|
||||
Color(const Color &o):b(o.b),g(o.g),r(o.r){}
|
||||
bool equal(const Color &o) const{
|
||||
@@ -22,8 +22,6 @@ class Color{
|
||||
bool operator != (const Color &other) const{
|
||||
return ! equal(other);
|
||||
}
|
||||
String toHex();
|
||||
String toName();
|
||||
};
|
||||
|
||||
static Color COLOR_GREEN=Color(0,255,0);
|
||||
|
||||
@@ -107,27 +107,6 @@ void hardwareInit(GwApi *api)
|
||||
}
|
||||
}
|
||||
|
||||
void powerInit(String powermode) {
|
||||
// Max Power | Only 5.0V | Min Power
|
||||
if (powermode == "Max Power" || powermode == "Only 5.0V") {
|
||||
#ifdef HARDWARE_V21
|
||||
setPortPin(OBP_POWER_50, true); // Power on 5.0V rail
|
||||
#endif
|
||||
#ifdef BOARD_OBP40S3
|
||||
setPortPin(OBP_POWER_EPD, true);// Power on ePaper display
|
||||
setPortPin(OBP_POWER_SD, true); // Power on SD card
|
||||
#endif
|
||||
} else { // Min Power
|
||||
#ifdef HARDWARE_V21
|
||||
setPortPin(OBP_POWER_50, false); // Power off 5.0V rail
|
||||
#endif
|
||||
#ifdef BOARD_OBP40S3
|
||||
setPortPin(OBP_POWER_EPD, false);// Power off ePaper display
|
||||
setPortPin(OBP_POWER_SD, false); // Power off SD card
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void setPortPin(uint pin, bool value){
|
||||
pinMode(pin, OUTPUT);
|
||||
digitalWrite(pin, value);
|
||||
|
||||
@@ -71,7 +71,6 @@ void deepSleep(CommonData &common);
|
||||
uint8_t getLastPage();
|
||||
|
||||
void hardwareInit(GwApi *api);
|
||||
void powerInit(String powermode);
|
||||
|
||||
void setPortPin(uint pin, bool value); // Set port pin for extension port
|
||||
|
||||
|
||||
433
lib/obp60task/PageAnchor.cpp
Normal file
433
lib/obp60task/PageAnchor.cpp
Normal file
@@ -0,0 +1,433 @@
|
||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||
|
||||
#include "Pagedata.h"
|
||||
#include "OBP60Extensions.h"
|
||||
#include "ConfigMenu.h"
|
||||
|
||||
/*
|
||||
Anchor overview with additional associated data
|
||||
This page is in experimental stage so be warned!
|
||||
North is up.
|
||||
|
||||
Boatdata used
|
||||
DBS - Water depth
|
||||
HDT - Boat heading
|
||||
AWS - Wind strength; Boat not moving so we assume AWS=TWS and AWD=TWD
|
||||
AWD - Wind direction
|
||||
LAT/LON - Boat position, current
|
||||
HDOP - Position error
|
||||
|
||||
This is the fist page to contain a configuration page with
|
||||
data entry option.
|
||||
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_height 16
|
||||
static unsigned char anchor_bits[] = {
|
||||
0x80, 0x01, 0x40, 0x02, 0x40, 0x02, 0x80, 0x01, 0xf0, 0x0f, 0x80, 0x01,
|
||||
0x80, 0x01, 0x88, 0x11, 0x8c, 0x31, 0x8e, 0x71, 0x84, 0x21, 0x86, 0x61,
|
||||
0x86, 0x61, 0xfc, 0x3f, 0xf8, 0x1f, 0x80, 0x01 };
|
||||
|
||||
class PageAnchor : public Page
|
||||
{
|
||||
private:
|
||||
GwConfigHandler *config;
|
||||
GwLog *logger;
|
||||
bool simulation = false;
|
||||
bool holdvalues = false;
|
||||
String flashLED;
|
||||
String backlightMode;
|
||||
String lengthformat;
|
||||
|
||||
int scale = 50; // Radius of display circle in meter
|
||||
|
||||
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
|
||||
int8_t editmode = -1; // marker for menu/edit/set function
|
||||
|
||||
ConfigMenu *menu;
|
||||
|
||||
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;
|
||||
String sunit_dbs = formatValue(bv_dbs, *commonData).unit;
|
||||
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;
|
||||
String sunit_aws = formatValue(bv_aws, *commonData).unit;
|
||||
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;
|
||||
String sunit_hdop = formatValue(bv_hdop, *commonData).unit;
|
||||
|
||||
LOG_DEBUG(GwLog::DEBUG,"Drawing at PageAnchor; DBS=%f, HDT=%f, AWS=%f", bv_dbs->value, bv_hdt->value, bv_aws->value);
|
||||
|
||||
Point c = {200, 150}; // center = anchor position
|
||||
uint16_t r = 125;
|
||||
|
||||
Point b = {200, 180}; // boat position while dropping anchor
|
||||
|
||||
const 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},
|
||||
{b.x + 5, b.y}
|
||||
};
|
||||
//rotatePoints und dann Linien zeichnen
|
||||
// TODO rotate boat according to current heading
|
||||
//drawPoly(rotatePoints(c, pts, RadToDeg(value2)), commonData->fgcolor);
|
||||
drawPoly(pts_boat, commonData->fgcolor);
|
||||
|
||||
// Draw wind arrow
|
||||
const std::vector<Point> pts_wind = {
|
||||
{c.x, c.y - r + 25},
|
||||
{c.x - 12, c.y - r - 4},
|
||||
{c.x, c.y - r + 6},
|
||||
{c.x + 12, c.y - r - 4}
|
||||
};
|
||||
if (bv_awd->valid) {
|
||||
fillPoly4(rotatePoints(c, pts_wind, bv_awd->value), commonData->fgcolor);
|
||||
}
|
||||
|
||||
// Title and corner value headings
|
||||
getdisplay().setTextColor(commonData->fgcolor);
|
||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
||||
getdisplay().setCursor(8, 48);
|
||||
getdisplay().print("Anchor");
|
||||
|
||||
getdisplay().setFont(&Ubuntu_Bold10pt8b);
|
||||
getdisplay().setCursor(8, 200);
|
||||
getdisplay().print("Depth");
|
||||
drawTextRalign(392, 38, "Chain");
|
||||
drawTextRalign(392, 200, "Wind");
|
||||
|
||||
// Units
|
||||
getdisplay().setCursor(8, 272);
|
||||
getdisplay().print(sunit_dbs);
|
||||
drawTextRalign(392, 272, sunit_aws);
|
||||
drawTextRalign(392, 100, lengthformat); // chain unit not implemented
|
||||
|
||||
// Corner values
|
||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
||||
getdisplay().setCursor(8, 70);
|
||||
getdisplay().print("Alarm: ");
|
||||
getdisplay().print(alarm_enabled ? "On" : "Off");
|
||||
|
||||
getdisplay().setCursor(8, 90);
|
||||
getdisplay().print("HDOP");
|
||||
getdisplay().setCursor(8, 106);
|
||||
if (bv_hdop->valid) {
|
||||
getdisplay().print(round(bv_hdop->value), 0);
|
||||
getdisplay().print(sunit_hdop);
|
||||
} else {
|
||||
getdisplay().print("n/a");
|
||||
}
|
||||
|
||||
// Values
|
||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||
// Current chain used
|
||||
getdisplay().setCursor(328, 85);
|
||||
getdisplay().print("27");
|
||||
|
||||
// Depth
|
||||
getdisplay().setCursor(8, 250);
|
||||
getdisplay().print(sval_dbs);
|
||||
// Wind
|
||||
getdisplay().setCursor(328, 250);
|
||||
getdisplay().print(sval_aws);
|
||||
|
||||
getdisplay().drawCircle(c.x, c.y, r, commonData->fgcolor);
|
||||
getdisplay().drawCircle(c.x, c.y, r + 1, commonData->fgcolor);
|
||||
|
||||
// zoom scale
|
||||
getdisplay().drawLine(c.x + 10, c.y, c.x + r - 4, c.y, commonData->fgcolor);
|
||||
// arrow left
|
||||
getdisplay().drawLine(c.x + 10, c.y, c.x + 16, c.y - 4, commonData->fgcolor);
|
||||
getdisplay().drawLine(c.x + 10, c.y, c.x + 16, c.y + 4, commonData->fgcolor);
|
||||
// arrow right
|
||||
getdisplay().drawLine(c.x + r - 4, c.y, c.x + r - 10, c.y - 4, commonData->fgcolor);
|
||||
getdisplay().drawLine(c.x + r - 4, c.y, c.x + r - 10, c.y + 4, commonData->fgcolor);
|
||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
||||
drawTextCenter(c.x + r / 2, c.y + 8, String(scale) + "m");
|
||||
|
||||
// alarm range circle
|
||||
if (alarm_enabled) {
|
||||
// alarm range in meter has to be smaller than the scale in meter
|
||||
// r and r_range are pixel values
|
||||
uint16_t r_range = int(alarm_range * r / scale);
|
||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageAnchor; Alarm range = %d", r_range);
|
||||
getdisplay().drawCircle(c.x, c.y, r_range, 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");
|
||||
|
||||
// TODO
|
||||
// show lat/lon for anchor pos
|
||||
// show lat/lon for boat pos
|
||||
// show distance anchor <-> boat
|
||||
|
||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
||||
for (int i = 0 ; i < menu->getItemCount(); i++) {
|
||||
ConfigMenuItem *itm = menu->getItemByIndex(i);
|
||||
if (!itm) {
|
||||
LOG_DEBUG(GwLog::ERROR, "Menu item not found: %d", i);
|
||||
} else {
|
||||
Rect r = menu->getItemRect(i);
|
||||
bool inverted = (i == menu->getActiveIndex());
|
||||
drawTextBoxed(r, itm->getLabel(), commonData->fgcolor, commonData->bgcolor, inverted, false);
|
||||
if (inverted and editmode > 0) {
|
||||
// triangle as edit marker
|
||||
getdisplay().fillTriangle(r.x + r.w + 20, r.y, r.x + r.w + 30, r.y + r.h / 2, r.x + r.w + 20, r.y + r.h, commonData->fgcolor);
|
||||
}
|
||||
getdisplay().setCursor(r.x + r.w + 40, r.y + r.h - 4);
|
||||
if (itm->getType() == "int") {
|
||||
getdisplay().print(itm->getValue());
|
||||
getdisplay().print(itm->getUnit());
|
||||
} else {
|
||||
getdisplay().print(itm->getValue() == 0 ? "No" : "Yes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public:
|
||||
PageAnchor(CommonData &common)
|
||||
{
|
||||
commonData = &common;
|
||||
config = commonData->config;
|
||||
logger = commonData->logger;
|
||||
logger->logDebug(GwLog::LOG,"Instantiate PageAnchor");
|
||||
|
||||
// preload configuration data
|
||||
simulation = config->getBool(config->useSimuData);
|
||||
holdvalues = config->getBool(config->holdvalues);
|
||||
flashLED = config->getString(config->flashLED);
|
||||
backlightMode = config->getString(config->backlight);
|
||||
lengthformat = config->getString(config->lengthFormat);
|
||||
chain_length = config->getInt(config->chainLength);
|
||||
|
||||
chain = 0;
|
||||
anchor_set = false;
|
||||
alarm_range = 30;
|
||||
|
||||
// Initialize config menu
|
||||
menu = new ConfigMenu("Options", 40, 80);
|
||||
menu->setItemDimension(150, 20);
|
||||
|
||||
ConfigMenuItem *newitem;
|
||||
newitem = menu->addItem("chain", "Chain out", "int", 0, "m");
|
||||
if (! newitem) {
|
||||
// Demo: in case of failure exit here, should never be happen
|
||||
logger->logDebug(GwLog::ERROR,"Menu item creation failed");
|
||||
return;
|
||||
}
|
||||
newitem->setRange(0, 200, {1, 5, 10});
|
||||
newitem = menu->addItem("chainmax", "Chain max", "int", chain_length, "m");
|
||||
newitem->setRange(0, 200, {1, 5, 10});
|
||||
newitem = menu->addItem("zoom", "Zoom", "int", 50, "m");
|
||||
newitem->setRange(0, 200, {1, });
|
||||
newitem = menu->addItem("range", "Alarm range", "int", 40, "m");
|
||||
newitem->setRange(0, 200, {1, 5, 10});
|
||||
newitem = menu->addItem("alat", "Adjust anchor lat.", "int", 0, "m");
|
||||
newitem->setRange(0, 200, {1, 5, 10});
|
||||
newitem = menu->addItem("alon", "Adjust anchor lon.", "int", 0, "m");
|
||||
newitem->setRange(0, 200, {1, 5, 10});
|
||||
#ifdef BOARD_OBP40S3
|
||||
// Intodruced here because of missing keys for OBP40
|
||||
newitem = menu->addItem("anchor", "Anchor down", "bool", 0, "");
|
||||
#endif
|
||||
menu->setItemActive("zoom");
|
||||
}
|
||||
|
||||
void setupKeys(){
|
||||
Page::setupKeys();
|
||||
commonData->keydata[0].label = "MODE";
|
||||
commonData->keydata[1].label = "ALARM";
|
||||
}
|
||||
|
||||
#ifdef BOARD_OBP60S3
|
||||
int handleKey(int key){
|
||||
if (key == 1) { // Switch between normal and config mode
|
||||
if (mode == 'N') {
|
||||
mode = 'C';
|
||||
} else {
|
||||
mode = 'N';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (mode == 'N') {
|
||||
if (key == 2) { // Toggle alarm
|
||||
alarm_enabled = !alarm_enabled;
|
||||
return 0;
|
||||
}
|
||||
} else { // Config mode
|
||||
if (key == 3) {
|
||||
// menu down
|
||||
menu->goNext();
|
||||
return 0;
|
||||
}
|
||||
if (key == 4) {
|
||||
// menu up
|
||||
menu->goPrev();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (key == 11) { // Code for keylock
|
||||
commonData->keylock = !commonData->keylock;
|
||||
return 0;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
#endif
|
||||
#ifdef BOARD_OBP40S3
|
||||
int handleKey(int key){
|
||||
if (key == 1) { // Switch between normal and config mode
|
||||
if (mode == 'N') {
|
||||
mode = 'C';
|
||||
commonData->keydata[1].label = "EDIT";
|
||||
} else {
|
||||
mode = 'N';
|
||||
commonData->keydata[1].label = "ALARM";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (mode == 'N') {
|
||||
if (key == 2) { // Toggle alarm
|
||||
alarm_enabled = !alarm_enabled;
|
||||
return 0;
|
||||
}
|
||||
} else { // Config mode
|
||||
// TODO different code for OBP40 / OBP60
|
||||
if (key == 9) {
|
||||
// menu down
|
||||
if (editmode > 0) {
|
||||
// decrease item value
|
||||
menu->getActiveItem()->decValue();
|
||||
} else {
|
||||
menu->goNext();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (key == 10) {
|
||||
// menu up or value up
|
||||
if (editmode > 0) {
|
||||
// increase item value
|
||||
menu->getActiveItem()->incValue();
|
||||
} else {
|
||||
menu->goPrev();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (key == 2) {
|
||||
// enter / leave edit mode for current menu item
|
||||
if (editmode > 0) {
|
||||
commonData->keydata[1].label = "EDIT";
|
||||
editmode = 0;
|
||||
} else {
|
||||
commonData->keydata[1].label = "SET";
|
||||
editmode = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (key == 11) { // Code for keylock
|
||||
commonData->keylock = !commonData->keylock;
|
||||
return 0;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
#endif
|
||||
|
||||
void displayNew(PageData &pageData){
|
||||
};
|
||||
|
||||
int displayPage(PageData &pageData){
|
||||
|
||||
// Logging boat values
|
||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageAnchor; Mode=%c", mode);
|
||||
|
||||
// Set display in partial refresh mode
|
||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
||||
|
||||
if (mode == 'N') {
|
||||
displayModeNormal(pageData);
|
||||
} else if (mode == 'C') {
|
||||
displayModeConfig();
|
||||
}
|
||||
|
||||
return PAGE_UPDATE;
|
||||
};
|
||||
};
|
||||
|
||||
static Page *createPage(CommonData &common){
|
||||
return new PageAnchor(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 registerPageAnchor(
|
||||
"Anchor", // Page name
|
||||
createPage, // Action
|
||||
0, // Number of bus values depends on selection in Web configuration
|
||||
{"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
|
||||
);
|
||||
|
||||
#endif
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "Pagedata.h"
|
||||
#include "OBP60Extensions.h"
|
||||
#include "ConfigMenu.h"
|
||||
#include "images/logo64.xbm"
|
||||
#include <esp32/clk.h>
|
||||
#include "qrcode.h"
|
||||
@@ -26,377 +25,37 @@
|
||||
* Consists of some sub-pages with following content:
|
||||
* 1. Hard and software information
|
||||
* 2. System settings
|
||||
* 3. System configuration: running and NVRAM
|
||||
* 4. NMEA2000 device list
|
||||
* 5. SD Card information if available
|
||||
*
|
||||
* TODO
|
||||
* - setCpuFrequencyMhz(80|160|240);
|
||||
* - Accesspoint / ! Änderung im Gatewaycode erforderlich?
|
||||
* if (! isApActive()) {
|
||||
* wifiSSID = config->getString(config->wifiSSID);
|
||||
* wifiPass = config->getString(config->wifiPass);
|
||||
* wifiSoftAP(wifiSSID, wifiPass);
|
||||
* }
|
||||
* - Power mode
|
||||
* powerInit(powermode);
|
||||
* 3. NMEA2000 device list
|
||||
*/
|
||||
|
||||
class PageSystem : public Page
|
||||
{
|
||||
private:
|
||||
GwConfigHandler *config;
|
||||
GwLog *logger;
|
||||
uint64_t chipid;
|
||||
bool simulation;
|
||||
bool sdcard;
|
||||
String buzzer_mode;
|
||||
uint8_t buzzer_power;
|
||||
String cpuspeed;
|
||||
String rtc_module;
|
||||
String gps_module;
|
||||
String env_module;
|
||||
|
||||
// NVRAM config options
|
||||
String flashLED;
|
||||
String batt_sensor;
|
||||
String solar_sensor;
|
||||
String gen_sensor;
|
||||
String rot_sensor;
|
||||
double homelat;
|
||||
double homelon;
|
||||
|
||||
// Generic data access
|
||||
|
||||
uint64_t chipid;
|
||||
bool simulation;
|
||||
bool sdcard;
|
||||
String buzzer_mode;
|
||||
uint8_t buzzer_power;
|
||||
String cpuspeed;
|
||||
String rtc_module;
|
||||
String gps_module;
|
||||
String env_module;
|
||||
|
||||
String batt_sensor;
|
||||
String solar_sensor;
|
||||
String gen_sensor;
|
||||
String rot_sensor;
|
||||
double homelat;
|
||||
double homelon;
|
||||
|
||||
char mode = 'N'; // (N)ormal, (S)ettings, (C)onfiguration, (D)evice list, c(A)rd
|
||||
int8_t editmode = -1; // marker for menu/edit/set function
|
||||
|
||||
ConfigMenu *menu;
|
||||
|
||||
void incMode() {
|
||||
if (mode == 'N') { // Normal
|
||||
mode = 'S';
|
||||
} else if (mode == 'S') { // Settings
|
||||
mode = 'C';
|
||||
} else if (mode == 'C') { // Config
|
||||
mode = 'D';
|
||||
} else if (mode == 'D') { // Device list
|
||||
if (sdcard) {
|
||||
mode = 'A'; // SD-Card
|
||||
} else {
|
||||
mode = 'N';
|
||||
}
|
||||
} else {
|
||||
mode = 'N';
|
||||
}
|
||||
}
|
||||
|
||||
void decMode() {
|
||||
if (mode == 'N') {
|
||||
if (sdcard) {
|
||||
mode = 'A';
|
||||
} else {
|
||||
mode = 'D';
|
||||
}
|
||||
} else if (mode == 'S') { // Settings
|
||||
mode = 'N';
|
||||
} else if (mode == 'C') { // Config
|
||||
mode = 'S';
|
||||
} else if (mode == 'D') { // Device list
|
||||
mode = 'C';
|
||||
} else {
|
||||
mode = 'D';
|
||||
}
|
||||
}
|
||||
|
||||
void displayModeNormal() {
|
||||
// Default system page view
|
||||
|
||||
uint16_t y0 = 155;
|
||||
|
||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
||||
getdisplay().setCursor(8, 48);
|
||||
getdisplay().print("System information");
|
||||
|
||||
getdisplay().drawXBitmap(320, 25, logo64_bits, logo64_width, logo64_height, commonData->fgcolor);
|
||||
|
||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
||||
|
||||
char ssid[13];
|
||||
snprintf(ssid, 13, "%04X%08X", (uint16_t)(chipid >> 32), (uint32_t)chipid);
|
||||
displayBarcode(String(ssid), 320, 200, 2);
|
||||
getdisplay().setCursor(8, 70);
|
||||
getdisplay().print(String("MCUDEVICE-") + String(ssid));
|
||||
|
||||
getdisplay().setCursor(8, 95);
|
||||
getdisplay().print("Firmware version: ");
|
||||
getdisplay().setCursor(150, 95);
|
||||
getdisplay().print(VERSINFO);
|
||||
|
||||
getdisplay().setCursor(8, 113);
|
||||
getdisplay().print("Board version: ");
|
||||
getdisplay().setCursor(150, 113);
|
||||
getdisplay().print(BOARDINFO);
|
||||
getdisplay().print(String(" HW ") + String(PCBINFO));
|
||||
|
||||
getdisplay().setCursor(8, 131);
|
||||
getdisplay().print("Display version: ");
|
||||
getdisplay().setCursor(150, 131);
|
||||
getdisplay().print(DISPLAYINFO);
|
||||
getdisplay().print("; GxEPD2 v");
|
||||
getdisplay().print(GXEPD2INFO);
|
||||
|
||||
getdisplay().setCursor(8, 265);
|
||||
#ifdef BOARD_OBP60S3
|
||||
getdisplay().print("Press STBY to enter deep sleep mode");
|
||||
#endif
|
||||
#ifdef BOARD_OBP40S3
|
||||
getdisplay().print("Press wheel to enter deep sleep mode");
|
||||
#endif
|
||||
|
||||
// Flash memory size
|
||||
uint32_t flash_size = ESP.getFlashChipSize();
|
||||
getdisplay().setCursor(8, y0);
|
||||
getdisplay().print("FLASH:");
|
||||
getdisplay().setCursor(90, y0);
|
||||
getdisplay().print(String(flash_size / 1024) + String(" kB"));
|
||||
|
||||
// PSRAM memory size
|
||||
uint32_t psram_size = ESP.getPsramSize();
|
||||
getdisplay().setCursor(8, y0 + 16);
|
||||
getdisplay().print("PSRAM:");
|
||||
getdisplay().setCursor(90, y0 + 16);
|
||||
getdisplay().print(String(psram_size / 1024) + String(" kB"));
|
||||
|
||||
// FRAM available / status
|
||||
getdisplay().setCursor(8, y0 + 32);
|
||||
getdisplay().print("FRAM:");
|
||||
getdisplay().setCursor(90, y0 + 32);
|
||||
getdisplay().print(hasFRAM ? "available" : "not found");
|
||||
|
||||
#ifdef BOARD_OBP40S3
|
||||
// SD-Card
|
||||
getdisplay().setCursor(8, y0 + 48);
|
||||
getdisplay().print("SD-Card:");
|
||||
getdisplay().setCursor(90, y0 + 48);
|
||||
if (sdcard) {
|
||||
uint64_t cardsize = SD.cardSize() / (1024 * 1024);
|
||||
getdisplay().print(String(cardsize) + String(" MB"));
|
||||
} else {
|
||||
getdisplay().print("off");
|
||||
}
|
||||
#endif
|
||||
|
||||
// CPU speed config / active
|
||||
getdisplay().setCursor(202, y0);
|
||||
getdisplay().print("CPU speed:");
|
||||
getdisplay().setCursor(300, y0);
|
||||
getdisplay().print(cpuspeed);
|
||||
getdisplay().print(" / ");
|
||||
int cpu_freq = esp_clk_cpu_freq() / 1000000;
|
||||
getdisplay().print(String(cpu_freq));
|
||||
|
||||
// total RAM free
|
||||
int Heap_free = esp_get_free_heap_size();
|
||||
getdisplay().setCursor(202, y0 + 16);
|
||||
getdisplay().print("Total free:");
|
||||
getdisplay().setCursor(300, y0 + 16);
|
||||
getdisplay().print(String(Heap_free));
|
||||
|
||||
// RAM free for task
|
||||
int RAM_free = uxTaskGetStackHighWaterMark(NULL);
|
||||
getdisplay().setCursor(202, y0 + 32);
|
||||
getdisplay().print("Task free:");
|
||||
getdisplay().setCursor(300, y0 + 32);
|
||||
getdisplay().print(String(RAM_free));
|
||||
}
|
||||
|
||||
void displayModeConfig() {
|
||||
// Configuration interface
|
||||
|
||||
uint16_t x0 = 16;
|
||||
uint16_t y0 = 80;
|
||||
uint16_t dy = 20;
|
||||
|
||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
||||
getdisplay().setCursor(8, 48);
|
||||
getdisplay().print("System configuration");
|
||||
|
||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
||||
|
||||
/*getdisplay().setCursor(x0, y0);
|
||||
getdisplay().print("CPU speed: 80 | 160 | 240");
|
||||
getdisplay().setCursor(x0, y0 + 1 * dy);
|
||||
getdisplay().print("Power mode: Max | 5V | Min");
|
||||
getdisplay().setCursor(x0, y0 + 2 * dy);
|
||||
getdisplay().print("Accesspoint: On | Off");
|
||||
|
||||
// TODO Change NVRAM-preferences settings here
|
||||
getdisplay().setCursor(x0, y0 + 4 * dy);
|
||||
getdisplay().print("Simulation: On | Off"); */
|
||||
|
||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
||||
for (int i = 0 ; i < menu->getItemCount(); i++) {
|
||||
ConfigMenuItem *itm = menu->getItemByIndex(i);
|
||||
if (!itm) {
|
||||
LOG_DEBUG(GwLog::ERROR, "Menu item not found: %d", i);
|
||||
} else {
|
||||
Rect r = menu->getItemRect(i);
|
||||
bool inverted = (i == menu->getActiveIndex());
|
||||
drawTextBoxed(r, itm->getLabel(), commonData->fgcolor, commonData->bgcolor, inverted, false);
|
||||
if (inverted and editmode > 0) {
|
||||
// triangle as edit marker
|
||||
getdisplay().fillTriangle(r.x + r.w + 20, r.y, r.x + r.w + 30, r.y + r.h / 2, r.x + r.w + 20, r.y + r.h, commonData->fgcolor);
|
||||
}
|
||||
getdisplay().setCursor(r.x + r.w + 40, r.y + r.h - 4);
|
||||
if (itm->getType() == "int") {
|
||||
getdisplay().print(itm->getValue());
|
||||
getdisplay().print(itm->getUnit());
|
||||
} else {
|
||||
getdisplay().print(itm->getValue() == 0 ? "No" : "Yes");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void displayModeSettings() {
|
||||
// View some of the current settings
|
||||
|
||||
const uint16_t x0 = 8;
|
||||
const uint16_t y0 = 72;
|
||||
|
||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
||||
getdisplay().setCursor(x0, 48);
|
||||
getdisplay().print("System settings");
|
||||
|
||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
||||
|
||||
// left column
|
||||
getdisplay().setCursor(x0, y0);
|
||||
getdisplay().print("Simulation:");
|
||||
getdisplay().setCursor(120, y0);
|
||||
getdisplay().print(simulation ? "on" : "off");
|
||||
|
||||
getdisplay().setCursor(x0, y0 + 16);
|
||||
getdisplay().print("Environment:");
|
||||
getdisplay().setCursor(120, y0 + 16);
|
||||
getdisplay().print(env_module);
|
||||
|
||||
getdisplay().setCursor(x0, y0 + 32);
|
||||
getdisplay().print("Buzzer:");
|
||||
getdisplay().setCursor(120, y0 + 32);
|
||||
getdisplay().print(buzzer_mode);
|
||||
|
||||
getdisplay().setCursor(x0, y0 + 64);
|
||||
getdisplay().print("GPS:");
|
||||
getdisplay().setCursor(120, y0 + 64);
|
||||
getdisplay().print(gps_module);
|
||||
|
||||
getdisplay().setCursor(x0, y0 + 80);
|
||||
getdisplay().print("RTC:");
|
||||
getdisplay().setCursor(120, y0 + 80);
|
||||
getdisplay().print(rtc_module);
|
||||
|
||||
getdisplay().setCursor(x0, y0 + 96);
|
||||
getdisplay().print("Wifi:");
|
||||
getdisplay().setCursor(120, y0 + 96);
|
||||
getdisplay().print(commonData->status.wifiApOn ? "on" : "off");
|
||||
|
||||
// Home location
|
||||
getdisplay().setCursor(x0, y0 + 128);
|
||||
getdisplay().print("Home Lat.:");
|
||||
drawTextRalign(230, y0 + 128, formatLatitude(homelat));
|
||||
getdisplay().setCursor(x0, y0 + 144);
|
||||
getdisplay().print("Home Lon.:");
|
||||
drawTextRalign(230, y0 + 144, formatLongitude(homelon));
|
||||
|
||||
// right column
|
||||
getdisplay().setCursor(202, y0);
|
||||
getdisplay().print("Batt. sensor:");
|
||||
getdisplay().setCursor(320, y0);
|
||||
getdisplay().print(batt_sensor);
|
||||
|
||||
// Solar sensor
|
||||
getdisplay().setCursor(202, y0 + 16);
|
||||
getdisplay().print("Solar sensor:");
|
||||
getdisplay().setCursor(320, y0 + 16);
|
||||
getdisplay().print(solar_sensor);
|
||||
|
||||
// Generator sensor
|
||||
getdisplay().setCursor(202, y0 + 32);
|
||||
getdisplay().print("Gen. sensor:");
|
||||
getdisplay().setCursor(320, y0 + 32);
|
||||
getdisplay().print(gen_sensor);
|
||||
|
||||
#ifdef BOARD_OBP60S3
|
||||
// Backlight infos
|
||||
getdisplay().setCursor(202, y0 + 64);
|
||||
getdisplay().print("Backlight:");
|
||||
getdisplay().setCursor(320, y0 + 64);
|
||||
getdisplay().printf("%d%%", commonData->backlight.brightness);
|
||||
// TODO test function with OBP60 device
|
||||
getdisplay().setCursor(202, y0 + 80);
|
||||
getdisplay().print("Bl color:");
|
||||
getdisplay().setCursor(320, y0 + 80);
|
||||
getdisplay().print(commonData->backlight.color.toName());
|
||||
getdisplay().setCursor(202, y0 + 96);
|
||||
getdisplay().print("Bl mode:");
|
||||
getdisplay().setCursor(320, y0 + 96);
|
||||
getdisplay().print(commonData->backlight.mode);
|
||||
// TODO Buzzer mode and power
|
||||
#endif
|
||||
|
||||
// Gyro sensor
|
||||
// WIP / FEATURE
|
||||
}
|
||||
|
||||
void displayModeSDCard() {
|
||||
// SD card info
|
||||
uint16_t x0 = 20;
|
||||
uint16_t y0 = 72;
|
||||
|
||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
||||
getdisplay().setCursor(8, 48);
|
||||
getdisplay().print("SD Card info");
|
||||
|
||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
||||
getdisplay().setCursor(x0, y0);
|
||||
getdisplay().print("Work in progress...");
|
||||
}
|
||||
|
||||
void displayModeDevicelist() {
|
||||
// NMEA2000 device list
|
||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
||||
getdisplay().setCursor(8, 48);
|
||||
getdisplay().print("NMEA2000 device list");
|
||||
|
||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
||||
getdisplay().setCursor(20, 80);
|
||||
getdisplay().print("RxD: ");
|
||||
getdisplay().print(String(commonData->status.n2kRx));
|
||||
getdisplay().setCursor(20, 100);
|
||||
getdisplay().print("TxD: ");
|
||||
getdisplay().print(String(commonData->status.n2kTx));
|
||||
}
|
||||
|
||||
void storeConfig() {
|
||||
menu->storeValues();
|
||||
}
|
||||
char mode = 'N'; // (N)ormal, (S)ettings, (D)evice list, (C)ard
|
||||
|
||||
public:
|
||||
PageSystem(CommonData &common){
|
||||
commonData = &common;
|
||||
config = commonData->config;
|
||||
logger = commonData->logger;
|
||||
|
||||
logger->logDebug(GwLog::LOG,"Instantiate PageSystem");
|
||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageSystem");
|
||||
if (hasFRAM) {
|
||||
mode = fram.read(FRAM_SYSTEM_MODE);
|
||||
}
|
||||
flashLED = common.config->getString(common.config->flashLED);
|
||||
|
||||
chipid = ESP.getEfuseMac();
|
||||
simulation = common.config->getBool(common.config->useSimuData);
|
||||
#ifdef BOARD_OBP40S3
|
||||
@@ -415,24 +74,6 @@ public:
|
||||
rot_sensor = common.config->getString(common.config->useRotSensor);
|
||||
homelat = common.config->getString(common.config->homeLAT).toDouble();
|
||||
homelon = common.config->getString(common.config->homeLON).toDouble();
|
||||
|
||||
// CPU speed: 80 | 160 | 240
|
||||
// Power mode: Max | 5V | Min
|
||||
// Accesspoint: On | Off
|
||||
|
||||
// TODO Change NVRAM-preferences settings here
|
||||
// getdisplay().setCursor(x0, y0 + 4 * dy);
|
||||
// getdisplay().print("Simulation: On | Off");
|
||||
|
||||
// Initialize config menu
|
||||
menu = new ConfigMenu("Options", 40, 80);
|
||||
menu->setItemDimension(150, 20);
|
||||
|
||||
ConfigMenuItem *newitem;
|
||||
newitem = menu->addItem("accesspoint", "Accesspoint", "bool", 0, "");
|
||||
newitem = menu->addItem("simulation", "Simulation", "on/off", 0, "");
|
||||
menu->setItemActive("accesspoint");
|
||||
|
||||
}
|
||||
|
||||
virtual void setupKeys(){
|
||||
@@ -449,7 +90,19 @@ public:
|
||||
// Switch display mode
|
||||
commonData->logger->logDebug(GwLog::LOG, "System keyboard handler");
|
||||
if (key == 2) {
|
||||
incMode();
|
||||
if (mode == 'N') {
|
||||
mode = 'S';
|
||||
} else if (mode == 'S') {
|
||||
mode = 'D';
|
||||
} else if (mode == 'D') {
|
||||
if (sdcard) {
|
||||
mode = 'C';
|
||||
} else {
|
||||
mode = 'N';
|
||||
}
|
||||
} else {
|
||||
mode = 'N';
|
||||
}
|
||||
if (hasFRAM) fram.write(FRAM_SYSTEM_MODE, mode);
|
||||
return 0;
|
||||
}
|
||||
@@ -473,13 +126,8 @@ public:
|
||||
}
|
||||
#endif
|
||||
#ifdef BOARD_OBP40S3
|
||||
// use cursor keys for local mode navigation
|
||||
if (key == 9) {
|
||||
incMode();
|
||||
return 0;
|
||||
}
|
||||
if (key == 10) {
|
||||
decMode();
|
||||
// grab cursor keys to disable page navigation
|
||||
if (key == 9 or key == 10) {
|
||||
return 0;
|
||||
}
|
||||
// standby / deep sleep
|
||||
@@ -520,35 +168,225 @@ public:
|
||||
GwConfigHandler *config = commonData->config;
|
||||
GwLog *logger = commonData->logger;
|
||||
|
||||
// Get config data
|
||||
String flashLED = config->getString(config->flashLED);
|
||||
|
||||
// Optical warning by limit violation (unused)
|
||||
if(flashLED == "Limit Violation"){
|
||||
if(String(flashLED) == "Limit Violation"){
|
||||
setBlinkingLED(false);
|
||||
setFlashLED(false);
|
||||
}
|
||||
|
||||
// Logging page information
|
||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageSystem, Mode=%c", mode);
|
||||
// Logging boat values
|
||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageSystem");
|
||||
|
||||
// Draw page
|
||||
//***********************************************************
|
||||
|
||||
uint16_t x0 = 8; // left column
|
||||
uint16_t y0 = 48; // data table starts here
|
||||
|
||||
// Set display in partial refresh mode
|
||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height());
|
||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
||||
|
||||
// call current system page
|
||||
switch (mode) {
|
||||
case 'N':
|
||||
displayModeNormal();
|
||||
break;
|
||||
case 'S':
|
||||
displayModeSettings();
|
||||
break;
|
||||
case 'C':
|
||||
displayModeConfig();
|
||||
break;
|
||||
case 'A':
|
||||
displayModeSDCard();
|
||||
break;
|
||||
case 'D':
|
||||
displayModeDevicelist();
|
||||
break;
|
||||
if (mode == 'N') {
|
||||
|
||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
||||
getdisplay().setCursor(8, 48);
|
||||
getdisplay().print("System Information");
|
||||
|
||||
getdisplay().drawXBitmap(320, 25, logo64_bits, logo64_width, logo64_height, commonData->fgcolor);
|
||||
|
||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
||||
y0 = 155;
|
||||
|
||||
char ssid[13];
|
||||
snprintf(ssid, 13, "%04X%08X", (uint16_t)(chipid >> 32), (uint32_t)chipid);
|
||||
displayBarcode(String(ssid), 320, 200, 2);
|
||||
getdisplay().setCursor(8, 70);
|
||||
getdisplay().print(String("MCUDEVICE-") + String(ssid));
|
||||
|
||||
getdisplay().setCursor(8, 95);
|
||||
getdisplay().print("Firmware version: ");
|
||||
getdisplay().setCursor(150, 95);
|
||||
getdisplay().print(VERSINFO);
|
||||
|
||||
getdisplay().setCursor(8, 113);
|
||||
getdisplay().print("Board version: ");
|
||||
getdisplay().setCursor(150, 113);
|
||||
getdisplay().print(BOARDINFO);
|
||||
getdisplay().print(String(" HW ") + String(PCBINFO));
|
||||
|
||||
getdisplay().setCursor(8, 131);
|
||||
getdisplay().print("Display version: ");
|
||||
getdisplay().setCursor(150, 131);
|
||||
getdisplay().print(DISPLAYINFO);
|
||||
getdisplay().print("; GxEPD2 v");
|
||||
getdisplay().print(GXEPD2INFO);
|
||||
|
||||
getdisplay().setCursor(8, 265);
|
||||
#ifdef BOARD_OBP60S3
|
||||
getdisplay().print("Press STBY to enter deep sleep mode");
|
||||
#endif
|
||||
#ifdef BOARD_OBP40S3
|
||||
getdisplay().print("Press wheel to enter deep sleep mode");
|
||||
#endif
|
||||
|
||||
// Flash memory size
|
||||
uint32_t flash_size = ESP.getFlashChipSize();
|
||||
getdisplay().setCursor(8, y0);
|
||||
getdisplay().print("FLASH:");
|
||||
getdisplay().setCursor(90, y0);
|
||||
getdisplay().print(String(flash_size / 1024) + String(" kB"));
|
||||
|
||||
// PSRAM memory size
|
||||
uint32_t psram_size = ESP.getPsramSize();
|
||||
getdisplay().setCursor(8, y0 + 16);
|
||||
getdisplay().print("PSRAM:");
|
||||
getdisplay().setCursor(90, y0 + 16);
|
||||
getdisplay().print(String(psram_size / 1024) + String(" kB"));
|
||||
|
||||
// FRAM available / status
|
||||
getdisplay().setCursor(8, y0 + 32);
|
||||
getdisplay().print("FRAM:");
|
||||
getdisplay().setCursor(90, y0 + 32);
|
||||
getdisplay().print(hasFRAM ? "available" : "not found");
|
||||
|
||||
#ifdef BOARD_OBP40S3
|
||||
// SD-Card
|
||||
getdisplay().setCursor(8, y0 + 48);
|
||||
getdisplay().print("SD-Card:");
|
||||
getdisplay().setCursor(90, y0 + 48);
|
||||
if (sdcard) {
|
||||
uint64_t cardsize = SD.cardSize() / (1024 * 1024);
|
||||
getdisplay().print(String(cardsize) + String(" MB"));
|
||||
} else {
|
||||
getdisplay().print("off");
|
||||
}
|
||||
#endif
|
||||
|
||||
// CPU speed config / active
|
||||
getdisplay().setCursor(202, y0);
|
||||
getdisplay().print("CPU speed:");
|
||||
getdisplay().setCursor(300, y0);
|
||||
getdisplay().print(cpuspeed);
|
||||
getdisplay().print(" / ");
|
||||
int cpu_freq = esp_clk_cpu_freq() / 1000000;
|
||||
getdisplay().print(String(cpu_freq));
|
||||
|
||||
// total RAM free
|
||||
int Heap_free = esp_get_free_heap_size();
|
||||
getdisplay().setCursor(202, y0 + 16);
|
||||
getdisplay().print("Total free:");
|
||||
getdisplay().setCursor(300, y0 + 16);
|
||||
getdisplay().print(String(Heap_free));
|
||||
|
||||
// RAM free for task
|
||||
int RAM_free = uxTaskGetStackHighWaterMark(NULL);
|
||||
getdisplay().setCursor(202, y0 + 32);
|
||||
getdisplay().print("Task free:");
|
||||
getdisplay().setCursor(300, y0 + 32);
|
||||
getdisplay().print(String(RAM_free));
|
||||
|
||||
} else if (mode == 'S') {
|
||||
// Settings
|
||||
|
||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
||||
getdisplay().setCursor(x0, 48);
|
||||
getdisplay().print("System settings");
|
||||
|
||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
||||
x0 = 8;
|
||||
y0 = 72;
|
||||
|
||||
// left column
|
||||
getdisplay().setCursor(x0, y0);
|
||||
getdisplay().print("Simulation:");
|
||||
getdisplay().setCursor(120, y0);
|
||||
getdisplay().print(simulation ? "on" : "off");
|
||||
|
||||
getdisplay().setCursor(x0, y0 + 16);
|
||||
getdisplay().print("Environment:");
|
||||
getdisplay().setCursor(120, y0 + 16);
|
||||
getdisplay().print(env_module);
|
||||
|
||||
getdisplay().setCursor(x0, y0 + 32);
|
||||
getdisplay().print("Buzzer:");
|
||||
getdisplay().setCursor(120, y0 + 32);
|
||||
getdisplay().print(buzzer_mode);
|
||||
|
||||
getdisplay().setCursor(x0, y0 + 64);
|
||||
getdisplay().print("GPS:");
|
||||
getdisplay().setCursor(120, y0 + 64);
|
||||
getdisplay().print(gps_module);
|
||||
|
||||
getdisplay().setCursor(x0, y0 + 80);
|
||||
getdisplay().print("RTC:");
|
||||
getdisplay().setCursor(120, y0 + 80);
|
||||
getdisplay().print(rtc_module);
|
||||
|
||||
getdisplay().setCursor(x0, y0 + 96);
|
||||
getdisplay().print("Wifi:");
|
||||
getdisplay().setCursor(120, y0 + 96);
|
||||
getdisplay().print(commonData->status.wifiApOn ? "on" : "off");
|
||||
|
||||
// Home location
|
||||
getdisplay().setCursor(x0, y0 + 128);
|
||||
getdisplay().print("Home Lat.:");
|
||||
getdisplay().setCursor(120, y0 + 128);
|
||||
getdisplay().print(formatLatitude(homelat));
|
||||
getdisplay().setCursor(x0, y0 + 144);
|
||||
getdisplay().print("Home Lon.:");
|
||||
getdisplay().setCursor(120, y0 + 144);
|
||||
getdisplay().print(formatLongitude(homelon));
|
||||
|
||||
// right column
|
||||
getdisplay().setCursor(202, y0);
|
||||
getdisplay().print("Batt. sensor:");
|
||||
getdisplay().setCursor(320, y0);
|
||||
getdisplay().print(batt_sensor);
|
||||
|
||||
// Solar sensor
|
||||
getdisplay().setCursor(202, y0 + 16);
|
||||
getdisplay().print("Solar sensor:");
|
||||
getdisplay().setCursor(320, y0 + 16);
|
||||
getdisplay().print(solar_sensor);
|
||||
|
||||
// Generator sensor
|
||||
getdisplay().setCursor(202, y0 + 32);
|
||||
getdisplay().print("Gen. sensor:");
|
||||
getdisplay().setCursor(320, y0 + 32);
|
||||
getdisplay().print(gen_sensor);
|
||||
|
||||
// Gyro sensor
|
||||
|
||||
} else if (mode == 'C') {
|
||||
// Card info
|
||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
||||
getdisplay().setCursor(8, 48);
|
||||
getdisplay().print("SD Card info");
|
||||
|
||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
||||
|
||||
x0 = 20;
|
||||
y0 = 72;
|
||||
getdisplay().setCursor(x0, y0);
|
||||
getdisplay().print("Work in progress...");
|
||||
|
||||
|
||||
} else {
|
||||
// NMEA2000 device list
|
||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
||||
getdisplay().setCursor(8, 48);
|
||||
getdisplay().print("NMEA2000 device list");
|
||||
|
||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
||||
getdisplay().setCursor(20, 80);
|
||||
getdisplay().print("RxD: ");
|
||||
getdisplay().print(String(commonData->status.n2kRx));
|
||||
getdisplay().setCursor(20, 100);
|
||||
getdisplay().print("TxD: ");
|
||||
getdisplay().print(String(commonData->status.n2kTx));
|
||||
}
|
||||
|
||||
// Update display
|
||||
|
||||
@@ -75,6 +75,20 @@
|
||||
"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",
|
||||
"label": "Fuel Tank [l]",
|
||||
@@ -1303,6 +1317,7 @@
|
||||
"default": "Voltage",
|
||||
"description": "Type of page for page 1",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
@@ -1584,6 +1599,7 @@
|
||||
"default": "WindRose",
|
||||
"description": "Type of page for page 2",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
@@ -1862,6 +1878,7 @@
|
||||
"default": "OneValue",
|
||||
"description": "Type of page for page 3",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
@@ -2137,6 +2154,7 @@
|
||||
"default": "TwoValues",
|
||||
"description": "Type of page for page 4",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
@@ -2409,6 +2427,7 @@
|
||||
"default": "ThreeValues",
|
||||
"description": "Type of page for page 5",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
@@ -2678,6 +2697,7 @@
|
||||
"default": "FourValues",
|
||||
"description": "Type of page for page 6",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
@@ -2944,6 +2964,7 @@
|
||||
"default": "FourValues2",
|
||||
"description": "Type of page for page 7",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
@@ -3207,6 +3228,7 @@
|
||||
"default": "Clock",
|
||||
"description": "Type of page for page 8",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
@@ -3467,6 +3489,7 @@
|
||||
"default": "RollPitch",
|
||||
"description": "Type of page for page 9",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
@@ -3724,6 +3747,7 @@
|
||||
"default": "Battery2",
|
||||
"description": "Type of page for page 10",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
|
||||
@@ -75,6 +75,20 @@
|
||||
"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",
|
||||
"label": "Fuel Tank [l]",
|
||||
@@ -1326,6 +1340,7 @@
|
||||
"default": "Clock",
|
||||
"description": "Type of page for page 1",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
@@ -1607,6 +1622,7 @@
|
||||
"default": "Wind",
|
||||
"description": "Type of page for page 2",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
@@ -1885,6 +1901,7 @@
|
||||
"default": "OneValue",
|
||||
"description": "Type of page for page 3",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
@@ -2160,6 +2177,7 @@
|
||||
"default": "TwoValues",
|
||||
"description": "Type of page for page 4",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
@@ -2432,6 +2450,7 @@
|
||||
"default": "ThreeValues",
|
||||
"description": "Type of page for page 5",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
@@ -2701,6 +2720,7 @@
|
||||
"default": "FourValues",
|
||||
"description": "Type of page for page 6",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
@@ -2967,6 +2987,7 @@
|
||||
"default": "FourValues2",
|
||||
"description": "Type of page for page 7",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
@@ -3230,6 +3251,7 @@
|
||||
"default": "Fluid",
|
||||
"description": "Type of page for page 8",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
@@ -3490,6 +3512,7 @@
|
||||
"default": "RollPitch",
|
||||
"description": "Type of page for page 9",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
@@ -3747,6 +3770,7 @@
|
||||
"default": "Battery2",
|
||||
"description": "Type of page for page 10",
|
||||
"list": [
|
||||
"Anchor",
|
||||
"BME280",
|
||||
"Battery",
|
||||
"Battery2",
|
||||
|
||||
@@ -34,6 +34,7 @@ no_of_fields_per_page = {
|
||||
"WindPlot": 0,
|
||||
"WindRose": 0,
|
||||
"WindRoseFlex": 6,
|
||||
"Anchor", 0
|
||||
}
|
||||
|
||||
# No changes needed beyond this point
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "OBPDataOperations.h" // Functions lib for data operations such as true wind calculation
|
||||
|
||||
#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 <SD.h>
|
||||
#include <SPI.h>
|
||||
@@ -54,13 +54,31 @@ void OBP60Init(GwApi *api){
|
||||
|
||||
// Check I2C devices
|
||||
|
||||
|
||||
// Init hardware
|
||||
hardwareInit(api);
|
||||
|
||||
// Init power
|
||||
// Init power rail 5.0V
|
||||
String powermode = api->getConfig()->getConfigItem(api->getConfig()->powerMode,true)->asString();
|
||||
api->getLogger()->logDebug(GwLog::DEBUG,"Power Mode is: %s", powermode.c_str());
|
||||
powerInit(powermode);
|
||||
if(powermode == "Max Power" || powermode == "Only 5.0V"){
|
||||
#ifdef HARDWARE_V21
|
||||
setPortPin(OBP_POWER_50, true); // Power on 5.0V rail
|
||||
#endif
|
||||
#ifdef BOARD_OBP40S3
|
||||
setPortPin(OBP_POWER_EPD, true);// Power on ePaper display
|
||||
setPortPin(OBP_POWER_SD, true); // Power on SD card
|
||||
#endif
|
||||
}
|
||||
else{
|
||||
#ifdef HARDWARE_V21
|
||||
setPortPin(OBP_POWER_50, false); // Power off 5.0V rail
|
||||
#endif
|
||||
#ifdef BOARD_OBP40S3
|
||||
setPortPin(OBP_POWER_EPD, false);// Power off ePaper display
|
||||
setPortPin(OBP_POWER_SD, false); // Power off SD card
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef BOARD_OBP40S3
|
||||
bool sdcard = config->getBool(config->useSDCard);
|
||||
@@ -295,6 +313,8 @@ void registerAllPages(PageList &list){
|
||||
list.add(®isterPageXTETrack);
|
||||
extern PageDescription registerPageFluid;
|
||||
list.add(®isterPageFluid);
|
||||
extern PageDescription registerPageAnchor;
|
||||
list.add(®isterPageAnchor);
|
||||
}
|
||||
|
||||
// Undervoltage detection for shutdown display
|
||||
|
||||
Reference in New Issue
Block a user