mirror of
https://github.com/thooge/esp32-nmea2000-obp60.git
synced 2025-12-28 21:23:07 +01:00
Compare commits
2 Commits
system
...
c7a580612e
| Author | SHA1 | Date | |
|---|---|---|---|
| c7a580612e | |||
| a311f2f164 |
@@ -1,204 +0,0 @@
|
|||||||
/*
|
|
||||||
Menu system for online configuration
|
|
||||||
*/
|
|
||||||
#include "ConfigMenu.h"
|
|
||||||
|
|
||||||
ConfigMenuItem::ConfigMenuItem(String itemtype, String itemlabel, uint16_t itemval, String itemunit) {
|
|
||||||
if (! (itemtype == "int" or itemtype == "bool")) {
|
|
||||||
valtype = "int";
|
|
||||||
} else {
|
|
||||||
valtype = itemtype;
|
|
||||||
}
|
|
||||||
label = itemlabel;
|
|
||||||
min = 0;
|
|
||||||
max = std::numeric_limits<uint16_t>::max();
|
|
||||||
value = itemval;
|
|
||||||
unit = itemunit;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigMenuItem::setRange(uint16_t valmin, uint16_t valmax, std::vector<uint16_t> valsteps) {
|
|
||||||
min = valmin;
|
|
||||||
max = valmax;
|
|
||||||
steps = valsteps;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool ConfigMenuItem::checkRange(uint16_t checkval) {
|
|
||||||
return (checkval >= min) and (checkval <= max);
|
|
||||||
}
|
|
||||||
|
|
||||||
String ConfigMenuItem::getLabel() {
|
|
||||||
return label;
|
|
||||||
};
|
|
||||||
|
|
||||||
uint16_t ConfigMenuItem::getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConfigMenuItem::setValue(uint16_t newval) {
|
|
||||||
if (valtype == "int") {
|
|
||||||
if (newval >= min and newval <= max) {
|
|
||||||
value = newval;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false; // out of range
|
|
||||||
} else if (valtype == "bool") {
|
|
||||||
value = (newval != 0) ? 1 : 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false; // invalid type
|
|
||||||
};
|
|
||||||
|
|
||||||
void ConfigMenuItem::incValue() {
|
|
||||||
// increase value by step
|
|
||||||
if (valtype == "int") {
|
|
||||||
if (value + step < max) {
|
|
||||||
value += step;
|
|
||||||
} else {
|
|
||||||
value = max;
|
|
||||||
}
|
|
||||||
} else if (valtype == "bool") {
|
|
||||||
value = !value;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void ConfigMenuItem::decValue() {
|
|
||||||
// decrease value by step
|
|
||||||
if (valtype == "int") {
|
|
||||||
if (value - step > min) {
|
|
||||||
value -= step;
|
|
||||||
} else {
|
|
||||||
value = min;
|
|
||||||
}
|
|
||||||
} else if (valtype == "bool") {
|
|
||||||
value = !value;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
String ConfigMenuItem::getUnit() {
|
|
||||||
return unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t ConfigMenuItem::getStep() {
|
|
||||||
return step;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigMenuItem::setStep(uint16_t newstep) {
|
|
||||||
if (std::find(steps.begin(), steps.end(), newstep) == steps.end()) {
|
|
||||||
return; // invalid step: not in list of possible steps
|
|
||||||
}
|
|
||||||
step = newstep;
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t ConfigMenuItem::getPos() {
|
|
||||||
return position;
|
|
||||||
};
|
|
||||||
|
|
||||||
void ConfigMenuItem::setPos(int8_t newpos) {
|
|
||||||
position = newpos;
|
|
||||||
};
|
|
||||||
|
|
||||||
String ConfigMenuItem::getType() {
|
|
||||||
return valtype;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigMenu::ConfigMenu(String menutitle, uint16_t menu_x, uint16_t menu_y) {
|
|
||||||
title = menutitle;
|
|
||||||
x = menu_x;
|
|
||||||
y = menu_y;
|
|
||||||
};
|
|
||||||
|
|
||||||
ConfigMenuItem* ConfigMenu::addItem(String key, String label, String valtype, uint16_t val, String valunit) {
|
|
||||||
if (items.find(key) != items.end()) {
|
|
||||||
// duplicate keys not allowed
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
ConfigMenuItem *itm = new ConfigMenuItem(valtype, label, val, valunit);
|
|
||||||
items.insert(std::pair<String, ConfigMenuItem*>(key, itm));
|
|
||||||
// Append key to index, index starting with 0
|
|
||||||
int8_t ix = items.size() - 1;
|
|
||||||
index[ix] = key;
|
|
||||||
itm->setPos(ix);
|
|
||||||
return itm;
|
|
||||||
};
|
|
||||||
|
|
||||||
void ConfigMenu::setItemDimension(uint16_t itemwidth, uint16_t itemheight) {
|
|
||||||
w = itemwidth;
|
|
||||||
h = itemheight;
|
|
||||||
};
|
|
||||||
|
|
||||||
void ConfigMenu::setItemActive(String key) {
|
|
||||||
if (items.find(key) != items.end()) {
|
|
||||||
activeitem = items[key]->getPos();
|
|
||||||
} else {
|
|
||||||
activeitem = -1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int8_t ConfigMenu::getActiveIndex() {
|
|
||||||
return activeitem;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigMenuItem* ConfigMenu::getActiveItem() {
|
|
||||||
if (activeitem < 0) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return items[index[activeitem]];
|
|
||||||
};
|
|
||||||
|
|
||||||
ConfigMenuItem* ConfigMenu::getItemByIndex(uint8_t ix) {
|
|
||||||
if (ix > index.size() - 1) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return items[index[ix]];
|
|
||||||
};
|
|
||||||
|
|
||||||
ConfigMenuItem* ConfigMenu::getItemByKey(String key) {
|
|
||||||
if (items.find(key) == items.end()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return items[key];
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t ConfigMenu::getItemCount() {
|
|
||||||
return items.size();
|
|
||||||
};
|
|
||||||
|
|
||||||
void ConfigMenu::goPrev() {
|
|
||||||
if (activeitem == 0) {
|
|
||||||
activeitem = items.size() - 1;
|
|
||||||
} else {
|
|
||||||
activeitem--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigMenu::goNext() {
|
|
||||||
if (activeitem == items.size() - 1) {
|
|
||||||
activeitem = 0;
|
|
||||||
} else {
|
|
||||||
activeitem++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Point ConfigMenu::getXY() {
|
|
||||||
return {static_cast<double>(x), static_cast<double>(y)};
|
|
||||||
}
|
|
||||||
|
|
||||||
Rect ConfigMenu::getRect() {
|
|
||||||
return {static_cast<double>(x), static_cast<double>(y),
|
|
||||||
static_cast<double>(w), static_cast<double>(h)};
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include "Graphics.h" // for Point and Rect
|
|
||||||
|
|
||||||
class ConfigMenuItem {
|
|
||||||
private:
|
|
||||||
String label;
|
|
||||||
uint16_t value;
|
|
||||||
String unit;
|
|
||||||
String valtype; // "int" | "bool"
|
|
||||||
uint16_t min;
|
|
||||||
uint16_t max;
|
|
||||||
std::vector<uint16_t> steps;
|
|
||||||
uint16_t step;
|
|
||||||
int8_t position; // counted fom 0
|
|
||||||
|
|
||||||
public:
|
|
||||||
ConfigMenuItem(String itemtype, String itemlabel, uint16_t itemval, String itemunit);
|
|
||||||
void setRange(uint16_t valmin, uint16_t valmax, std::vector<uint16_t> steps);
|
|
||||||
bool checkRange(uint16_t checkval);
|
|
||||||
String getLabel();
|
|
||||||
uint16_t getValue();
|
|
||||||
bool setValue(uint16_t newval);
|
|
||||||
void incValue();
|
|
||||||
void decValue();
|
|
||||||
String getUnit();
|
|
||||||
uint16_t getStep();
|
|
||||||
void setStep(uint16_t newstep);
|
|
||||||
int8_t getPos();
|
|
||||||
void setPos(int8_t newpos);
|
|
||||||
String getType();
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConfigMenu {
|
|
||||||
private:
|
|
||||||
String title;
|
|
||||||
std::map <String,ConfigMenuItem*> items;
|
|
||||||
std::map <uint8_t,String> index;
|
|
||||||
int8_t activeitem = -1; // refers to position of item
|
|
||||||
uint16_t x;
|
|
||||||
uint16_t y;
|
|
||||||
uint16_t w;
|
|
||||||
uint16_t h;
|
|
||||||
void (*fptrCallback)();
|
|
||||||
|
|
||||||
public:
|
|
||||||
ConfigMenu(String title, uint16_t menu_x, uint16_t menu_y);
|
|
||||||
ConfigMenuItem* addItem(String key, String label, String valtype, uint16_t val, String valunit);
|
|
||||||
void setItemDimension(uint16_t itemwidth, uint16_t itemheight);
|
|
||||||
int8_t getActiveIndex();
|
|
||||||
void setItemActive(String key);
|
|
||||||
ConfigMenuItem* getActiveItem();
|
|
||||||
ConfigMenuItem* getItemByIndex(uint8_t index);
|
|
||||||
ConfigMenuItem* getItemByKey(String key);
|
|
||||||
uint8_t getItemCount();
|
|
||||||
void goPrev();
|
|
||||||
void goNext();
|
|
||||||
Point getXY();
|
|
||||||
Rect getRect();
|
|
||||||
Rect getItemRect(int8_t index);
|
|
||||||
void setCallback(void (*callback)());
|
|
||||||
void storeValues();
|
|
||||||
};
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
Generic graphics functions
|
|
||||||
|
|
||||||
*/
|
|
||||||
#include <math.h>
|
|
||||||
#include "Graphics.h"
|
|
||||||
|
|
||||||
Point rotatePoint(const Point& origin, const Point& p, double angle) {
|
|
||||||
// rotate poind around origin by degrees
|
|
||||||
Point rotated;
|
|
||||||
double phi = angle * M_PI / 180.0;
|
|
||||||
double dx = p.x - origin.x;
|
|
||||||
double dy = p.y - origin.y;
|
|
||||||
rotated.x = origin.x + cos(phi) * dx - sin(phi) * dy;
|
|
||||||
rotated.y = origin.y + sin(phi) * dx + cos(phi) * dy;
|
|
||||||
return rotated;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Point> rotatePoints(const Point& origin, const std::vector<Point>& pts, double angle) {
|
|
||||||
std::vector<Point> rotatedPoints;
|
|
||||||
for (const auto& p : pts) {
|
|
||||||
rotatedPoints.push_back(rotatePoint(origin, p, angle));
|
|
||||||
}
|
|
||||||
return rotatedPoints;
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
struct Point {
|
|
||||||
double x;
|
|
||||||
double y;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Rect {
|
|
||||||
double x;
|
|
||||||
double y;
|
|
||||||
double w;
|
|
||||||
double h;
|
|
||||||
};
|
|
||||||
|
|
||||||
Point rotatePoint(const Point& origin, const Point& p, double angle);
|
|
||||||
std::vector<Point> rotatePoints(const Point& origin, const std::vector<Point>& pts, double angle);
|
|
||||||
@@ -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){
|
static uint8_t mulcolor(uint8_t f1, uint8_t f2){
|
||||||
uint16_t rt=f1;
|
uint16_t rt=f1;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class Color{
|
|||||||
uint8_t g;
|
uint8_t g;
|
||||||
uint8_t b;
|
uint8_t b;
|
||||||
Color():r(0),g(0),b(0){}
|
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){}
|
b(cb),g(cg),r(cr){}
|
||||||
Color(const Color &o):b(o.b),g(o.g),r(o.r){}
|
Color(const Color &o):b(o.b),g(o.g),r(o.r){}
|
||||||
bool equal(const Color &o) const{
|
bool equal(const Color &o) const{
|
||||||
@@ -22,8 +22,6 @@ class Color{
|
|||||||
bool operator != (const Color &other) const{
|
bool operator != (const Color &other) const{
|
||||||
return ! equal(other);
|
return ! equal(other);
|
||||||
}
|
}
|
||||||
String toHex();
|
|
||||||
String toName();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static Color COLOR_GREEN=Color(0,255,0);
|
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){
|
void setPortPin(uint pin, bool value){
|
||||||
pinMode(pin, OUTPUT);
|
pinMode(pin, OUTPUT);
|
||||||
digitalWrite(pin, value);
|
digitalWrite(pin, value);
|
||||||
@@ -297,20 +276,30 @@ String xdrDelete(String input){
|
|||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Point rotatePoint(const Point& origin, const Point& p, double angle) {
|
||||||
|
// rotate poind around origin by degrees
|
||||||
|
Point rotated;
|
||||||
|
double phi = angle * M_PI / 180.0;
|
||||||
|
double dx = p.x - origin.x;
|
||||||
|
double dy = p.y - origin.y;
|
||||||
|
rotated.x = origin.x + cos(phi) * dx - sin(phi) * dy;
|
||||||
|
rotated.y = origin.y + sin(phi) * dx + cos(phi) * dy;
|
||||||
|
return rotated;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Point> rotatePoints(const Point& origin, const std::vector<Point>& pts, double angle) {
|
||||||
|
std::vector<Point> rotatedPoints;
|
||||||
|
for (const auto& p : pts) {
|
||||||
|
rotatedPoints.push_back(rotatePoint(origin, p, angle));
|
||||||
|
}
|
||||||
|
return rotatedPoints;
|
||||||
|
}
|
||||||
|
|
||||||
void fillPoly4(const std::vector<Point>& p4, uint16_t color) {
|
void fillPoly4(const std::vector<Point>& p4, uint16_t color) {
|
||||||
getdisplay().fillTriangle(p4[0].x, p4[0].y, p4[1].x, p4[1].y, p4[2].x, p4[2].y, color);
|
getdisplay().fillTriangle(p4[0].x, p4[0].y, p4[1].x, p4[1].y, p4[2].x, p4[2].y, color);
|
||||||
getdisplay().fillTriangle(p4[0].x, p4[0].y, p4[2].x, p4[2].y, p4[3].x, p4[3].y, color);
|
getdisplay().fillTriangle(p4[0].x, p4[0].y, p4[2].x, p4[2].y, p4[3].x, p4[3].y, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawPoly(const std::vector<Point>& points, uint16_t color) {
|
|
||||||
size_t polysize = points.size();
|
|
||||||
for (size_t i = 0; i < polysize - 1; i++) {
|
|
||||||
getdisplay().drawLine(points[i].x, points[i].y, points[i+1].x, points[i+1].y, color);
|
|
||||||
}
|
|
||||||
// close path
|
|
||||||
getdisplay().drawLine(points[polysize-1].x, points[polysize-1].y, points[0].x, points[0].y, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Split string into words, whitespace separated
|
// Split string into words, whitespace separated
|
||||||
std::vector<String> split(const String &s) {
|
std::vector<String> split(const String &s) {
|
||||||
std::vector<String> words;
|
std::vector<String> words;
|
||||||
@@ -372,24 +361,6 @@ void drawTextRalign(int16_t x, int16_t y, String text) {
|
|||||||
getdisplay().print(text);
|
getdisplay().print(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw text inside box, normal or inverted
|
|
||||||
void drawTextBoxed(Rect box, String text, uint16_t fg, uint16_t bg, bool inverted, bool border) {
|
|
||||||
if (inverted) {
|
|
||||||
getdisplay().fillRect(box.x, box.y, box.w, box.h, fg);
|
|
||||||
getdisplay().setTextColor(bg);
|
|
||||||
} else {
|
|
||||||
if (border) {
|
|
||||||
getdisplay().fillRect(box.x + 1, box.y + 1, box.w - 2, box.h - 2, bg);
|
|
||||||
getdisplay().drawRect(box.x, box.y, box.w, box.h, fg);
|
|
||||||
}
|
|
||||||
getdisplay().setTextColor(fg);
|
|
||||||
}
|
|
||||||
uint16_t border_offset = box.h / 4; // 25% of box height
|
|
||||||
getdisplay().setCursor(box.x + border_offset, box.y + box.h - border_offset);
|
|
||||||
getdisplay().print(text);
|
|
||||||
getdisplay().setTextColor(fg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show a triangle for trend direction high (x, y is the left edge)
|
// Show a triangle for trend direction high (x, y is the left edge)
|
||||||
void displayTrendHigh(int16_t x, int16_t y, uint16_t size, uint16_t color){
|
void displayTrendHigh(int16_t x, int16_t y, uint16_t size, uint16_t color){
|
||||||
getdisplay().fillTriangle(x, y, x+size*2, y, x+size, y-size*2, color);
|
getdisplay().fillTriangle(x, y, x+size*2, y, x+size, y-size*2, color);
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "OBP60Hardware.h"
|
#include "OBP60Hardware.h"
|
||||||
#include "LedSpiTask.h"
|
#include "LedSpiTask.h"
|
||||||
#include "Graphics.h"
|
|
||||||
#include <GxEPD2_BW.h> // E-paper lib V2
|
#include <GxEPD2_BW.h> // E-paper lib V2
|
||||||
#include <Adafruit_FRAM_I2C.h> // I2C FRAM
|
#include <Adafruit_FRAM_I2C.h> // I2C FRAM
|
||||||
|
|
||||||
@@ -63,15 +62,19 @@ GxEPD2_BW<GxEPD2_420_SE0420NQ04, GxEPD2_420_SE0420NQ04::HEIGHT> & getdisplay();
|
|||||||
#define PAGE_UPDATE 1 // page wants display to update
|
#define PAGE_UPDATE 1 // page wants display to update
|
||||||
#define PAGE_HIBERNATE 2 // page wants displey to hibernate
|
#define PAGE_HIBERNATE 2 // page wants displey to hibernate
|
||||||
|
|
||||||
|
struct Point {
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
};
|
||||||
|
Point rotatePoint(const Point& origin, const Point& p, double angle);
|
||||||
|
std::vector<Point> rotatePoints(const Point& origin, const std::vector<Point>& pts, double angle);
|
||||||
void fillPoly4(const std::vector<Point>& p4, uint16_t color);
|
void fillPoly4(const std::vector<Point>& p4, uint16_t color);
|
||||||
void drawPoly(const std::vector<Point>& points, uint16_t color);
|
|
||||||
|
|
||||||
void deepSleep(CommonData &common);
|
void deepSleep(CommonData &common);
|
||||||
|
|
||||||
uint8_t getLastPage();
|
uint8_t getLastPage();
|
||||||
|
|
||||||
void hardwareInit(GwApi *api);
|
void hardwareInit(GwApi *api);
|
||||||
void powerInit(String powermode);
|
|
||||||
|
|
||||||
void setPortPin(uint pin, bool value); // Set port pin for extension port
|
void setPortPin(uint pin, bool value); // Set port pin for extension port
|
||||||
|
|
||||||
@@ -93,7 +96,6 @@ String xdrDelete(String input); // Delete xdr prefix from string
|
|||||||
|
|
||||||
void drawTextCenter(int16_t cx, int16_t cy, String text);
|
void drawTextCenter(int16_t cx, int16_t cy, String text);
|
||||||
void drawTextRalign(int16_t x, int16_t y, String text);
|
void drawTextRalign(int16_t x, int16_t y, String text);
|
||||||
void drawTextBoxed(Rect box, String text, uint16_t fg, uint16_t bg, bool inverted, bool border);
|
|
||||||
|
|
||||||
void displayTrendHigh(int16_t x, int16_t y, uint16_t size, uint16_t color);
|
void displayTrendHigh(int16_t x, int16_t y, uint16_t size, uint16_t color);
|
||||||
void displayTrendLow(int16_t x, int16_t y, uint16_t size, uint16_t color);
|
void displayTrendLow(int16_t x, int16_t y, uint16_t size, uint16_t color);
|
||||||
|
|||||||
@@ -49,9 +49,9 @@ String formatLongitude(double lon) {
|
|||||||
return String(degree, 0) + "\x90 " + String(minute, 4) + "' " + ((lon > 0) ? "E" : "W");
|
return String(degree, 0) + "\x90 " + String(minute, 4) + "' " + ((lon > 0) ? "E" : "W");
|
||||||
}
|
}
|
||||||
|
|
||||||
FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
FormatedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
||||||
GwLog *logger = commondata.logger;
|
GwLog *logger = commondata.logger;
|
||||||
FormattedData result;
|
FormatedData result;
|
||||||
static int dayoffset = 0;
|
static int dayoffset = 0;
|
||||||
double rawvalue = 0;
|
double rawvalue = 0;
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal,
|
|||||||
} else if (*cogVal != DBL_MIN) {
|
} else if (*cogVal != DBL_MIN) {
|
||||||
hdt = *cogVal; // Use COG as fallback if HDT and HDM are not available
|
hdt = *cogVal; // Use COG as fallback if HDT and HDM are not available
|
||||||
} else {
|
} else {
|
||||||
return false; // Cannot calculate without valid HDT or HDM+VAR or COG
|
return false; // Cannot calculate without valid HDT or HDM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +102,8 @@ bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal,
|
|||||||
ctw = *cogVal; // Use COG as CTW if available
|
ctw = *cogVal; // Use COG as CTW if available
|
||||||
// ctw = *cogVal + ((*cogVal - hdt) / 2); // Estimate CTW from COG
|
// ctw = *cogVal + ((*cogVal - hdt) / 2); // Estimate CTW from COG
|
||||||
} else {
|
} else {
|
||||||
ctw = hdt; // 2nd approximation for CTW; hdt must exist if we reach this part of the code
|
ctw = hdt; // 2nd approximation for CTW;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*stwVal != DBL_MIN) {
|
if (*stwVal != DBL_MIN) {
|
||||||
@@ -114,11 +115,11 @@ bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*awaVal == DBL_MIN) || (*awsVal == DBL_MIN)) {
|
if ((*awaVal == DBL_MIN) || (*awsVal == DBL_MIN) || (*cogVal == DBL_MIN) || (*stwVal == DBL_MIN)) {
|
||||||
// Cannot calculate true wind without valid AWA, AWS; other checks are done earlier
|
// Cannot calculate true wind without valid AWA, AWS, COG, or STW
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
calcTwdSA(awaVal, awsVal, &ctw, &stw, &hdt, &twd, &tws, &twa);
|
calcTwdSA(awaVal, awsVal, &ctw, stwVal, &hdt, &twd, &tws, &twa);
|
||||||
*twdVal = twd;
|
*twdVal = twd;
|
||||||
*twsVal = tws;
|
*twsVal = tws;
|
||||||
*twaVal = twa;
|
*twaVal = twa;
|
||||||
|
|||||||
249
lib/obp60task/PageAnchor.cpp
Normal file
249
lib/obp60task/PageAnchor.cpp
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
|
#include "Pagedata.h"
|
||||||
|
#include "OBP60Extensions.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;
|
||||||
|
|
||||||
|
bool alarm = false;
|
||||||
|
bool alarm_enabled = false;
|
||||||
|
uint8_t alarm_range;
|
||||||
|
|
||||||
|
uint8_t chain_length;
|
||||||
|
uint8_t chain;
|
||||||
|
|
||||||
|
bool anchor_set = false;
|
||||||
|
double anchor_lat;
|
||||||
|
double anchor_lon;
|
||||||
|
double anchor_depth;
|
||||||
|
int anchor_ts; // time stamp anchor dropped
|
||||||
|
|
||||||
|
char mode = 'N'; // (N)ormal, (C)onfig
|
||||||
|
|
||||||
|
void displayModeNormal(PageData &pageData) {
|
||||||
|
|
||||||
|
// Boatvalues: DBS, HDT, AWS, AWD, LAT, LON, HDOP
|
||||||
|
GwApi::BoatValue *bv_dbs = pageData.values[0]; // DBS
|
||||||
|
String sval_dbs = formatValue(bv_dbs, *commonData).svalue;
|
||||||
|
GwApi::BoatValue *bv_hdt = pageData.values[1]; // HDT
|
||||||
|
String sval_hdt = formatValue(bv_hdt, *commonData).svalue;
|
||||||
|
GwApi::BoatValue *bv_aws = pageData.values[2]; // AWS
|
||||||
|
String sval_aws = formatValue(bv_aws, *commonData).svalue;
|
||||||
|
GwApi::BoatValue *bv_awd = pageData.values[3]; // AWD
|
||||||
|
String sval_awd = formatValue(bv_awd, *commonData).svalue;
|
||||||
|
GwApi::BoatValue *bv_lat = pageData.values[4]; // LAT
|
||||||
|
String sval_lat = formatValue(bv_lat, *commonData).svalue;
|
||||||
|
GwApi::BoatValue *bv_lon = pageData.values[5]; // LON
|
||||||
|
String sval_lon = formatValue(bv_lon, *commonData).svalue;
|
||||||
|
GwApi::BoatValue *bv_hdop = pageData.values[6]; // HDOP
|
||||||
|
String sval_hdop = formatValue(bv_hdop, *commonData).svalue;
|
||||||
|
|
||||||
|
Point c = {200, 150}; // center = anchor position
|
||||||
|
uint16_t r = 125;
|
||||||
|
|
||||||
|
Point b = {200, 180}; // boat position while dropping anchor
|
||||||
|
|
||||||
|
std::vector<Point> pts_boat = { // polygon lines
|
||||||
|
{b.x - 5, b.y},
|
||||||
|
{b.x - 5, b.y - 10},
|
||||||
|
{b.x, b.y - 16},
|
||||||
|
{b.x + 5, b.y - 10}
|
||||||
|
};
|
||||||
|
//rotatePoints und dann Linien zeichnen
|
||||||
|
// TODO rotate boat according to current heading
|
||||||
|
//fillPoly4(rotatePoints(c, pts, RadToDeg(value2)), commonData->fgcolor);
|
||||||
|
|
||||||
|
// Draw wind arrow
|
||||||
|
/*
|
||||||
|
if self._bd.awa.value:
|
||||||
|
p = ((cx, cy - r + 25), (cx - 12, cy - r - 4), (cx, cy - r + 6), (cx + 12, cy - r - 4), (cx, cy - r + 25))
|
||||||
|
wind = self.rotate((cx, cy), p, self._bd.awa.value)
|
||||||
|
ctx.move_to(*wind[0])
|
||||||
|
for point in wind[1:]:
|
||||||
|
ctx.line_to(*point)
|
||||||
|
ctx.fill()
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Title and corner value headings
|
||||||
|
getdisplay().setTextColor(commonData->fgcolor);
|
||||||
|
getdisplay().setFont(&Ubuntu_Bold10pt8b);
|
||||||
|
getdisplay().setCursor(8, 48);
|
||||||
|
getdisplay().print("Anchor");
|
||||||
|
|
||||||
|
getdisplay().setCursor(8, 200);
|
||||||
|
getdisplay().print("Depth");
|
||||||
|
|
||||||
|
drawTextRalign(392, 50, "Chain");
|
||||||
|
drawTextRalign(392, 200, "Wind");
|
||||||
|
|
||||||
|
// Corner values
|
||||||
|
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
getdisplay().setCursor(2, 70);
|
||||||
|
getdisplay().print("Alarm: ");
|
||||||
|
getdisplay().print(alarm_enabled ? "On" : "Off");
|
||||||
|
|
||||||
|
// Units
|
||||||
|
|
||||||
|
// Values
|
||||||
|
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
|
// Depth
|
||||||
|
getdisplay().setCursor(8, 250);
|
||||||
|
//getdisplay().print(sval_dbs);
|
||||||
|
getdisplay().print("6.4");
|
||||||
|
// Wind
|
||||||
|
getdisplay().setCursor(320, 250);
|
||||||
|
//getdisplay().print(sval_aws);
|
||||||
|
getdisplay().print("12");
|
||||||
|
|
||||||
|
getdisplay().drawCircle(c.x, c.y, r, commonData->fgcolor);
|
||||||
|
|
||||||
|
// draw anchor symbol (as bitmap)
|
||||||
|
getdisplay().drawXBitmap(c.x - anchor_width / 2, c.y - anchor_height / 2,
|
||||||
|
anchor_bits, anchor_width, anchor_height, commonData->fgcolor);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayModeConfig() {
|
||||||
|
getdisplay().setTextColor(commonData->fgcolor);
|
||||||
|
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
getdisplay().setCursor(8, 48);
|
||||||
|
getdisplay().print("Anchor configuration");
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
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);
|
||||||
|
chainLength = config->getInt(config->chainLength);
|
||||||
|
|
||||||
|
chain = 0;
|
||||||
|
anchor_set = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupKeys(){
|
||||||
|
Page::setupKeys();
|
||||||
|
commonData->keydata[0].label = "MODE";
|
||||||
|
commonData->keydata[1].label = "ALARM";
|
||||||
|
}
|
||||||
|
|
||||||
|
int handleKey(int key){
|
||||||
|
if (key == 1) { // Switch between normal and config mode
|
||||||
|
if (mode == 'N') {
|
||||||
|
mode = 'C';
|
||||||
|
} else {
|
||||||
|
mode = 'N';
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (key == 2) { // Toggle alarm
|
||||||
|
alarm_enabled = !alarm_enabled;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (key == 11) { // Code for keylock
|
||||||
|
commonData->keylock = !commonData->keylock;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayNew(PageData &pageData){
|
||||||
|
};
|
||||||
|
|
||||||
|
int displayPage(PageData &pageData){
|
||||||
|
|
||||||
|
// Logging boat values
|
||||||
|
LOG_DEBUG(GwLog::LOG,"Drawing at PageAnchor");
|
||||||
|
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
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
class PageBattery : public Page
|
class PageBattery : public Page
|
||||||
{
|
{
|
||||||
int average = 0; // Average type [0...3], 0=off, 1=10s, 2=60s, 3=300s
|
int average = 0; // Average type [0...3], 0=off, 1=10s, 2=60s, 3=300s
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageBattery(CommonData &common){
|
PageBattery(CommonData &common){
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ bool homevalid = false; // homelat and homelon are valid
|
|||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
value1 = simtime++; // Simulation data for time value 11:36 in seconds
|
value1 = simtime++; // Simulation data for time value 11:36 in seconds
|
||||||
} // Other simulation data see OBP60Formatter.cpp
|
} // Other simulation data see OBP60Formater.cpp
|
||||||
bool valid1 = bvalue1->valid; // Valid information
|
bool valid1 = bvalue1->valid; // Valid information
|
||||||
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
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ class PageCompass : public Page
|
|||||||
String DataText[HowManyValues];
|
String DataText[HowManyValues];
|
||||||
String DataUnits[HowManyValues];
|
String DataUnits[HowManyValues];
|
||||||
String DataFormat[HowManyValues];
|
String DataFormat[HowManyValues];
|
||||||
FormattedData TheFormattedData;
|
FormatedData TheFormattedData;
|
||||||
|
|
||||||
for (int i = 0; i < HowManyValues; i++){
|
for (int i = 0; i < HowManyValues; i++){
|
||||||
bvalue = pageData.values[i];
|
bvalue = pageData.values[i];
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class PageFourValues : public Page
|
|||||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values #2
|
// Get boat values #2
|
||||||
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list
|
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list (only one value by PageOneValue)
|
||||||
String name2 = xdrDelete(bvalue2->getName()); // Value name
|
String name2 = xdrDelete(bvalue2->getName()); // 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
|
||||||
@@ -63,7 +63,7 @@ class PageFourValues : public Page
|
|||||||
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
|
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values #3
|
// Get boat values #3
|
||||||
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Third element in list
|
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue)
|
||||||
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
|
||||||
@@ -73,7 +73,7 @@ class PageFourValues : public Page
|
|||||||
String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value
|
String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values #4
|
// Get boat values #4
|
||||||
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Fourth element in list
|
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Second element in list (only one value by PageOneValue)
|
||||||
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
|
||||||
@@ -301,7 +301,7 @@ static Page *createPage(CommonData &common){
|
|||||||
* this will be number of BoatValue pointers in pageData.values
|
* this will be number of BoatValue pointers in pageData.values
|
||||||
*/
|
*/
|
||||||
PageDescription registerPageFourValues(
|
PageDescription registerPageFourValues(
|
||||||
"FourValues", // Page name
|
"FourValues", // Page name
|
||||||
createPage, // Action
|
createPage, // Action
|
||||||
4, // Number of bus values depends on selection in Web configuration
|
4, // Number of bus values depends on selection in Web configuration
|
||||||
true // Show display header on/off
|
true // Show display header on/off
|
||||||
|
|||||||
@@ -86,20 +86,21 @@ public:
|
|||||||
float x = 200 + (rInstrument-30)*sin(i/180.0*pi); // x-coordinate dots
|
float x = 200 + (rInstrument-30)*sin(i/180.0*pi); // x-coordinate dots
|
||||||
float y = 150 - (rInstrument-30)*cos(i/180.0*pi); // y-coordinate cots
|
float y = 150 - (rInstrument-30)*cos(i/180.0*pi); // y-coordinate cots
|
||||||
const char *ii = " ";
|
const char *ii = " ";
|
||||||
switch (i) {
|
switch (i)
|
||||||
case 0: ii=" "; break; // Use a blank for a empty scale value
|
{
|
||||||
case 30 : ii=" "; break;
|
case 0: ii=" "; break; // Use a blank for a empty scale value
|
||||||
case 60 : ii=" "; break;
|
case 30 : ii=" "; break;
|
||||||
case 90 : ii="45"; break;
|
case 60 : ii=" "; break;
|
||||||
case 120 : ii="30"; break;
|
case 90 : ii="45"; break;
|
||||||
case 150 : ii="15"; break;
|
case 120 : ii="30"; break;
|
||||||
case 180 : ii="0"; break;
|
case 150 : ii="15"; break;
|
||||||
case 210 : ii="15"; break;
|
case 180 : ii="0"; break;
|
||||||
case 240 : ii="30"; break;
|
case 210 : ii="15"; break;
|
||||||
case 270 : ii="45"; break;
|
case 240 : ii="30"; break;
|
||||||
case 300 : ii=" "; break;
|
case 270 : ii="45"; break;
|
||||||
case 330 : ii=" "; break;
|
case 300 : ii=" "; break;
|
||||||
default: break;
|
case 330 : ii=" "; break;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print text centered on position x, y
|
// Print text centered on position x, y
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ public:
|
|||||||
String backlightMode = config->getString(config->backlight);
|
String backlightMode = config->getString(config->backlight);
|
||||||
int rolllimit = config->getInt(config->rollLimit);
|
int rolllimit = config->getInt(config->rollLimit);
|
||||||
String roffset = config->getString(config->rollOffset);
|
String roffset = config->getString(config->rollOffset);
|
||||||
double rolloffset = roffset.toFloat()/360*(2*M_PI);
|
double rolloffset = roffset.toFloat()/360*(2*PI);
|
||||||
String poffset = config->getString(config->pitchOffset);
|
String poffset = config->getString(config->pitchOffset);
|
||||||
double pitchoffset = poffset.toFloat()/360*(2*M_PI);
|
double pitchoffset = poffset.toFloat()/360*(2*PI);
|
||||||
|
|
||||||
// Get boat values for roll
|
// Get boat values for roll
|
||||||
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (xdrRoll)
|
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (xdrRoll)
|
||||||
@@ -55,17 +55,17 @@ public:
|
|||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if(simulation == true){
|
if(simulation == true){
|
||||||
value1 = (20 + float(random(0, 50)) / 10.0)/360*2*M_PI;
|
value1 = (20 + float(random(0, 50)) / 10.0)/360*2*PI;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
value1 = 0;
|
value1 = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(value1/(2*M_PI)*360 > -10 && value1/(2*M_PI)*360 < 10){
|
if(value1/(2*PI)*360 > -10 && value1/(2*PI)*360 < 10){
|
||||||
svalue1 = String(value1/(2*M_PI)*360,1); // Convert raw value to string
|
svalue1 = String(value1/(2*PI)*360,1); // Convert raw value to string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
svalue1 = String(value1/(2*M_PI)*360,0);
|
svalue1 = String(value1/(2*PI)*360,0);
|
||||||
}
|
}
|
||||||
if(valid1 == true){
|
if(valid1 == true){
|
||||||
svalue1old = svalue1; // Save the old value
|
svalue1old = svalue1; // Save the old value
|
||||||
@@ -80,17 +80,17 @@ public:
|
|||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if(simulation == true){
|
if(simulation == true){
|
||||||
value2 = (float(random(-5, 5)))/360*2*M_PI;
|
value2 = (float(random(-5, 5)))/360*2*PI;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
value2 = 0;
|
value2 = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(value2/(2*PI)*360 > -10 && value2/(2*M_PI)*360 < 10){
|
if(value2/(2*PI)*360 > -10 && value2/(2*PI)*360 < 10){
|
||||||
svalue2 = String(value2/(2*M_PI)*360,1); // Convert raw value to string
|
svalue2 = String(value2/(2*PI)*360,1); // Convert raw value to string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
svalue2 = String(value2/(2*M_PI)*360,0);
|
svalue2 = String(value2/(2*PI)*360,0);
|
||||||
}
|
}
|
||||||
if(valid2 == true){
|
if(valid2 == true){
|
||||||
svalue2old = svalue2; // Save the old value
|
svalue2old = svalue2; // Save the old value
|
||||||
@@ -99,7 +99,7 @@ public:
|
|||||||
// Optical warning by limit violation
|
// Optical warning by limit violation
|
||||||
if(String(flashLED) == "Limit Violation"){
|
if(String(flashLED) == "Limit Violation"){
|
||||||
// Limits for roll
|
// Limits for roll
|
||||||
if(value1*360/(2*M_PI) >= -1*rolllimit && value1*360/(2*M_PI) <= rolllimit){
|
if(value1*360/(2*PI) >= -1*rolllimit && value1*360/(2*PI) <= rolllimit){
|
||||||
setBlinkingLED(false);
|
setBlinkingLED(false);
|
||||||
setFlashLED(false);
|
setFlashLED(false);
|
||||||
}
|
}
|
||||||
@@ -132,7 +132,7 @@ public:
|
|||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(10, 115);
|
getdisplay().setCursor(10, 115);
|
||||||
getdisplay().print("DEG");
|
getdisplay().print("DEG");
|
||||||
|
|
||||||
// Horizintal separator left
|
// Horizintal separator left
|
||||||
getdisplay().fillRect(0, 149, 60, 3, commonData->fgcolor);
|
getdisplay().fillRect(0, 149, 60, 3, commonData->fgcolor);
|
||||||
|
|
||||||
@@ -164,7 +164,7 @@ public:
|
|||||||
getdisplay().print("Deg");
|
getdisplay().print("Deg");
|
||||||
|
|
||||||
//*******************************************************************************************
|
//*******************************************************************************************
|
||||||
|
|
||||||
// Draw instrument
|
// Draw instrument
|
||||||
int rInstrument = 100; // Radius of instrument
|
int rInstrument = 100; // Radius of instrument
|
||||||
float pi = 3.141592;
|
float pi = 3.141592;
|
||||||
@@ -177,18 +177,19 @@ public:
|
|||||||
// Only scaling +/- 60 degrees
|
// Only scaling +/- 60 degrees
|
||||||
if((i >= 0 && i <= 60) || (i >= 300 && i <= 360)){
|
if((i >= 0 && i <= 60) || (i >= 300 && i <= 360)){
|
||||||
// Scaling values
|
// Scaling values
|
||||||
float x = 200 + (rInstrument+25)*sin(i/180.0*M_PI); // x-coordinate dots
|
float x = 200 + (rInstrument+25)*sin(i/180.0*pi); // x-coordinate dots
|
||||||
float y = 150 - (rInstrument+25)*cos(i/180.0*M_PI); // y-coordinate cots
|
float y = 150 - (rInstrument+25)*cos(i/180.0*pi); // y-coordinate cots
|
||||||
const char *ii = "";
|
const char *ii = "";
|
||||||
switch (i) {
|
switch (i)
|
||||||
case 0: ii="0"; break;
|
{
|
||||||
case 20 : ii="20"; break;
|
case 0: ii="0"; break;
|
||||||
case 40 : ii="40"; break;
|
case 20 : ii="20"; break;
|
||||||
case 60 : ii="60"; break;
|
case 40 : ii="40"; break;
|
||||||
case 300 : ii="60"; break;
|
case 60 : ii="60"; break;
|
||||||
case 320 : ii="40"; break;
|
case 300 : ii="60"; break;
|
||||||
case 340 : ii="20"; break;
|
case 320 : ii="40"; break;
|
||||||
default: break;
|
case 340 : ii="20"; break;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print text centered on position x, y
|
// Print text centered on position x, y
|
||||||
@@ -202,11 +203,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw sub scale with dots
|
// Draw sub scale with dots
|
||||||
float x1c = 200 + rInstrument*sin(i/180.0*M_PI);
|
float x1c = 200 + rInstrument*sin(i/180.0*pi);
|
||||||
float y1c = 150 - rInstrument*cos(i/180.0*M_PI);
|
float y1c = 150 - rInstrument*cos(i/180.0*pi);
|
||||||
getdisplay().fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor);
|
getdisplay().fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor);
|
||||||
float sinx=sin(i/180.0*M_PI);
|
float sinx=sin(i/180.0*pi);
|
||||||
float cosx=cos(i/180.0*M_PI);
|
float cosx=cos(i/180.0*pi);
|
||||||
|
|
||||||
// Draw sub scale with lines (two triangles)
|
// Draw sub scale with lines (two triangles)
|
||||||
if(i % 20 == 0){
|
if(i % 20 == 0){
|
||||||
@@ -228,17 +229,17 @@ public:
|
|||||||
// Draw mast position pointer
|
// Draw mast position pointer
|
||||||
float startwidth = 8; // Start width of pointer
|
float startwidth = 8; // Start width of pointer
|
||||||
|
|
||||||
// value1 = (2 * M_PI ) - value1; // Mirror coordiante system for pointer, keel and boat
|
// value1 = (2 * pi ) - value1; // Mirror coordiante system for pointer, keel and boat
|
||||||
|
|
||||||
if(valid1 == true || holdvalues == true || simulation == true){
|
if(valid1 == true || holdvalues == true || simulation == true){
|
||||||
float sinx=sin(value1 + M_PI);
|
float sinx=sin(value1 + pi);
|
||||||
float cosx=cos(value1 + M_PI);
|
float cosx=cos(value1 + pi);
|
||||||
// Normal pointer
|
// Normal pointer
|
||||||
// Pointer as triangle with center base 2*width
|
// Pointer as triangle with center base 2*width
|
||||||
float xx1 = -startwidth;
|
float xx1 = -startwidth;
|
||||||
float xx2 = startwidth;
|
float xx2 = startwidth;
|
||||||
float yy1 = -startwidth;
|
float yy1 = -startwidth;
|
||||||
float yy2 = -(rInstrument * 0.7);
|
float yy2 = -(rInstrument * 0.7);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
||||||
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
||||||
@@ -282,7 +283,7 @@ public:
|
|||||||
float xx1 = -startwidth;
|
float xx1 = -startwidth;
|
||||||
float xx2 = startwidth;
|
float xx2 = startwidth;
|
||||||
float yy1 = -startwidth;
|
float yy1 = -startwidth;
|
||||||
float yy2 = -(rInstrument - 15);
|
float yy2 = -(rInstrument - 15);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
||||||
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
#include "OBP60Extensions.h"
|
#include "OBP60Extensions.h"
|
||||||
#include "ConfigMenu.h"
|
|
||||||
#include "images/logo64.xbm"
|
#include "images/logo64.xbm"
|
||||||
#include <esp32/clk.h>
|
#include <esp32/clk.h>
|
||||||
#include "qrcode.h"
|
#include "qrcode.h"
|
||||||
@@ -26,377 +25,37 @@
|
|||||||
* Consists of some sub-pages with following content:
|
* Consists of some sub-pages with following content:
|
||||||
* 1. Hard and software information
|
* 1. Hard and software information
|
||||||
* 2. System settings
|
* 2. System settings
|
||||||
* 3. System configuration: running and NVRAM
|
* 3. NMEA2000 device list
|
||||||
* 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);
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class PageSystem : public Page
|
class PageSystem : public Page
|
||||||
{
|
{
|
||||||
private:
|
uint64_t chipid;
|
||||||
GwConfigHandler *config;
|
bool simulation;
|
||||||
GwLog *logger;
|
bool sdcard;
|
||||||
|
String buzzer_mode;
|
||||||
|
uint8_t buzzer_power;
|
||||||
|
String cpuspeed;
|
||||||
|
String rtc_module;
|
||||||
|
String gps_module;
|
||||||
|
String env_module;
|
||||||
|
|
||||||
// NVRAM config options
|
String batt_sensor;
|
||||||
String flashLED;
|
String solar_sensor;
|
||||||
|
String gen_sensor;
|
||||||
|
String rot_sensor;
|
||||||
|
double homelat;
|
||||||
|
double homelon;
|
||||||
|
|
||||||
// Generic data access
|
char mode = 'N'; // (N)ormal, (S)ettings, (D)evice list, (C)ard
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageSystem(CommonData &common){
|
PageSystem(CommonData &common){
|
||||||
commonData = &common;
|
commonData = &common;
|
||||||
config = commonData->config;
|
common.logger->logDebug(GwLog::LOG,"Instantiate PageSystem");
|
||||||
logger = commonData->logger;
|
|
||||||
|
|
||||||
logger->logDebug(GwLog::LOG,"Instantiate PageSystem");
|
|
||||||
if (hasFRAM) {
|
if (hasFRAM) {
|
||||||
mode = fram.read(FRAM_SYSTEM_MODE);
|
mode = fram.read(FRAM_SYSTEM_MODE);
|
||||||
}
|
}
|
||||||
flashLED = common.config->getString(common.config->flashLED);
|
|
||||||
|
|
||||||
chipid = ESP.getEfuseMac();
|
chipid = ESP.getEfuseMac();
|
||||||
simulation = common.config->getBool(common.config->useSimuData);
|
simulation = common.config->getBool(common.config->useSimuData);
|
||||||
#ifdef BOARD_OBP40S3
|
#ifdef BOARD_OBP40S3
|
||||||
@@ -415,24 +74,6 @@ public:
|
|||||||
rot_sensor = common.config->getString(common.config->useRotSensor);
|
rot_sensor = common.config->getString(common.config->useRotSensor);
|
||||||
homelat = common.config->getString(common.config->homeLAT).toDouble();
|
homelat = common.config->getString(common.config->homeLAT).toDouble();
|
||||||
homelon = common.config->getString(common.config->homeLON).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(){
|
virtual void setupKeys(){
|
||||||
@@ -449,7 +90,19 @@ public:
|
|||||||
// Switch display mode
|
// Switch display mode
|
||||||
commonData->logger->logDebug(GwLog::LOG, "System keyboard handler");
|
commonData->logger->logDebug(GwLog::LOG, "System keyboard handler");
|
||||||
if (key == 2) {
|
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);
|
if (hasFRAM) fram.write(FRAM_SYSTEM_MODE, mode);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -473,13 +126,8 @@ public:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef BOARD_OBP40S3
|
#ifdef BOARD_OBP40S3
|
||||||
// use cursor keys for local mode navigation
|
// grab cursor keys to disable page navigation
|
||||||
if (key == 9) {
|
if (key == 9 or key == 10) {
|
||||||
incMode();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (key == 10) {
|
|
||||||
decMode();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// standby / deep sleep
|
// standby / deep sleep
|
||||||
@@ -520,35 +168,225 @@ public:
|
|||||||
GwConfigHandler *config = commonData->config;
|
GwConfigHandler *config = commonData->config;
|
||||||
GwLog *logger = commonData->logger;
|
GwLog *logger = commonData->logger;
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
String flashLED = config->getString(config->flashLED);
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
// Optical warning by limit violation (unused)
|
||||||
if(flashLED == "Limit Violation"){
|
if(String(flashLED) == "Limit Violation"){
|
||||||
setBlinkingLED(false);
|
setBlinkingLED(false);
|
||||||
setFlashLED(false);
|
setFlashLED(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logging page information
|
// Logging boat values
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageSystem, Mode=%c", mode);
|
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
|
// 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
|
if (mode == 'N') {
|
||||||
switch (mode) {
|
|
||||||
case 'N':
|
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
||||||
displayModeNormal();
|
getdisplay().setCursor(8, 48);
|
||||||
break;
|
getdisplay().print("System Information");
|
||||||
case 'S':
|
|
||||||
displayModeSettings();
|
getdisplay().drawXBitmap(320, 25, logo64_bits, logo64_width, logo64_height, commonData->fgcolor);
|
||||||
break;
|
|
||||||
case 'C':
|
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
||||||
displayModeConfig();
|
y0 = 155;
|
||||||
break;
|
|
||||||
case 'A':
|
char ssid[13];
|
||||||
displayModeSDCard();
|
snprintf(ssid, 13, "%04X%08X", (uint16_t)(chipid >> 32), (uint32_t)chipid);
|
||||||
break;
|
displayBarcode(String(ssid), 320, 200, 2);
|
||||||
case 'D':
|
getdisplay().setCursor(8, 70);
|
||||||
displayModeDevicelist();
|
getdisplay().print(String("MCUDEVICE-") + String(ssid));
|
||||||
break;
|
|
||||||
|
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
|
// Update display
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class PageThreeValues : public Page
|
|||||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values #2
|
// Get boat values #2
|
||||||
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list
|
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list (only one value by PageOneValue)
|
||||||
String name2 = xdrDelete(bvalue2->getName()); // Value name
|
String name2 = xdrDelete(bvalue2->getName()); // 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
|
||||||
@@ -61,7 +61,7 @@ class PageThreeValues : public Page
|
|||||||
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
|
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values #3
|
// Get boat values #3
|
||||||
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Third element in list
|
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue)
|
||||||
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
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class PageTwoValues : public Page
|
|||||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values #2
|
// Get boat values #2
|
||||||
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list
|
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list (only one value by PageOneValue)
|
||||||
String name2 = xdrDelete(bvalue2->getName()); // Value name
|
String name2 = xdrDelete(bvalue2->getName()); // 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
|
||||||
|
|||||||
@@ -398,11 +398,11 @@ static Page *createPage(CommonData &common){
|
|||||||
* 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 registerPageVoltage(
|
PageDescription registerPageVoltage(
|
||||||
"Voltage", // Name of page
|
"Voltage", // Name of page
|
||||||
createPage, // Action
|
createPage, // Action
|
||||||
0, // Number of bus values depends on selection in Web configuration
|
0, // Number of bus values depends on selection in Web configuration
|
||||||
{}, // Names of bus values undepends on selection in Web configuration (refer GwBoatData.h)
|
{}, // Names of bus values undepends on selection in Web configuration (refer GwBoatData.h)
|
||||||
true // Show display header on/off
|
true // Show display header on/off
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -633,11 +633,11 @@ static Page *createPage(CommonData &common){
|
|||||||
* 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 registerPageWind(
|
PageDescription registerPageWind(
|
||||||
"Wind", // Page name
|
"Wind", // Page name
|
||||||
createPage, // Action
|
createPage, // Action
|
||||||
0, // Number of bus values depends on selection in Web configuration
|
0, // Number of bus values depends on selection in Web configuration
|
||||||
{"AWS","AWA", "TWS", "TWA"}, // Bus values we need in the page
|
{"AWS","AWA", "TWS", "TWA"}, // Bus values we need in the page
|
||||||
true // Show display header on/off
|
true // Show display header on/off
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ public:
|
|||||||
// read boat data values; TWD only for validation test, TWS for display of current value
|
// read boat data values; TWD only for validation test, TWS for display of current value
|
||||||
for (int i = 0; i < numBoatData; i++) {
|
for (int i = 0; i < numBoatData; i++) {
|
||||||
bvalue = pageData.values[i];
|
bvalue = pageData.values[i];
|
||||||
BDataName[i] = xdrDelete(bvalue->getName());
|
// BDataName[i] = xdrDelete(bvalue->getName());
|
||||||
BDataName[i] = BDataName[i].substring(0, 6); // String length limit for value name
|
BDataName[i] = BDataName[i].substring(0, 6); // String length limit for value name
|
||||||
calibrationData.calibrateInstance(bvalue, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue, logger); // Check if boat data value is to be calibrated
|
||||||
BDataValue[i] = bvalue->value; // Value as double in SI unit
|
BDataValue[i] = bvalue->value; // Value as double in SI unit
|
||||||
@@ -326,13 +326,24 @@ public:
|
|||||||
chrtVal = static_cast<int>(pageData.boatHstry.twdHstry->get(bufStart + (i * dataIntv))); // show the latest wind values in buffer; keep 1st value constant in a rolling buffer
|
chrtVal = static_cast<int>(pageData.boatHstry.twdHstry->get(bufStart + (i * dataIntv))); // show the latest wind values in buffer; keep 1st value constant in a rolling buffer
|
||||||
if (chrtVal == INT16_MIN) {
|
if (chrtVal == INT16_MIN) {
|
||||||
chrtPrevVal = INT16_MIN;
|
chrtPrevVal = INT16_MIN;
|
||||||
|
/* if (i == linesToShow - 1) {
|
||||||
|
numNoData++;
|
||||||
|
// If more than 4 invalid values in a row, reset chart
|
||||||
|
} else {
|
||||||
|
numNoData = 0; // Reset invalid value counter
|
||||||
|
}
|
||||||
|
if (numNoData > 4) {
|
||||||
|
// If more than 4 invalid values in a row, send message
|
||||||
|
getdisplay().setFont(&Ubuntu_Bold10pt8b);
|
||||||
|
getdisplay().fillRect(xCenter - 66, height / 2 - 20, 146, 24, commonData->bgcolor); // Clear area for TWS value
|
||||||
|
drawTextCenter(xCenter, height / 2 - 10, "No sensor data");
|
||||||
|
} */
|
||||||
} else {
|
} else {
|
||||||
chrtVal = static_cast<int>((chrtVal / 1000.0 * radToDeg) + 0.5); // Convert to degrees and round
|
chrtVal = static_cast<int>((chrtVal / 1000.0 * radToDeg) + 0.5); // Convert to degrees and round
|
||||||
x = ((chrtVal - wndLeft + 360) % 360) * chrtScl;
|
x = ((chrtVal - wndLeft + 360) % 360) * chrtScl;
|
||||||
y = yOffset + cHeight - i; // Position in chart area
|
y = yOffset + cHeight - i; // Position in chart area
|
||||||
|
|
||||||
// if (i >= (numWndVals / dataIntv) - 10)
|
if (i >= (numWndVals / dataIntv) - 10)
|
||||||
if (i >= (numWndVals / dataIntv) - 1)
|
|
||||||
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Chart: i: %d, chrtVal: %d, bufStart: %d, count: %d, linesToShow: %d", i, chrtVal, bufStart, count, (numWndVals / dataIntv));
|
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Chart: i: %d, chrtVal: %d, bufStart: %d, count: %d, linesToShow: %d", i, chrtVal, bufStart, count, (numWndVals / dataIntv));
|
||||||
|
|
||||||
if ((i == 0) || (chrtPrevVal == INT16_MIN)) {
|
if ((i == 0) || (chrtPrevVal == INT16_MIN)) {
|
||||||
@@ -367,8 +378,7 @@ public:
|
|||||||
int minWndDir = pageData.boatHstry.twdHstry->getMin(numWndVals) / 1000.0 * radToDeg;
|
int minWndDir = pageData.boatHstry.twdHstry->getMin(numWndVals) / 1000.0 * radToDeg;
|
||||||
int maxWndDir = pageData.boatHstry.twdHstry->getMax(numWndVals) / 1000.0 * radToDeg;
|
int maxWndDir = pageData.boatHstry.twdHstry->getMax(numWndVals) / 1000.0 * radToDeg;
|
||||||
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot FreeTop: Minimum: %d, Maximum: %d, OldwndCenter: %d", minWndDir, maxWndDir, wndCenter);
|
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot FreeTop: Minimum: %d, Maximum: %d, OldwndCenter: %d", minWndDir, maxWndDir, wndCenter);
|
||||||
// if ((minWndDir + 540 >= wndCenter + 540) || (maxWndDir + 540 <= wndCenter + 540)) {
|
if ((minWndDir + 540 >= wndCenter + 540) || (maxWndDir + 540 <= wndCenter + 540)) {
|
||||||
if (((minWndDir - wndCenter >= 0) && (minWndDir - wndCenter < 180)) || ((maxWndDir - wndCenter <= 0) && (maxWndDir - wndCenter >=180))) {
|
|
||||||
// Check if all wind value are left or right of center value -> optimize chart range
|
// Check if all wind value are left or right of center value -> optimize chart range
|
||||||
midWndDir = pageData.boatHstry.twdHstry->getMid(numWndVals) / 1000.0 * radToDeg;
|
midWndDir = pageData.boatHstry.twdHstry->getMid(numWndVals) / 1000.0 * radToDeg;
|
||||||
if (midWndDir != INT16_MIN) {
|
if (midWndDir != INT16_MIN) {
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ 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 value for AWA
|
// Get boat values for AWA
|
||||||
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
||||||
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
||||||
name1 = name1.substring(0, 6); // String length limit for value name
|
name1 = name1.substring(0, 6); // String length limit for value name
|
||||||
@@ -63,8 +63,8 @@ public:
|
|||||||
unit1old = unit1; // Save old unit
|
unit1old = unit1; // Save old unit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get boat value for AWS
|
// Get boat values for AWS
|
||||||
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list
|
GwApi::BoatValue *bvalue2 = pageData.values[1]; // First element in list (only one value by PageOneValue)
|
||||||
String name2 = xdrDelete(bvalue2->getName()); // Value name
|
String name2 = xdrDelete(bvalue2->getName()); // 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
|
||||||
@@ -77,8 +77,8 @@ public:
|
|||||||
unit2old = unit2; // Save old unit
|
unit2old = unit2; // Save old unit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get boat value for TWD
|
// Get boat values TWD
|
||||||
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Third element in list
|
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue)
|
||||||
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
|
||||||
@@ -91,9 +91,9 @@ public:
|
|||||||
unit3old = unit3; // Save old unit
|
unit3old = unit3; // Save old unit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get boat value for TWS
|
// Get boat values TWS
|
||||||
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Fourth element in list
|
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Second element in list (only one value by PageOneValue)
|
||||||
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
|
||||||
@@ -105,9 +105,9 @@ public:
|
|||||||
unit4old = unit4; // Save old unit
|
unit4old = unit4; // Save old unit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get boat value for DBT
|
// Get boat values DBT
|
||||||
GwApi::BoatValue *bvalue5 = pageData.values[4]; // Fifth element in list
|
GwApi::BoatValue *bvalue5 = pageData.values[4]; // Second element in list (only one value by PageOneValue)
|
||||||
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
|
||||||
@@ -119,9 +119,9 @@ public:
|
|||||||
unit5old = unit5; // Save old unit
|
unit5old = unit5; // Save old unit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get boat value for STW
|
// Get boat values STW
|
||||||
GwApi::BoatValue *bvalue6 = pageData.values[5]; // Sixth element in list
|
GwApi::BoatValue *bvalue6 = pageData.values[5]; // Second element in list (only one value by PageOneValue)
|
||||||
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
|
||||||
@@ -248,7 +248,7 @@ public:
|
|||||||
float y = 150 - (rInstrument-30)*cos(i/180.0*pi); // y-coordinate cots
|
float y = 150 - (rInstrument-30)*cos(i/180.0*pi); // y-coordinate cots
|
||||||
const char *ii = "";
|
const char *ii = "";
|
||||||
switch (i)
|
switch (i)
|
||||||
{
|
{
|
||||||
case 0: ii="0"; break;
|
case 0: ii="0"; break;
|
||||||
case 30 : ii="30"; break;
|
case 30 : ii="30"; break;
|
||||||
case 60 : ii="60"; break;
|
case 60 : ii="60"; break;
|
||||||
@@ -372,11 +372,11 @@ static Page *createPage(CommonData &common){
|
|||||||
* 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 registerPageWindRose(
|
PageDescription registerPageWindRose(
|
||||||
"WindRose", // Page name
|
"WindRose", // Page name
|
||||||
createPage, // Action
|
createPage, // Action
|
||||||
0, // Number of bus values depends on selection in Web configuration
|
0, // Number of bus values depends on selection in Web configuration
|
||||||
{"AWA", "AWS", "TWD", "TWS", "DBT", "STW"}, // Bus values we need in the page
|
{"AWA", "AWS", "TWD", "TWS", "DBT", "STW"}, // Bus values we need in the page
|
||||||
true // Show display header on/off
|
true // Show display header on/off
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ 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
|
// Get boat values for AWA
|
||||||
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
||||||
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
||||||
name1 = name1.substring(0, 6); // String length limit for value name
|
name1 = name1.substring(0, 6); // String length limit for value name
|
||||||
@@ -63,13 +63,13 @@ public:
|
|||||||
unit1old = unit1; // Save old unit
|
unit1old = unit1; // Save old unit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get boat values #2
|
// Get boat values for AWS
|
||||||
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list
|
GwApi::BoatValue *bvalue2 = pageData.values[1]; // First element in list (only one value by PageOneValue)
|
||||||
String name2 = xdrDelete(bvalue2->getName()); // Value name
|
String name2 = xdrDelete(bvalue2->getName()); // 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
|
||||||
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){
|
||||||
@@ -77,13 +77,13 @@ public:
|
|||||||
unit2old = unit2; // Save old unit
|
unit2old = unit2; // Save old unit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get boat values #3
|
// Get boat values TWD
|
||||||
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Third element in list
|
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue)
|
||||||
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 +91,13 @@ public:
|
|||||||
unit3old = unit3; // Save old unit
|
unit3old = unit3; // Save old unit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get boat values #4
|
// Get boat values TWS
|
||||||
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Fourth element in list
|
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Second element in list (only one value by PageOneValue)
|
||||||
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 +105,13 @@ public:
|
|||||||
unit4old = unit4; // Save old unit
|
unit4old = unit4; // Save old unit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get boat values #5
|
// Get boat values DBT
|
||||||
GwApi::BoatValue *bvalue5 = pageData.values[4]; // Fifth element in list
|
GwApi::BoatValue *bvalue5 = pageData.values[4]; // Second element in list (only one value by PageOneValue)
|
||||||
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 +119,13 @@ public:
|
|||||||
unit5old = unit5; // Save old unit
|
unit5old = unit5; // Save old unit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get boat values #5
|
// Get boat values STW
|
||||||
GwApi::BoatValue *bvalue6 = pageData.values[5]; // Sixth element in list
|
GwApi::BoatValue *bvalue6 = pageData.values[5]; // Second element in list (only one value by PageOneValue)
|
||||||
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){
|
||||||
@@ -136,7 +136,7 @@ public:
|
|||||||
// 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);
|
||||||
setFlashLED(false);
|
setFlashLED(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logging boat values
|
// Logging boat values
|
||||||
@@ -192,7 +192,7 @@ public:
|
|||||||
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(abs(value3 * 180 / PI), 0); // Value
|
||||||
getdisplay().print(svalue4); // Value
|
getdisplay().print(svalue4); // Value
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@@ -227,15 +227,16 @@ public:
|
|||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit5); // Unit
|
getdisplay().print(unit5); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit5old); // Unit
|
getdisplay().print(unit5old); // Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//*******************************************************************************************
|
//*******************************************************************************************
|
||||||
|
|
||||||
// Draw wind rose
|
// Draw wind rose
|
||||||
int rInstrument = 110; // Radius of grafic instrument
|
int rInstrument = 110; // Radius of grafic instrument
|
||||||
|
float pi = 3.141592;
|
||||||
|
|
||||||
getdisplay().fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle
|
getdisplay().fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle
|
||||||
getdisplay().fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle
|
getdisplay().fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle
|
||||||
@@ -245,23 +246,24 @@ public:
|
|||||||
for(int i=0; i<360; i=i+10)
|
for(int i=0; i<360; i=i+10)
|
||||||
{
|
{
|
||||||
// Scaling values
|
// Scaling values
|
||||||
float x = 200 + (rInstrument-30)*sin(i/180.0*M_PI); // x-coordinate dots
|
float x = 200 + (rInstrument-30)*sin(i/180.0*pi); // x-coordinate dots
|
||||||
float y = 150 - (rInstrument-30)*cos(i/180.0*M_PI); // y-coordinate dots
|
float y = 150 - (rInstrument-30)*cos(i/180.0*pi); // y-coordinate dots
|
||||||
const char *ii = "";
|
const char *ii = "";
|
||||||
switch (i) {
|
switch (i)
|
||||||
case 0: ii="0"; break;
|
{
|
||||||
case 30 : ii="30"; break;
|
case 0: ii="0"; break;
|
||||||
case 60 : ii="60"; break;
|
case 30 : ii="30"; break;
|
||||||
case 90 : ii="90"; break;
|
case 60 : ii="60"; break;
|
||||||
case 120 : ii="120"; break;
|
case 90 : ii="90"; break;
|
||||||
case 150 : ii="150"; break;
|
case 120 : ii="120"; break;
|
||||||
case 180 : ii="180"; break;
|
case 150 : ii="150"; break;
|
||||||
case 210 : ii="210"; break;
|
case 180 : ii="180"; break;
|
||||||
case 240 : ii="240"; break;
|
case 210 : ii="210"; break;
|
||||||
case 270 : ii="270"; break;
|
case 240 : ii="240"; break;
|
||||||
case 300 : ii="300"; break;
|
case 270 : ii="270"; break;
|
||||||
case 330 : ii="330"; break;
|
case 300 : ii="300"; break;
|
||||||
default: break;
|
case 330 : ii="330"; break;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print text centered on position x, y
|
// Print text centered on position x, y
|
||||||
@@ -275,11 +277,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw sub scale with dots
|
// Draw sub scale with dots
|
||||||
float x1c = 200 + rInstrument*sin(i/180.0*M_PI);
|
float x1c = 200 + rInstrument*sin(i/180.0*pi);
|
||||||
float y1c = 150 - rInstrument*cos(i/180.0*M_PI);
|
float y1c = 150 - rInstrument*cos(i/180.0*pi);
|
||||||
getdisplay().fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor);
|
getdisplay().fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor);
|
||||||
float sinx=sin(i/180.0*M_PI);
|
float sinx=sin(i/180.0*pi);
|
||||||
float cosx=cos(i/180.0*M_PI);
|
float cosx=cos(i/180.0*pi);
|
||||||
|
|
||||||
// Draw sub scale with lines (two triangles)
|
// Draw sub scale with lines (two triangles)
|
||||||
if(i % 30 == 0){
|
if(i % 30 == 0){
|
||||||
@@ -307,7 +309,7 @@ public:
|
|||||||
float xx1 = -startwidth;
|
float xx1 = -startwidth;
|
||||||
float xx2 = startwidth;
|
float xx2 = startwidth;
|
||||||
float yy1 = -startwidth;
|
float yy1 = -startwidth;
|
||||||
float yy2 = -(rInstrument-15);
|
float yy2 = -(rInstrument-15);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
||||||
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
||||||
@@ -329,26 +331,36 @@ public:
|
|||||||
|
|
||||||
//*******************************************************************************************
|
//*******************************************************************************************
|
||||||
|
|
||||||
// Show value6, so that it does not collide with the wind pointer
|
// Show value6, so that it does 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){
|
}
|
||||||
getdisplay().print(unit6); // Unit
|
else{
|
||||||
}
|
getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b);
|
||||||
else{
|
getdisplay().setCursor(160, 130);
|
||||||
getdisplay().print(unit6old); // Unit
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return PAGE_UPDATE;
|
return PAGE_UPDATE;
|
||||||
};
|
};
|
||||||
@@ -365,10 +377,11 @@ static Page *createPage(CommonData &common){
|
|||||||
* 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
|
6, // Number of bus values depends on selection in Web configuration; was zero
|
||||||
true // Show display header on/off
|
//{"AWA", "AWS", "COG", "SOG", "TWD", "TWS"}, // Bus values we need in the page, modified for WindRose2
|
||||||
|
true // Show display header on/off
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -223,11 +223,11 @@ static Page* createPage(CommonData &common){
|
|||||||
* this will be number of BoatValue pointers in pageData.values
|
* this will be number of BoatValue pointers in pageData.values
|
||||||
*/
|
*/
|
||||||
PageDescription registerPageXTETrack(
|
PageDescription registerPageXTETrack(
|
||||||
"XTETrack", // Page name
|
"XTETrack", // Page name
|
||||||
createPage, // Action
|
createPage, // Action
|
||||||
0, // Number of bus values depends on selection in Web configuration
|
0, // Number of bus values depends on selection in Web configuration
|
||||||
{"XTE", "COG", "DTW", "BTW"}, // Bus values we need in the page
|
{"XTE", "COG", "DTW", "BTW"}, // Bus values we need in the page
|
||||||
true // Show display header on/off
|
true // Show display header on/off
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ typedef struct{
|
|||||||
double value;
|
double value;
|
||||||
String svalue;
|
String svalue;
|
||||||
String unit;
|
String unit;
|
||||||
} FormattedData;
|
} FormatedData;
|
||||||
|
|
||||||
// Formatter for boat values
|
// Formatter for boat values
|
||||||
FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata);
|
FormatedData formatValue(GwApi::BoatValue *value, CommonData &commondata);
|
||||||
|
|||||||
@@ -75,6 +75,20 @@
|
|||||||
"obp60":"true"
|
"obp60":"true"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "chainLength",
|
||||||
|
"label": "Anchor Chain Length [m]",
|
||||||
|
"type": "number",
|
||||||
|
"default": 0,
|
||||||
|
"check": "checkMinMax",
|
||||||
|
"min": 0,
|
||||||
|
"max": 255,
|
||||||
|
"description": "The length of the anchor chain [0...255m]",
|
||||||
|
"category": "OBP60 Settings",
|
||||||
|
"capabilities": {
|
||||||
|
"obp60":"true"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "fuelTank",
|
"name": "fuelTank",
|
||||||
"label": "Fuel Tank [l]",
|
"label": "Fuel Tank [l]",
|
||||||
@@ -1303,6 +1317,7 @@
|
|||||||
"default": "Voltage",
|
"default": "Voltage",
|
||||||
"description": "Type of page for page 1",
|
"description": "Type of page for page 1",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
@@ -1584,6 +1599,7 @@
|
|||||||
"default": "WindRose",
|
"default": "WindRose",
|
||||||
"description": "Type of page for page 2",
|
"description": "Type of page for page 2",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
@@ -1862,6 +1878,7 @@
|
|||||||
"default": "OneValue",
|
"default": "OneValue",
|
||||||
"description": "Type of page for page 3",
|
"description": "Type of page for page 3",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
@@ -2137,6 +2154,7 @@
|
|||||||
"default": "TwoValues",
|
"default": "TwoValues",
|
||||||
"description": "Type of page for page 4",
|
"description": "Type of page for page 4",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
@@ -2409,6 +2427,7 @@
|
|||||||
"default": "ThreeValues",
|
"default": "ThreeValues",
|
||||||
"description": "Type of page for page 5",
|
"description": "Type of page for page 5",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
@@ -2678,6 +2697,7 @@
|
|||||||
"default": "FourValues",
|
"default": "FourValues",
|
||||||
"description": "Type of page for page 6",
|
"description": "Type of page for page 6",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
@@ -2944,6 +2964,7 @@
|
|||||||
"default": "FourValues2",
|
"default": "FourValues2",
|
||||||
"description": "Type of page for page 7",
|
"description": "Type of page for page 7",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
@@ -3207,6 +3228,7 @@
|
|||||||
"default": "Clock",
|
"default": "Clock",
|
||||||
"description": "Type of page for page 8",
|
"description": "Type of page for page 8",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
@@ -3467,6 +3489,7 @@
|
|||||||
"default": "RollPitch",
|
"default": "RollPitch",
|
||||||
"description": "Type of page for page 9",
|
"description": "Type of page for page 9",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
@@ -3724,6 +3747,7 @@
|
|||||||
"default": "Battery2",
|
"default": "Battery2",
|
||||||
"description": "Type of page for page 10",
|
"description": "Type of page for page 10",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
|
|||||||
@@ -75,6 +75,20 @@
|
|||||||
"obp40": "true"
|
"obp40": "true"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "chainLength",
|
||||||
|
"label": "Anchor Chain Length [m]",
|
||||||
|
"type": "number",
|
||||||
|
"default": "0",
|
||||||
|
"check": "checkMinMax",
|
||||||
|
"min": 0,
|
||||||
|
"max": 255,
|
||||||
|
"description": "The length of the anchor chain [0...255m]",
|
||||||
|
"category": "OBP40 Settings",
|
||||||
|
"capabilities": {
|
||||||
|
"obp40":"true"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "fuelTank",
|
"name": "fuelTank",
|
||||||
"label": "Fuel Tank [l]",
|
"label": "Fuel Tank [l]",
|
||||||
@@ -1326,6 +1340,7 @@
|
|||||||
"default": "Clock",
|
"default": "Clock",
|
||||||
"description": "Type of page for page 1",
|
"description": "Type of page for page 1",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
@@ -1607,6 +1622,7 @@
|
|||||||
"default": "Wind",
|
"default": "Wind",
|
||||||
"description": "Type of page for page 2",
|
"description": "Type of page for page 2",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
@@ -1885,6 +1901,7 @@
|
|||||||
"default": "OneValue",
|
"default": "OneValue",
|
||||||
"description": "Type of page for page 3",
|
"description": "Type of page for page 3",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
@@ -2160,6 +2177,7 @@
|
|||||||
"default": "TwoValues",
|
"default": "TwoValues",
|
||||||
"description": "Type of page for page 4",
|
"description": "Type of page for page 4",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
@@ -2432,6 +2450,7 @@
|
|||||||
"default": "ThreeValues",
|
"default": "ThreeValues",
|
||||||
"description": "Type of page for page 5",
|
"description": "Type of page for page 5",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
@@ -2701,6 +2720,7 @@
|
|||||||
"default": "FourValues",
|
"default": "FourValues",
|
||||||
"description": "Type of page for page 6",
|
"description": "Type of page for page 6",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
@@ -2967,6 +2987,7 @@
|
|||||||
"default": "FourValues2",
|
"default": "FourValues2",
|
||||||
"description": "Type of page for page 7",
|
"description": "Type of page for page 7",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
@@ -3230,6 +3251,7 @@
|
|||||||
"default": "Fluid",
|
"default": "Fluid",
|
||||||
"description": "Type of page for page 8",
|
"description": "Type of page for page 8",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
@@ -3490,6 +3512,7 @@
|
|||||||
"default": "RollPitch",
|
"default": "RollPitch",
|
||||||
"description": "Type of page for page 9",
|
"description": "Type of page for page 9",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
@@ -3747,6 +3770,7 @@
|
|||||||
"default": "Battery2",
|
"default": "Battery2",
|
||||||
"description": "Type of page for page 10",
|
"description": "Type of page for page 10",
|
||||||
"list": [
|
"list": [
|
||||||
|
"Anchor",
|
||||||
"BME280",
|
"BME280",
|
||||||
"Battery",
|
"Battery",
|
||||||
"Battery2",
|
"Battery2",
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ no_of_fields_per_page = {
|
|||||||
"WindPlot": 0,
|
"WindPlot": 0,
|
||||||
"WindRose": 0,
|
"WindRose": 0,
|
||||||
"WindRoseFlex": 6,
|
"WindRoseFlex": 6,
|
||||||
|
"Anchor", 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# No changes needed beyond this point
|
# No changes needed beyond this point
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
#include "OBPDataOperations.h" // Functions lib for data operations such as true wind calculation
|
#include "OBPDataOperations.h" // Functions lib for data operations such as true wind calculation
|
||||||
|
|
||||||
#ifdef BOARD_OBP40S3
|
#ifdef BOARD_OBP40S3
|
||||||
#include "driver/rtc_io.h" // Needs for weakup from deep sleep
|
#include "driver/rtc_io.h" // Needs for wakeup from deep sleep
|
||||||
#include <FS.h> // SD-Card access
|
#include <FS.h> // SD-Card access
|
||||||
#include <SD.h>
|
#include <SD.h>
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
@@ -54,13 +54,31 @@ void OBP60Init(GwApi *api){
|
|||||||
|
|
||||||
// Check I2C devices
|
// Check I2C devices
|
||||||
|
|
||||||
|
|
||||||
// Init hardware
|
// Init hardware
|
||||||
hardwareInit(api);
|
hardwareInit(api);
|
||||||
|
|
||||||
// Init power
|
// Init power rail 5.0V
|
||||||
String powermode = api->getConfig()->getConfigItem(api->getConfig()->powerMode,true)->asString();
|
String powermode = api->getConfig()->getConfigItem(api->getConfig()->powerMode,true)->asString();
|
||||||
api->getLogger()->logDebug(GwLog::DEBUG,"Power Mode is: %s", powermode.c_str());
|
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
|
#ifdef BOARD_OBP40S3
|
||||||
bool sdcard = config->getBool(config->useSDCard);
|
bool sdcard = config->getBool(config->useSDCard);
|
||||||
@@ -295,6 +313,8 @@ void registerAllPages(PageList &list){
|
|||||||
list.add(®isterPageXTETrack);
|
list.add(®isterPageXTETrack);
|
||||||
extern PageDescription registerPageFluid;
|
extern PageDescription registerPageFluid;
|
||||||
list.add(®isterPageFluid);
|
list.add(®isterPageFluid);
|
||||||
|
extern PageDescription registerPageAnchor;
|
||||||
|
list.add(®isterPageAnchor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Undervoltage detection for shutdown display
|
// Undervoltage detection for shutdown display
|
||||||
@@ -386,9 +406,10 @@ bool addTrueWind(GwApi* api, BoatValueList* boatValues) {
|
|||||||
hdtVal = hdtBVal->valid ? hdtBVal->value : DBL_MIN;
|
hdtVal = hdtBVal->valid ? hdtBVal->value : DBL_MIN;
|
||||||
hdmVal = hdmBVal->valid ? hdmBVal->value : DBL_MIN;
|
hdmVal = hdmBVal->valid ? hdmBVal->value : DBL_MIN;
|
||||||
varVal = varBVal->valid ? varBVal->value : DBL_MIN;
|
varVal = varBVal->valid ? varBVal->value : DBL_MIN;
|
||||||
api->getLogger()->logDebug(GwLog::DEBUG,"obp60task addTrueWind: AWA %.1f, AWS %.1f, COG %.1f, STW %.1f, SOG %.1f, HDT %.1f, HDM %.1f, VAR %.1f", awaBVal->value * RAD_TO_DEG, awsBVal->value * 3.6 / 1.852,
|
api->getLogger()->logDebug(GwLog::DEBUG,"obp60task addTrueWind: AWA: %.1f, AWS: %.1f, COG: %.1f, STW: %.1f, HDT: %.1f, HDM: %.1f, VAR: %.1f", awaBVal->value * RAD_TO_DEG, awsBVal->value * 3.6 / 1.852,
|
||||||
cogBVal->value * RAD_TO_DEG, stwBVal->value * 3.6 / 1.852, sogBVal->value * 3.6 / 1.852, hdtBVal->value * RAD_TO_DEG, hdmBVal->value * RAD_TO_DEG, varBVal->value * RAD_TO_DEG);
|
cogBVal->value * RAD_TO_DEG, stwBVal->value * 3.6 / 1.852, hdtBVal->value * RAD_TO_DEG, hdmBVal->value * RAD_TO_DEG, varBVal->value * RAD_TO_DEG);
|
||||||
|
|
||||||
|
// isCalculated = WindUtils::calcTrueWind(&awaVal, &awsVal, &cogVal, &stwVal, &sogVal, &hdtVal, &hdmVal, &varVal, &twdBVal->value, &twsBVal->value, &twaBVal->value);
|
||||||
isCalculated = WindUtils::calcTrueWind(&awaVal, &awsVal, &cogVal, &stwVal, &sogVal, &hdtVal, &hdmVal, &varVal, &twd, &tws, &twa);
|
isCalculated = WindUtils::calcTrueWind(&awaVal, &awsVal, &cogVal, &stwVal, &sogVal, &hdtVal, &hdmVal, &varVal, &twd, &tws, &twa);
|
||||||
|
|
||||||
if (isCalculated) { // Replace values only, if successfully calculated and not already available
|
if (isCalculated) { // Replace values only, if successfully calculated and not already available
|
||||||
@@ -405,8 +426,8 @@ bool addTrueWind(GwApi* api, BoatValueList* boatValues) {
|
|||||||
twaBVal->valid = true;
|
twaBVal->valid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
api->getLogger()->logDebug(GwLog::DEBUG,"obp60task addTrueWind: TWD_Valid %d, isCalculated %d, TWD %.1f, TWA %.1f, TWS %.1f", twdBVal->valid, isCalculated, twdBVal->value * RAD_TO_DEG,
|
api->getLogger()->logDebug(GwLog::DEBUG,"obp60task calcTrueWind: TWD_Valid? %d, TWD=%.1f, TWS=%.1f, TWA=%.1f, isCalculated? %d", twdBVal->valid, twdBVal->value * RAD_TO_DEG, twsBVal->value * 3.6 / 1.852,
|
||||||
twaBVal->value * RAD_TO_DEG, twsBVal->value * 3.6 / 1.852);
|
twaBVal->value * RAD_TO_DEG, isCalculated);
|
||||||
|
|
||||||
return isCalculated;
|
return isCalculated;
|
||||||
}
|
}
|
||||||
@@ -445,8 +466,8 @@ void handleHstryBuf(GwApi* api, BoatValueList* boatValues, tBoatHstryData hstryB
|
|||||||
GwApi::BoatValue *twsBVal = boatValues->findValueOrCreate(hstryBufList.twsHstry->getName());
|
GwApi::BoatValue *twsBVal = boatValues->findValueOrCreate(hstryBufList.twsHstry->getName());
|
||||||
GwApi::BoatValue *twaBVal = boatValues->findValueOrCreate("TWA");
|
GwApi::BoatValue *twaBVal = boatValues->findValueOrCreate("TWA");
|
||||||
|
|
||||||
api->getLogger()->logDebug(GwLog::DEBUG,"obp60task handleHstryBuf: twdBVal: %.1f, twaBVal: %.1f, twsBVal: %.1f, TWD_isValid? %d", twdBVal->value * RAD_TO_DEG,
|
api->getLogger()->logDebug(GwLog::DEBUG,"obp60task handleHstryBuf: twdBVal: %f, twsBVal: %f, twaBVal: %f, TWD_isValid? %d", twdBVal->value * RAD_TO_DEG,
|
||||||
twaBVal->value * RAD_TO_DEG, twsBVal->value * 3.6 / 1.852, twdBVal->valid);
|
twsBVal->value * 3.6 / 1.852, twaBVal->value * RAD_TO_DEG, twdBVal->valid);
|
||||||
calBVal = new GwApi::BoatValue("TWD"); // temporary solution for calibration of history buffer values
|
calBVal = new GwApi::BoatValue("TWD"); // temporary solution for calibration of history buffer values
|
||||||
calBVal->setFormat(twdBVal->getFormat());
|
calBVal->setFormat(twdBVal->getFormat());
|
||||||
if (twdBVal->valid) {
|
if (twdBVal->valid) {
|
||||||
|
|||||||
Reference in New Issue
Block a user