Compare commits

..

4 Commits

18 changed files with 2263 additions and 2117 deletions

View File

@ -2,6 +2,7 @@
#define _GWAPI_H
#include "GwMessage.h"
#include "N2kMsg.h"
#include "Nmea2kTwai.h"
#include "NMEA0183Msg.h"
#include "GWConfig.h"
#include "GwBoatData.h"
@ -222,6 +223,7 @@ class GwApi{
* accessing boat data must only be executed from within the main thread
* you need to use the request pattern as shown in GwExampleTask.cpp
*/
virtual Nmea2kTwai *getNMEA2000()=0;
virtual GwBoatData *getBoatData()=0;
virtual ~GwApi(){}
};

View File

@ -6,6 +6,7 @@
#define GWTYPE_UINT32 2
#define GWTYPE_UINT16 3
#define GWTYPE_INT16 4
#define GWTYPE_STRING 5
#define GWTYPE_USER 100
class GwBoatItemTypes
@ -15,6 +16,7 @@ public:
static int getType(const uint16_t &x) { return GWTYPE_UINT16; }
static int getType(const int16_t &x) { return GWTYPE_INT16; }
static int getType(const double &x) { return GWTYPE_DOUBLE; }
static int getType(const String &x) { return GWTYPE_STRING; }
static int getType(const GwSatInfoList &x) { return GWTYPE_USER + 1; }
};
@ -252,6 +254,10 @@ static void writeToString(GwTextWriter *writer, const int16_t &value)
{
writer->writeInteger(value);
}
static void writeToString(GwTextWriter *writer, String value)
{
writer->writeString(value.c_str());
}
static void writeToString(GwTextWriter *writer, GwSatInfoList &value)
{
writer->writeInteger(value.getNumSats());

View File

@ -58,6 +58,7 @@ class GwBoatItemBase{
GWSC(formatRot);
GWSC(formatDate);
GWSC(formatTime);
GWSC(formatName);
protected:
int type;
unsigned long lastSet=0;
@ -120,7 +121,13 @@ template<class T> class GwBoatItem : public GwBoatItemBase{
if (! isValid(millis())) return defaultv;
return data;
}
virtual double getDoubleValue(){return (double)data;}
virtual double getDoubleValue(){
if constexpr (std::is_same<T, String>::value) {
return 0.0; // TODO any better ideas?
} else {
return (double)data;
}
}
virtual void fillString();
virtual void toJsonDoc(GwJsonDocument *doc, unsigned long minTime);
virtual int getLastSource(){return lastUpdateSource;}
@ -235,6 +242,7 @@ class GwBoatData{
GWBOATDATA(double,XTE,formatXte) // cross track error
GWBOATDATA(double,WPLat,formatLatitude) // waypoint latitude
GWBOATDATA(double,WPLon,formatLongitude) // waypoint longitude
GWBOATDATA(String,WPName,formatName) // waypoint name
GWSPECBOATDATA(GwBoatDataSatList,SatInfo,GwSatInfoList::toType,formatFixed0);
public:
GwBoatData(GwLog *logger, GwConfigHandler *cfg);

View File

@ -461,12 +461,6 @@ void displayHeader(CommonData &commonData, bool symbolmode, GwApi::BoatValue *da
if(commonData.config->getBool(commonData.config->statusLine) == true){
if (symbolmode) {
commonData.logger->logDebug(GwLog::LOG,"Header: Symbolmode");
} else {
commonData.logger->logDebug(GwLog::LOG,"Header: Textmode");
}
// Show status info
epd->setTextColor(commonData.fgcolor);
epd->setFont(&Ubuntu_Bold8pt8b);

View File

@ -3,7 +3,6 @@
#include "Pagedata.h"
#include "OBP60Extensions.h"
#include "ConfigMenu.h"
/*
AIS Overview
@ -12,6 +11,9 @@
- perhaps collision alarm
Data: LAT LON SOG HDT
Feature possibilities
- switch between North up / Heading up
*/
class PageAIS : public Page
@ -31,9 +33,6 @@ private:
int alarm_range = 3;
char mode = 'N'; // (N)ormal, (C)onfig
int8_t editmode = -1; // marker for menu/edit/set function
ConfigMenu *menu;
void displayModeNormal(PageData &pageData) {
@ -98,21 +97,8 @@ public:
flashLED = config->getString(config->flashLED);
backlightMode = config->getString(config->backlight);
alarm_range = 30;
alarm_range = 3;
// Initialize config menu
/* menu = new ConfigMenu("Options", 40, 80);
menu->setItemDimension(150, 20);
ConfigMenuItem *newitem;
newitem = menu->addItem("range", "Range", "int", 4, "nm");
if (! newitem) {
// Demo: in case of failure exit here, should never be happen
logger->logDebug(GwLog::ERROR,"Menu item creation failed");
return;
}
newitem->setRange(0, 20, {1, 5});
menu->setItemActive("range"); */
}
void setupKeys(){

View File

@ -3,7 +3,6 @@
#include "Pagedata.h"
#include "OBP60Extensions.h"
#include "ConfigMenu.h"
/*
Autopilot
@ -21,9 +20,6 @@ private:
String backlightMode;
char mode = 'N'; // (N)ormal, (C)onfig
int8_t editmode = -1; // marker for menu/edit/set function
ConfigMenu *menu;
void displayModeNormal(PageData &pageData) {
@ -142,11 +138,11 @@ static Page *createPage(CommonData &common){
* this will be number of BoatValue pointers in pageData.values
*/
PageDescription registerPageAutopilot(
"Autopilot", // Page name
createPage, // Action
0, // Number of bus values depends on selection in Web configuration
{}, // Names of bus values undepends on selection in Web configuration (refer GwBoatData.h)
true // Show display header on/off
"Autopilot", // Page name
createPage, // Action
0, // Number of bus values depends on selection in Web configuration
{}, // Names of bus values undepends on selection in Web configuration (refer GwBoatData.h)
false // Show display header on/off
);
#endif

View File

@ -7,6 +7,7 @@
#include "images/logo64.xbm"
#include <esp32/clk.h>
#include "qrcode.h"
#include "Nmea2kTwai.h"
#ifdef BOARD_OBP40S3
#include <SD.h>
@ -530,6 +531,10 @@ public:
// Logging page information
LOG_DEBUG(GwLog::LOG,"Drawing at PageSystem, Mode=%c", mode);
// Get references from API
Nmea2kTwai *NMEA2000 = pageData.api->getNMEA2000();
LOG_DEBUG(GwLog::LOG,"N2k source address=%d", NMEA2000->GetN2kSource());
// Set display in partial refresh mode
epd->setPartialWindow(0, 0, epd->width(), epd->height());

View File

@ -14,6 +14,7 @@
typedef std::vector<GwApi::BoatValue *> ValueList;
typedef struct{
GwApi *api;
String pageName;
uint8_t pageNumber; // page number in sequence of visible pages
//the values will always contain the user defined values first

View File

@ -27,20 +27,23 @@ New pages
---------
To create a new page for OBP60 the following steps are necessary:
1. Create a page under /lib/obp60task/PageXXXX.cpp
1. Create a page under /lib/obp60task/PageXXXX.cpp. You can use a simple
page e.g. PageOneValue.cpp as template
2. Set page name in PageXXXX.cpp on file name
3. Register new page in /lib/obp60task/obp60task.cpp in function
'registerAllPages'
4. Add new page in /lib/obp60task/config.json for each page type or add
new page to gen_set.py and run it to auto-generate the relevant
section of config.json
4. Add new page in /lib/obp60task/config.json for each page type
or use gen_set.py to auto-generate the relevant section of
config.json. For further information on that read the comments
in gen_set.py.
5. Copy the changes in config.json to config_obp40.json and rename
strings accordingly. E.g. obp60 to obp40.
Using Gitpod
------------
Warning: You have to register with gitpod!
Open web page:
https://gitpod.io/#https://github.com/norbert-walter/esp32-nmea2000-obp60/tree/master/lib/obp60task

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -28,3 +28,4 @@ except:
env["CPPDEFINES"].extend([("BOARD", env["BOARD"]), ("EPDTYPE", epdtype), ("PCBVERS", pcbvers), ("GXEPD2VERS", gxepd2vers)])
print("added hardware info to CPPDEFINES")
print("friendly board name is '{}'".format(env.GetProjectOption("board_name")))

View File

@ -20,7 +20,7 @@ import getopt
import re
import json
__version__ = "0.2"
__version__ = "1.2"
def detect_pages(filename):
# returns a dictionary with page name and the number of gui fields
@ -110,11 +110,10 @@ def create_json(device, no_of_pages, pagedata):
"description": "The display for field {}".format(number_to_text(field_no)),
"category": f"{device.upper()} Page {page_no}",
"capabilities": {device.lower(): "true"},
"condition": [
{f"page{page_no}type": page}
for page in pages
if pagedata[page] >= field_no
],
"condition": {
f"page{page_no}type": [page for page in pages if pagedata[page] >= field_no],
"visiblePages": [vp for vp in range(page_no, no_of_pages + 1)]
},
}
output.append(field_data)

View File

@ -231,12 +231,13 @@ class PageList{
* each page should have defined a registerXXXPage variable of type
* PageData that describes what it needs
*/
void registerAllPages(PageList &list){
void registerAllPages(GwLog *logger, PageList &list){
//the next line says that this variable is defined somewhere else
//in our case in a separate C++ source file
//this way this separate source file can be compiled by it's own
//and has no access to any of our data except the one that we
//give as a parameter to the page function
logger->logDebug(GwLog::LOG, "Memory before registering pages: stack=%d, heap=%d", uxTaskGetStackHighWaterMark(NULL), ESP.getFreeHeap());
extern PageDescription registerPageSystem;
//we add the variable to our list
list.add(&registerPageSystem);
@ -294,12 +295,9 @@ void registerAllPages(PageList &list){
list.add(&registerPageSkyView);
extern PageDescription registerPageAnchor;
list.add(&registerPageAnchor);
/* extern PageDescription registerPageAIS;
extern PageDescription registerPageAIS;
list.add(&registerPageAIS);
extern PageDescription registerPageAutopilot;
list.add(&registerPageAutopilot);
extern PageDescription registerPageEPropulsion;
list.add(&registerPageEPropulsion); */
logger->logDebug(GwLog::LOG,"Memory after registering pages: stack=%d, heap=%d", uxTaskGetStackHighWaterMark(NULL), ESP.getFreeHeap());
}
// Undervoltage detection for shutdown display
@ -492,7 +490,7 @@ void OBP60Task(GwApi *api){
startLedTask(api);
#endif
PageList allPages;
registerAllPages(allPages);
registerAllPages(logger, allPages);
CommonData commonData;
commonData.logger=logger;
commonData.config=config;
@ -978,6 +976,7 @@ void OBP60Task(GwApi *api){
if (systemPage) {
displayFooter(commonData);
PageData sysparams; // empty
sysparams.api = api;
syspage->displayPage(sysparams);
}
else {

View File

@ -8,7 +8,6 @@ default_envs =
obp40_s3
[env:obp60_s3]
platform = espressif32@6.8.1
board_build.variants_dir = variants
#board = obp60_s3_n8 #ESP32-S3 N8, 8MB flash, no PSRAM
#board = obp60_s3_n16 #ESP32-S3 N16,16MB flash, no PSRAM, zero series
@ -16,6 +15,7 @@ board_build.variants_dir = variants
board = obp60_s3_n16r8 #ESP32-S3 N16R8, 16MB flash, 8MB PSRAM, production series
#board_build.partitions = default_8MB.csv #ESP32-S3 N8, 8MB flash
board_build.partitions = default_16MB.csv #ESP32-S3 N16, 16MB flash
board_name = OBP60
framework = arduino
lib_deps =
${basedeps.lib_deps}
@ -62,10 +62,10 @@ upload_speed = 230400
monitor_speed = 115200
[env:obp40_s3]
platform = espressif32@6.8.1
board_build.variants_dir = variants
board = obp40_s3_n8r8 #ESP32-S3 N8R8, 8MB flash, 8MB PSRAM, OBP60 clone (CrowPanel 4.2)
board_build.partitions = default_8MB.csv #ESP32-S3 N8, 8MB flash
board_name = OBP40
custom_config = config_obp40.json
framework = arduino
lib_deps =

View File

@ -216,6 +216,10 @@ public:
{
return api->getLogger();
}
virtual Nmea2kTwai *getNMEA2000()
{
return api->getNMEA2000();
}
virtual GwBoatData *getBoatData()
{
return api->getBoatData();
@ -428,4 +432,4 @@ void GwUserCode::handleWebRequest(const String &url,AsyncWebServerRequest *req){
}
LOG_DEBUG(GwLog::DEBUG,"no task found for web request %s[%s]",url.c_str(),tname.c_str());
req->send(404, "text/plain", "not found");
}
}

View File

@ -30,7 +30,7 @@ lib_deps =
Update
[env]
platform = espressif32 @ 6.8.1
platform = espressif32 @ 6.9.0
framework = arduino
;platform_packages=
; framework-arduinoespressif32 @ 3.20017.0
@ -56,6 +56,9 @@ lib_ldf_mode = off
monitor_speed = 115200
build_flags =
-D PIO_ENV_BUILD=$PIOENV
-std=gnu++17
build_unflags =
-std=gnu++11
[sensors]
; collect the libraries for sensors here

View File

@ -333,6 +333,9 @@ public:
status.n2kTx=countNMEA2KOut.getGlobal();
channels.fillStatus(status);
}
virtual Nmea2kTwai *getNMEA2000(){
return &NMEA2000;
}
virtual GwBoatData *getBoatData(){
return &boatData;
}