Compare commits

...

4 Commits

18 changed files with 2263 additions and 2117 deletions

View File

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

View File

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

View File

@ -58,6 +58,7 @@ class GwBoatItemBase{
GWSC(formatRot); GWSC(formatRot);
GWSC(formatDate); GWSC(formatDate);
GWSC(formatTime); GWSC(formatTime);
GWSC(formatName);
protected: protected:
int type; int type;
unsigned long lastSet=0; unsigned long lastSet=0;
@ -120,7 +121,13 @@ template<class T> class GwBoatItem : public GwBoatItemBase{
if (! isValid(millis())) return defaultv; if (! isValid(millis())) return defaultv;
return data; 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 fillString();
virtual void toJsonDoc(GwJsonDocument *doc, unsigned long minTime); virtual void toJsonDoc(GwJsonDocument *doc, unsigned long minTime);
virtual int getLastSource(){return lastUpdateSource;} virtual int getLastSource(){return lastUpdateSource;}
@ -235,6 +242,7 @@ class GwBoatData{
GWBOATDATA(double,XTE,formatXte) // cross track error GWBOATDATA(double,XTE,formatXte) // cross track error
GWBOATDATA(double,WPLat,formatLatitude) // waypoint latitude GWBOATDATA(double,WPLat,formatLatitude) // waypoint latitude
GWBOATDATA(double,WPLon,formatLongitude) // waypoint longitude GWBOATDATA(double,WPLon,formatLongitude) // waypoint longitude
GWBOATDATA(String,WPName,formatName) // waypoint name
GWSPECBOATDATA(GwBoatDataSatList,SatInfo,GwSatInfoList::toType,formatFixed0); GWSPECBOATDATA(GwBoatDataSatList,SatInfo,GwSatInfoList::toType,formatFixed0);
public: public:
GwBoatData(GwLog *logger, GwConfigHandler *cfg); 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(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 // Show status info
epd->setTextColor(commonData.fgcolor); epd->setTextColor(commonData.fgcolor);
epd->setFont(&Ubuntu_Bold8pt8b); epd->setFont(&Ubuntu_Bold8pt8b);

View File

@ -3,7 +3,6 @@
#include "Pagedata.h" #include "Pagedata.h"
#include "OBP60Extensions.h" #include "OBP60Extensions.h"
#include "ConfigMenu.h"
/* /*
AIS Overview AIS Overview
@ -12,6 +11,9 @@
- perhaps collision alarm - perhaps collision alarm
Data: LAT LON SOG HDT Data: LAT LON SOG HDT
Feature possibilities
- switch between North up / Heading up
*/ */
class PageAIS : public Page class PageAIS : public Page
@ -31,9 +33,6 @@ private:
int alarm_range = 3; int alarm_range = 3;
char mode = 'N'; // (N)ormal, (C)onfig char mode = 'N'; // (N)ormal, (C)onfig
int8_t editmode = -1; // marker for menu/edit/set function
ConfigMenu *menu;
void displayModeNormal(PageData &pageData) { void displayModeNormal(PageData &pageData) {
@ -98,21 +97,8 @@ public:
flashLED = config->getString(config->flashLED); flashLED = config->getString(config->flashLED);
backlightMode = config->getString(config->backlight); 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(){ void setupKeys(){

View File

@ -3,7 +3,6 @@
#include "Pagedata.h" #include "Pagedata.h"
#include "OBP60Extensions.h" #include "OBP60Extensions.h"
#include "ConfigMenu.h"
/* /*
Autopilot Autopilot
@ -21,9 +20,6 @@ private:
String backlightMode; String backlightMode;
char mode = 'N'; // (N)ormal, (C)onfig char mode = 'N'; // (N)ormal, (C)onfig
int8_t editmode = -1; // marker for menu/edit/set function
ConfigMenu *menu;
void displayModeNormal(PageData &pageData) { void displayModeNormal(PageData &pageData) {
@ -142,11 +138,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 registerPageAutopilot( PageDescription registerPageAutopilot(
"Autopilot", // Page name "Autopilot", // 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
{}, // 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 false // Show display header on/off
); );
#endif #endif

View File

@ -7,6 +7,7 @@
#include "images/logo64.xbm" #include "images/logo64.xbm"
#include <esp32/clk.h> #include <esp32/clk.h>
#include "qrcode.h" #include "qrcode.h"
#include "Nmea2kTwai.h"
#ifdef BOARD_OBP40S3 #ifdef BOARD_OBP40S3
#include <SD.h> #include <SD.h>
@ -530,6 +531,10 @@ public:
// Logging page information // Logging page information
LOG_DEBUG(GwLog::LOG,"Drawing at PageSystem, Mode=%c", mode); 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 // Set display in partial refresh mode
epd->setPartialWindow(0, 0, epd->width(), epd->height()); epd->setPartialWindow(0, 0, epd->width(), epd->height());

View File

@ -14,6 +14,7 @@
typedef std::vector<GwApi::BoatValue *> ValueList; typedef std::vector<GwApi::BoatValue *> ValueList;
typedef struct{ typedef struct{
GwApi *api;
String pageName; String pageName;
uint8_t pageNumber; // page number in sequence of visible pages uint8_t pageNumber; // page number in sequence of visible pages
//the values will always contain the user defined values first //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: 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 2. Set page name in PageXXXX.cpp on file name
3. Register new page in /lib/obp60task/obp60task.cpp in function 3. Register new page in /lib/obp60task/obp60task.cpp in function
'registerAllPages' 'registerAllPages'
4. Add new page in /lib/obp60task/config.json for each page type or add 4. Add new page in /lib/obp60task/config.json for each page type
new page to gen_set.py and run it to auto-generate the relevant or use gen_set.py to auto-generate the relevant section of
section of config.json 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 5. Copy the changes in config.json to config_obp40.json and rename
strings accordingly. E.g. obp60 to obp40. strings accordingly. E.g. obp60 to obp40.
Using Gitpod Using Gitpod
------------ ------------
Warning: You have to register with gitpod!
Open web page: Open web page:
https://gitpod.io/#https://github.com/norbert-walter/esp32-nmea2000-obp60/tree/master/lib/obp60task 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)]) env["CPPDEFINES"].extend([("BOARD", env["BOARD"]), ("EPDTYPE", epdtype), ("PCBVERS", pcbvers), ("GXEPD2VERS", gxepd2vers)])
print("added hardware info to CPPDEFINES") 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 re
import json import json
__version__ = "0.2" __version__ = "1.2"
def detect_pages(filename): def detect_pages(filename):
# returns a dictionary with page name and the number of gui fields # 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)), "description": "The display for field {}".format(number_to_text(field_no)),
"category": f"{device.upper()} Page {page_no}", "category": f"{device.upper()} Page {page_no}",
"capabilities": {device.lower(): "true"}, "capabilities": {device.lower(): "true"},
"condition": [ "condition": {
{f"page{page_no}type": page} f"page{page_no}type": [page for page in pages if pagedata[page] >= field_no],
for page in pages "visiblePages": [vp for vp in range(page_no, no_of_pages + 1)]
if pagedata[page] >= field_no },
],
} }
output.append(field_data) output.append(field_data)

View File

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

View File

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

View File

@ -216,6 +216,10 @@ public:
{ {
return api->getLogger(); return api->getLogger();
} }
virtual Nmea2kTwai *getNMEA2000()
{
return api->getNMEA2000();
}
virtual GwBoatData *getBoatData() virtual GwBoatData *getBoatData()
{ {
return api->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()); 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"); req->send(404, "text/plain", "not found");
} }

View File

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

View File

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