Compare commits

..

18 Commits

Author SHA1 Message Date
norbert-walter d1c620a858 Fix for compass page 2025-07-04 14:11:22 +02:00
norbert-walter 07a1b2388e Fix for voltage sensor OBP40 2025-07-03 22:41:12 +02:00
norbert-walter c614cae472 Change to actual extra_script.py 2025-07-03 19:41:27 +02:00
Norbert Walter ec7e1a35e7
Merge branch 'wellenvogel:master' into master 2025-07-03 19:39:16 +02:00
norbert-walter b82e94d716 Change back to old extra_script.py for sync with wellenvogel 2025-07-03 19:36:47 +02:00
wellenvogel d228f38461 update link to the newer version of the web installer 2025-05-02 17:58:26 +02:00
wellenvogel 417fe3db08 update link to the newer version of the web installer 2025-05-02 17:57:26 +02:00
andreas 44c9e998c9 rename dbs to dbt in convertDBKx for more code clearity 2025-04-28 18:42:16 +02:00
andreas c02122f253 #107: update doc 2025-04-22 19:43:23 +02:00
andreas 30ade0c07a Merge branch 'master' of github.com:wellenvogel/esp32-nmea2000 2025-04-22 19:39:15 +02:00
andreas 38d370dcfb #107: correctly handle DBT,DBS,DBK 2025-04-22 19:35:57 +02:00
wellenvogel 52a376c43a release docs for 20250305 2025-03-05 20:56:51 +01:00
wellenvogel 8c035c4ba1 #100: allow to set custom_config, custom_js, custom_css 2025-03-05 20:48:29 +01:00
wellenvogel 036add6feb #100: introduce extra_config, extra_js, extra_css as options in the environment 2025-03-05 19:49:46 +01:00
rowa-hooge a1f00dde82 Fix warning extra_script.py 2025-03-05 19:03:34 +01:00
rowa-hooge 756064a362 Fix warning NMEA0183DataToN2K.cpp
Also switch to more readable function names
2025-03-05 19:01:45 +01:00
rowa-hooge b640d1adda Fix warning GwSpiSensor.h 2025-03-05 19:00:24 +01:00
rowa-hooge c5cadce268 Fix deprecated warning in main.cpp 2025-03-05 18:59:09 +01:00
16 changed files with 230 additions and 192 deletions

View File

@ -68,12 +68,12 @@ Initial Flash
__Browser__
If you run a system with a modern Chrome or Edge Browser you can directly flash your device from within the browser.
Just go to the [Flash Page](https://wellenvogel.github.io/esp32-nmea2000/install.html) and select the "Initial" flash for your Hardware. This will install the most current software to your device.
Just go to the [Flash Page](https://wellenvogel.de/software/esp32/install.html) and select the "Initial" flash for your Hardware. This will install the most current software to your device. If you are using a forked project (like OBP60) refer to the documentation of the fork. You can just install any flash binary from your local computer with the browser based installation using the "upload" button.<br>
If you are on Windows you will need to have the correct driver installed before (see below at [windows users](#windows) - only install the driver, not the flashtool).
You can also install an update from the flash page but normally it is easier to do this from the Web Gui of the device (see [below](#update)).
The [Flash Page](https://wellenvogel.github.io/esp32-nmea2000/install.html) will also allow you to open a console window to your ESP32.
The [Flash Page](https://wellenvogel.de/software/esp32/install.html) will also allow you to open a console window to your ESP32.
__Tool based__
@ -170,6 +170,12 @@ For details refer to the [example description](lib/exampletask/Readme.md).
Changelog
---------
[20250305](../../releases/tag/20250305)
*********
* better handling for reconnect to a raspberry pi after reset [#102](../../issues/102)
* introduce _custom_config_, _custom_js_, _custom_css_, refer to [extending the core](lib/exampletask/Readme.md) [#100](../../pull/100)
* create VWR [#103](../../issues/103)
[20241128](../../releases/tag/20241128)
*********
* additional correction for: USB connection on S3 stops [#81](../../issues/81)

Binary file not shown.

Binary file not shown.

View File

@ -14,7 +14,7 @@ Files
* [platformio.ini](platformio.ini)<br>
This file is completely optional.
You only need this if you want to
extend the base configuration - we add a dummy library here and define one additional build environment (board)
extend the base configuration - we add a dummy library here and define additional build environments (boards)
* [GwExampleTask.h](GwExampleTask.h) the name of this include must match the name of the directory (ignoring case) with a "gw" in front. This file includes our special hardware definitions and registers our task at the core.<br>
This registration can be done statically using [DECLARE_USERTASK](https://github.com/wellenvogel/esp32-nmea2000/blob/9b955d135d74937a60f2926e8bfb9395585ff8cd/lib/api/GwApi.h#L202) in the header file. <br>
As an alternative we just only register an [initialization function](https://github.com/wellenvogel/esp32-nmea2000/blob/9b955d135d74937a60f2926e8bfb9395585ff8cd/lib/exampletask/GwExampleTask.h#L19) using DECLARE_INITFUNCTION and later on register the task function itself via the [API](https://github.com/wellenvogel/esp32-nmea2000/blob/9b955d135d74937a60f2926e8bfb9395585ff8cd/lib/exampletask/GwExampleTask.cpp#L32).<br>
@ -28,11 +28,13 @@ Files
* [GwExampleTaks.cpp](GwExampleTask.cpp) includes the implementation of our task. This tasks runs in an own thread - see the comments in the code.
We can have as many cpp (and header files) as we need to structure our code.
* [config.json](config.json)<br>
* [config.json](exampleConfig.json)<br>
This file allows to add some config definitions that are needed for our task. For the possible options have a look at the global [config.json](../../web/config.json). Be careful not to overwrite config defitions from the global file. A good practice wood be to prefix the names of definitions with parts of the library name. Always put them in a separate category so that they do not interfere with the system ones.
The defined config items can later be accessed in the code (see the example in [GwExampleTask.cpp](GwExampleTask.cpp)).
The defined config items can later be accessed in the code (see the example in [GwExampleTask.cpp](GwExampleTask.cpp)).<br>
Starting from Version 20250305 you should normally not use this file name any more as those configs would be added for all build environments. Instead define a parameter _custom_config_ in your [platformio.ini](platformio.ini) for the environments you would like to add some configurations for. This parameter accepts a list of file names (relative to the project root, separated by ,).
* [index.js](index.js)<br>
* [index.js](example.js)<br>
You can add javascript code that will contribute to the UI of the system. The WebUI provides a small API that allows you to "hook" into some functions to include your own parts of the UI. This includes adding new tabs, modifying/replacing the data display items, modifying the status display or accessing the config items.
For the API refer to [../../web/index.js](../../web/index.js#L2001).
To start interacting just register for some events like api.EVENTS.init. You can check the capabilities you have defined to see if your task is active.
@ -46,10 +48,14 @@ Files
tools/testServer.py nnn http://x.x.x.x/api
```
with nnn being the local port and x.x.x.x the address of a running system. Open `http://localhost:nnn` in your browser.<br>
After a change just start the compilation and reload the page.
After a change just start the compilation and reload the page.<br>
Starting from Version 20250305 you should normally not use this file name any more as those js code would be added for all build environments. Instead define a parameter _custom_js_ in your [platformio.ini](platformio.ini) for the environments you would like to add the js code for. This parameter accepts a list of file names (relative to the project root, separated by ,). This will also allow you to skip the check for capabilities in your code.
* [index.css](index.css)<br>
You can add own css to influence the styling of the display.
You can add own css to influence the styling of the display.<br>
Starting from Version 20250305 you should normally not use this file name any more as those styles would be added for all build environments. Instead define a parameter _custom_css_ in your [platformio.ini](platformio.ini) for the environments you would like to add some styles for. This parameter accepts a list of file names (relative to the project root, separated by , or as multi line entry)
Interfaces

View File

@ -10,5 +10,9 @@ lib_deps =
build_flags=
-D BOARD_TEST
${env.build_flags}
custom_config=
lib/exampletask/exampleConfig.json
custom_js=lib/exampletask/example.js
custom_css=lib/exampletask/example.css
upload_port = /dev/esp32
upload_protocol = esptool

View File

@ -351,8 +351,8 @@ private:
rmb.vmg
);
send(n2kMsg,msg.sourceId);
SetN2kPGN129285(n2kMsg,sourceId,1,1,true,true,"default");
AppendN2kPGN129285(n2kMsg,destinationId,rmb.destID,rmb.latitude,rmb.longitude);
SetN2kRouteWPInfo(n2kMsg,sourceId,1,1,N2kdir_forward,"default");
AppendN2kRouteWPInfo(n2kMsg,destinationId,rmb.destID,rmb.latitude,rmb.longitude);
send(n2kMsg,msg.sourceId);
}
}
@ -638,8 +638,8 @@ private:
for (int i=0;i< 3;i++){
if (msg.FieldLen(0)>0){
Depth=atof(msg.Field(0));
char dt=msg.Field(i+1)[0];
switch(dt){
char du=msg.Field(i+1)[0];
switch(du){
case 'f':
Depth=Depth/mToFeet;
break;
@ -662,8 +662,9 @@ private:
//we can only send if we have a valid depth beloww tranducer
//to compute the offset
if (! boatData->DBT->isValid()) return;
double offset=Depth-boatData->DBT->getData();
if (offset >= 0 && dt == DBT){
double dbt=boatData->DBT->getData();
double offset=Depth-dbt;
if (offset >= 0 && dt == DBK){
logger->logDebug(GwLog::DEBUG, "strange DBK - more depth then transducer %s", msg.line);
return;
}
@ -675,8 +676,8 @@ private:
if (! boatData->DBS->update(Depth,msg.sourceId)) return;
}
tN2kMsg n2kMsg;
SetN2kWaterDepth(n2kMsg,1,Depth,offset);
send(n2kMsg,msg.sourceId,(n2kMsg.PGN)+String((offset != N2kDoubleNA)?1:0));
SetN2kWaterDepth(n2kMsg,1,dbt,offset); //on the N2K side we always have depth below transducer
send(n2kMsg,msg.sourceId,(n2kMsg.PGN)+String((offset >=0)?1:0));
}
}
}

View File

@ -267,21 +267,29 @@ private:
double DepthBelowTransducer;
double Offset;
double Range;
double WaterDepth;
if (ParseN2kWaterDepth(N2kMsg, SID, DepthBelowTransducer, Offset, Range))
{
WaterDepth = DepthBelowTransducer + Offset;
updateDouble(boatData->DBS, WaterDepth);
updateDouble(boatData->DBT,DepthBelowTransducer);
tNMEA0183Msg NMEA0183Msg;
if (NMEA0183SetDPT(NMEA0183Msg, DepthBelowTransducer, Offset,talkerId))
if (updateDouble(boatData->DBT, DepthBelowTransducer))
{
SendMessage(NMEA0183Msg);
}
if (NMEA0183SetDBx(NMEA0183Msg, DepthBelowTransducer, Offset,talkerId))
{
SendMessage(NMEA0183Msg);
tNMEA0183Msg NMEA0183Msg;
bool offsetValid=true;
if (N2kIsNA(Offset)) {
Offset=NMEA0183DoubleNA;
offsetValid=false;
}
if (NMEA0183SetDPT(NMEA0183Msg, DepthBelowTransducer, Offset, talkerId))
{
SendMessage(NMEA0183Msg);
}
if (offsetValid)
{
double WaterDepth = DepthBelowTransducer + Offset;
updateDouble(boatData->DBS, WaterDepth);
}
if (NMEA0183SetDBx(NMEA0183Msg, DepthBelowTransducer, Offset, talkerId))
{
SendMessage(NMEA0183Msg);
}
}
}
}

View File

@ -498,10 +498,12 @@ void sensorTask(void *param){
// Send supply voltage value all 1s
if(millis() > starttime5 + 1000 && String(powsensor1) == "off"){
starttime5 = millis();
#ifdef VOLTAGE_SENSOR
float rawVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.53) * 2; // Vin = 1/2 for OBP40
#else
float rawVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.17) * 20; // Vin = 1/20 for OBP60
float rawVoltage = 0;
#ifdef BOARD_OBP40S3 && VOLTAGE_SENSOR
rawVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.53) * 2; // Vin = 1/2 for OBP40
#endif
#ifdef BOARD_OBP60S3
rawVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.17) * 20; // Vin = 1/20 for OBP60
#endif
sensors.batteryVoltage = rawVoltage * vslope + voffset; // Calibration
// Save new data in average array
@ -510,7 +512,7 @@ void sensorTask(void *param){
sensors.batteryVoltage10 = batV.getAvg(10) / 100.0;
sensors.batteryVoltage60 = batV.getAvg(60) / 100.0;
sensors.batteryVoltage300 = batV.getAvg(300) / 100.0;
#if defined LIPO_ACCU_1200 && defined VOLTAGE_SENSOR
#if BOARD_OBP40S3 && defined LIPO_ACCU_1200 && defined VOLTAGE_SENSOR
// Polynomfit for LiPo capacity calculation for 3,7V LiPo accus, 0...100%
sensors.batteryLevelLiPo = sensors.batteryVoltage60 * 203.8312 -738.1635;
// Limiter

View File

@ -19,8 +19,8 @@ const int ShowDBS = 5;
const int Compass_X0 = 200; // center point of compass band
const int Compass_Y0 = 220; // position of compass lines
const int Compass_LineLength = 22; // length of compass lines
const float Compass_LineDelta = 8.0; // compass band: 1deg = 5 Pixels, 10deg = 50 Pixels
const int Compass_LineLength = 22; // length of compass lines
const float Compass_LineDelta = 8.0;// compass band: 1deg = 5 Pixels, 10deg = 50 Pixels
class PageCompass : public Page
{
@ -64,180 +64,179 @@ class PageCompass : public Page
virtual void displayPage(PageData &pageData){
GwConfigHandler *config = commonData->config;
GwLog *logger = commonData->logger;
// Old values for hold function
static String OldDataText[HowManyValues] = {"", "", "","", "", ""};
static String OldDataUnits[HowManyValues] = {"", "", "","", "", ""};
// Old values for hold function
static String OldDataText[HowManyValues] = {"", "", "","", "", ""};
static String OldDataUnits[HowManyValues] = {"", "", "","", "", ""};
// Get config data
String lengthformat = config->getString(config->lengthFormat);
// bool simulation = config->getBool(config->useSimuData);
bool holdvalues = config->getBool(config->holdvalues);
String flashLED = config->getString(config->flashLED);
String backlightMode = config->getString(config->backlight);
GwApi::BoatValue *bvalue;
String DataName[HowManyValues];
double DataValue[HowManyValues];
bool DataValid[HowManyValues];
String DataText[HowManyValues];
String DataUnits[HowManyValues];
String DataFormat[HowManyValues];
FormatedData TheFormattedData;
for (int i = 0; i < HowManyValues; i++){
bvalue = pageData.values[i];
TheFormattedData = formatValue(bvalue, *commonData);
DataName[i] = xdrDelete(bvalue->getName());
DataName[i] = DataName[i].substring(0, 6); // String length limit for value name
DataUnits[i] = formatValue(bvalue, *commonData).unit;
DataText[i] = TheFormattedData.svalue; // Formatted value as string including unit conversion and switching decimal places
DataValue[i] = TheFormattedData.value; // Value as double in SI unit
DataValid[i] = bvalue->valid;
DataFormat[i] = bvalue->getFormat(); // Unit of value
LOG_DEBUG(GwLog::LOG,"Drawing at PageCompass: %d %s %f %s %s", i, DataName[i], DataValue[i], DataFormat[i], DataText[i] );
}
// Get config data
String lengthformat = config->getString(config->lengthFormat);
// bool simulation = config->getBool(config->useSimuData);
bool holdvalues = config->getBool(config->holdvalues);
String flashLED = config->getString(config->flashLED);
String backlightMode = config->getString(config->backlight);
GwApi::BoatValue *bvalue;
String DataName[HowManyValues];
double DataValue[HowManyValues];
bool DataValid[HowManyValues];
String DataText[HowManyValues];
String DataUnits[HowManyValues];
String DataFormat[HowManyValues];
FormatedData TheFormattedData;
// Optical warning by limit violation (unused)
if(String(flashLED) == "Limit Violation"){
setBlinkingLED(false);
setFlashLED(false);
}
if (bvalue == NULL) return;
//***********************************************************
// Set display in partial refresh mode
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
getdisplay().setTextColor(commonData->fgcolor);
for (int i = 0; i < HowManyValues; i++){
bvalue = pageData.values[i];
TheFormattedData = formatValue(bvalue, *commonData);
DataName[i] = xdrDelete(bvalue->getName());
DataName[i] = DataName[i].substring(0, 6); // String length limit for value name
DataUnits[i] = formatValue(bvalue, *commonData).unit;
DataText[i] = TheFormattedData.svalue; // Formatted value as string including unit conversion and switching decimal places
DataValue[i] = TheFormattedData.value; // Value as double in SI unit
DataValid[i] = bvalue->valid;
DataFormat[i] = bvalue->getFormat(); // Unit of value
LOG_DEBUG(GwLog::LOG,"Drawing at PageCompass: %d %s %f %s %s", i, DataName[i], DataValue[i], DataFormat[i], DataText[i] );
}
// Horizontal line 3 pix top & bottom
// print Data on top half
getdisplay().fillRect(0, 23, 400, 3, commonData->fgcolor);
getdisplay().setFont(&Ubuntu_Bold20pt7b);
getdisplay().setCursor(10, 70);
getdisplay().print(DataName[WhichDataDisplay]); // Page name
// Show unit
getdisplay().setFont(&Ubuntu_Bold12pt7b);
getdisplay().setCursor(10, 120);
getdisplay().print(DataUnits[WhichDataDisplay]);
getdisplay().setCursor(200, 120);
getdisplay().setFont(&DSEG7Classic_BoldItalic42pt7b);
// Optical warning by limit violation (unused)
if(String(flashLED) == "Limit Violation"){
setBlinkingLED(false);
setFlashLED(false);
}
if (bvalue == NULL) return;
//***********************************************************
// Set display in partial refresh mode
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
getdisplay().setTextColor(commonData->fgcolor);
// Horizontal line 2 pix top & bottom
// Print data on top half
getdisplay().fillRect(0, 130, 400, 2, commonData->fgcolor);
getdisplay().setFont(&Ubuntu_Bold20pt7b);
getdisplay().setCursor(10, 70);
getdisplay().print(DataName[WhichDataDisplay]); // Page name
// Show unit
getdisplay().setFont(&Ubuntu_Bold12pt7b);
getdisplay().setCursor(10, 120);
getdisplay().print(DataUnits[WhichDataDisplay]);
getdisplay().setCursor(190, 120);
getdisplay().setFont(&DSEG7Classic_BoldItalic42pt7b);
if(holdvalues == false){
getdisplay().print(DataText[WhichDataDisplay]); // Real value as formated string
if(holdvalues == false){
getdisplay().print(DataText[WhichDataDisplay]); // Real value as formated string
}
else{
getdisplay().print(OldDataText[WhichDataDisplay]); // Old value as formated string
getdisplay().print(OldDataText[WhichDataDisplay]); // Old value as formated string
}
if(DataValid[WhichDataDisplay] == true){
OldDataText[WhichDataDisplay] = DataText[WhichDataDisplay]; // Save the old value
OldDataUnits[WhichDataDisplay] = DataUnits[WhichDataDisplay]; // Save the old unit
}
// now draw compass band
// get the data
double TheAngle = DataValue[WhichDataCompass];
static double AvgAngle = 0;
AvgAngle = ( AvgAngle * AverageValues + TheAngle ) / (AverageValues + 1 );
OldDataText[WhichDataDisplay] = DataText[WhichDataDisplay]; // Save the old value
OldDataUnits[WhichDataDisplay] = DataUnits[WhichDataDisplay]; // Save the old unit
}
int TheTrend = round( ( TheAngle - AvgAngle) * 180.0 / M_PI );
static const int bsize = 30;
char buffer[bsize+1];
buffer[0]=0;
getdisplay().setFont(&Ubuntu_Bold16pt7b);
getdisplay().setCursor(10, Compass_Y0-60);
getdisplay().print(DataName[WhichDataCompass]); // Page name
// Now draw compass band
// Get the data
double TheAngle = DataValue[WhichDataCompass];
static double AvgAngle = 0;
AvgAngle = ( AvgAngle * AverageValues + TheAngle ) / (AverageValues + 1 );
int TheTrend = round( ( TheAngle - AvgAngle) * 180.0 / M_PI );
static const int bsize = 30;
char buffer[bsize+1];
buffer[0]=0;
getdisplay().setFont(&Ubuntu_Bold16pt7b);
getdisplay().setCursor(10, Compass_Y0-60);
getdisplay().print(DataName[WhichDataCompass]); // Page name
// draw compass base line and pointer
getdisplay().fillRect(0, Compass_Y0, 400, 3, commonData->fgcolor);
getdisplay().fillTriangle(Compass_X0,Compass_Y0-40,Compass_X0-10,Compass_Y0-80,Compass_X0+10,Compass_Y0-80,commonData->fgcolor);
// draw trendlines
for ( int i = 1; i < abs(TheTrend) / 2; i++){
int x1;
if ( TheTrend < 0 )
x1 = Compass_X0 + 20 * i;
else
x1 = Compass_X0 - 20 * ( i + 1 );
// Draw compass base line and pointer
getdisplay().fillRect(0, Compass_Y0, 400, 3, commonData->fgcolor);
getdisplay().fillTriangle(Compass_X0,Compass_Y0-40,Compass_X0-10,Compass_Y0-80,Compass_X0+10,Compass_Y0-80,commonData->fgcolor);
// Draw trendlines
for ( int i = 1; i < abs(TheTrend) / 2; i++){
int x1;
if ( TheTrend < 0 )
x1 = Compass_X0 + 20 * i;
else
x1 = Compass_X0 - 20 * ( i + 1 );
getdisplay().fillRect(x1, Compass_Y0 -60, 10, 6, commonData->fgcolor);
}
// central line + satellite lines
double NextSector = round(TheAngle / ( M_PI / 9 )) * ( M_PI / 9 ); // get the next 20degree value
double Offset = - ( NextSector - TheAngle); // offest of the center line compared to TheAngle in Radian
int Delta_X = int ( Offset * 180.0 / M_PI * Compass_LineDelta );
for ( int i = 0; i <=4; i++ )
{
int x0;
x0 = Compass_X0 + Delta_X + 2 * i * 5 * Compass_LineDelta;
getdisplay().fillRect(x0-1, Compass_Y0 - 2 * Compass_LineLength,3, 2 * Compass_LineLength, commonData->fgcolor);
x0 = Compass_X0 + Delta_X + ( 2 * i + 1 ) * 5 * Compass_LineDelta;
getdisplay().fillRect(x0-1, Compass_Y0 - Compass_LineLength,3, Compass_LineLength, commonData->fgcolor);
getdisplay().fillRect(x1, Compass_Y0 -55, 10, 6, commonData->fgcolor);
}
// Central line + satellite lines
double NextSector = round(TheAngle / ( M_PI / 9 )) * ( M_PI / 9 ); // Get the next 20degree value
double Offset = - ( NextSector - TheAngle); // Offest of the center line compared to TheAngle in Radian
int Delta_X = int ( Offset * 180.0 / M_PI * Compass_LineDelta );
for ( int i = 0; i <=4; i++ ){
int x0;
x0 = Compass_X0 + Delta_X + 2 * i * 5 * Compass_LineDelta;
getdisplay().fillRect(x0-2, Compass_Y0 - 2 * Compass_LineLength, 5, 2 * Compass_LineLength, commonData->fgcolor);
x0 = Compass_X0 + Delta_X + ( 2 * i + 1 ) * 5 * Compass_LineDelta;
getdisplay().fillRect(x0-1, Compass_Y0 - Compass_LineLength, 3, Compass_LineLength, commonData->fgcolor);
x0 = Compass_X0 + Delta_X - 2 * i * 5 * Compass_LineDelta;
getdisplay().fillRect(x0-1, Compass_Y0 - 2 * Compass_LineLength,3, 2 * Compass_LineLength, commonData->fgcolor);
x0 = Compass_X0 + Delta_X - ( 2 * i + 1 ) * 5 * Compass_LineDelta;
getdisplay().fillRect(x0-1, Compass_Y0 - Compass_LineLength,3, Compass_LineLength, commonData->fgcolor);
}
x0 = Compass_X0 + Delta_X - 2 * i * 5 * Compass_LineDelta;
getdisplay().fillRect(x0-2, Compass_Y0 - 2 * Compass_LineLength, 5, 2 * Compass_LineLength, commonData->fgcolor);
x0 = Compass_X0 + Delta_X - ( 2 * i + 1 ) * 5 * Compass_LineDelta;
getdisplay().fillRect(x0-1, Compass_Y0 - Compass_LineLength, 3, Compass_LineLength, commonData->fgcolor);
}
getdisplay().fillRect(0, Compass_Y0, 400, 3, commonData->fgcolor);
// add the numbers to the compass band
int x0;
float AngleToDisplay = NextSector * 180.0 / M_PI;
getdisplay().fillRect(0, Compass_Y0, 400, 3, commonData->fgcolor);
// Add the numbers to the compass band
int x0;
float AngleToDisplay = NextSector * 180.0 / M_PI;
x0 = Compass_X0 + Delta_X;
getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b);
x0 = Compass_X0 + Delta_X;
getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b);
do {
getdisplay().setCursor(x0 - 40, Compass_Y0 + 40);
snprintf(buffer,bsize,"%03.0f", AngleToDisplay);
getdisplay().print(buffer);
AngleToDisplay += 20;
if ( AngleToDisplay >= 360.0 )
AngleToDisplay -= 360.0;
x0 -= 4 * 5 * Compass_LineDelta;
} while ( x0 >= 0 - 60 );
AngleToDisplay = NextSector * 180.0 / M_PI - 20;
do {
getdisplay().setCursor(x0 - 40, Compass_Y0 + 40);
snprintf(buffer,bsize,"%03.0f", AngleToDisplay);
getdisplay().print(buffer);
AngleToDisplay += 20;
if ( AngleToDisplay >= 360.0 )
AngleToDisplay -= 360.0;
x0 -= 4 * 5 * Compass_LineDelta;
} while ( x0 >= 0 - 60 );
AngleToDisplay = NextSector * 180.0 / M_PI - 20;
if ( AngleToDisplay < 0 )
AngleToDisplay += 360.0;
x0 = Compass_X0 + Delta_X + 4 * 5 * Compass_LineDelta;
do {
getdisplay().setCursor(x0 - 40, Compass_Y0 + 40);
snprintf(buffer,bsize,"%03.0f", AngleToDisplay);
// Quick and dirty way to prevent wrapping text in next line
if ( ( x0 - 40 ) > 380 )
buffer[0] = 0;
else if ( ( x0 - 40 ) > 355 )
buffer[1] = 0;
else if ( ( x0 - 40 ) > 325 )
buffer[2] = 0;
getdisplay().print(buffer);
AngleToDisplay -= 20;
if ( AngleToDisplay < 0 )
AngleToDisplay += 360.0;
x0 = Compass_X0 + Delta_X + 4 * 5 * Compass_LineDelta;
do {
getdisplay().setCursor(x0 - 40, Compass_Y0 + 40);
snprintf(buffer,bsize,"%03.0f", AngleToDisplay);
// quick and dirty way to prevent wrapping text in next line
if ( ( x0 - 40 ) > 380 )
buffer[0] = 0;
else if ( ( x0 - 40 ) > 355 )
buffer[1] = 0;
else if ( ( x0 - 40 ) > 325 )
buffer[2] = 0;
getdisplay().print(buffer);
AngleToDisplay -= 20;
if ( AngleToDisplay < 0 )
AngleToDisplay += 360.0;
x0 += 4 * 5 * Compass_LineDelta;
} while (x0 < ( 400 - 20 -40 ) );
// static int x_test = 320;
// x_test += 2;
x0 += 4 * 5 * Compass_LineDelta;
} while (x0 < ( 400 - 20 -40 ) );
// snprintf(buffer,bsize,"%03d", x_test);
// getdisplay().setCursor(x_test, Compass_Y0 - 60);
// getdisplay().print(buffer);
// if ( x_test > 390)
// x_test = 320;
// static int x_test = 320;
// x_test += 2;
// Update display
getdisplay().nextPage(); // Partial update (fast)
// snprintf(buffer,bsize,"%03d", x_test);
// getdisplay().setCursor(x_test, Compass_Y0 - 60);
// getdisplay().print(buffer);
// if ( x_test > 390)
// x_test = 320;
// Update display
getdisplay().nextPage(); // Partial update (fast)
};

View File

@ -1187,6 +1187,7 @@
"Battery",
"Battery2",
"Clock",
"Compass",
"DST810",
"Fluid",
"FourValues",
@ -1466,6 +1467,7 @@
"Battery",
"Battery2",
"Clock",
"Compass",
"DST810",
"Fluid",
"FourValues",
@ -1742,6 +1744,7 @@
"Battery",
"Battery2",
"Clock",
"Compass",
"DST810",
"Fluid",
"FourValues",
@ -2015,6 +2018,7 @@
"Battery",
"Battery2",
"Clock",
"Compass",
"DST810",
"Fluid",
"FourValues",
@ -2285,6 +2289,7 @@
"Battery",
"Battery2",
"Clock",
"Compass",
"DST810",
"Fluid",
"FourValues",
@ -2552,6 +2557,7 @@
"Battery",
"Battery2",
"Clock",
"Compass",
"DST810",
"Fluid",
"FourValues",
@ -2816,6 +2822,7 @@
"Battery",
"Battery2",
"Clock",
"Compass",
"DST810",
"Fluid",
"FourValues",
@ -3077,6 +3084,7 @@
"Battery",
"Battery2",
"Clock",
"Compass",
"DST810",
"Fluid",
"FourValues",
@ -3335,6 +3343,7 @@
"Battery",
"Battery2",
"Clock",
"Compass",
"DST810",
"Fluid",
"FourValues",
@ -3590,6 +3599,7 @@
"Battery",
"Battery2",
"Clock",
"Compass",
"DST810",
"Fluid",
"FourValues",

View File

@ -285,6 +285,8 @@ void registerAllPages(PageList &list){
list.add(&registerPageDST810);
extern PageDescription registerPageClock;
list.add(&registerPageClock);
extern PageDescription registerPageCompass;
list.add(&registerPageCompass);
extern PageDescription registerPageWhite;
list.add(&registerPageWhite);
extern PageDescription registerPageBME280;

View File

@ -112,7 +112,7 @@ class SSISensor : public SensorTemplate<BUSTYPE,SensorBase::SPI>{
.flags = SPI_TRANS_USE_RXDATA,
.cmd = 0,
.addr = 0,
.length = bits+1,
.length = (size_t)bits+1,
.rxlength = 0};
esp_err_t ret = spi_device_queue_trans(device->device(), &ta, portMAX_DELAY);
if (ret != ESP_OK) return ret;
@ -138,4 +138,4 @@ class SSISensor : public SensorTemplate<BUSTYPE,SensorBase::SPI>{
using SpiSensorList=SensorList;
#define GWSPI1_HOST SPI2_HOST
#define GWSPI2_HOST SPI3_HOST
#endif
#endif

View File

@ -917,7 +917,7 @@ void setup() {
logger.flush();
NMEA2000.SetMode(tNMEA2000::N2km_ListenAndNode, NodeAddress);
NMEA2000.SetForwardOwnMessages(false);
NMEA2000.SetHeartbeatInterval(NMEA2000_HEARTBEAT_INTERVAL);
NMEA2000.SetHeartbeatIntervalAndOffset(NMEA2000_HEARTBEAT_INTERVAL);
if (sendOutN2k){
// Set the information for other bus devices, which messages we support
unsigned long *pgns=toN2KConverter->handledPgns();