From e269034073e1b0b9fd0297472a6884f9d8340e74 Mon Sep 17 00:00:00 2001 From: norbert-walter Date: Wed, 16 Mar 2022 12:02:31 +0100 Subject: [PATCH 1/3] Fix for problems with reboots by using GPS modul --- lib/obp60task/ObpNmea0183.h | 54 +++++++++++++++++++++++++++++++++++++ lib/obp60task/obp60task.cpp | 7 ++++- 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 lib/obp60task/ObpNmea0183.h diff --git a/lib/obp60task/ObpNmea0183.h b/lib/obp60task/ObpNmea0183.h new file mode 100644 index 0000000..56a5db6 --- /dev/null +++ b/lib/obp60task/ObpNmea0183.h @@ -0,0 +1,54 @@ +#pragma once +#include "NMEA0183.h" +#include "GwNmea0183Msg.h" + +class ObpNmea0183 : public tNMEA0183 +{ +public: + bool GetMessageCor(SNMEA0183Msg &NMEA0183Msg) + { + if (!IsOpen()) + return false; + + bool result = false; + + while (port->available() > 0 && !result) + { + int NewByte = port->read(); + if (NewByte == '$' || NewByte == '!') + { // Message start + MsgInStarted = true; + MsgInPos = 0; + MsgInBuf[MsgInPos] = NewByte; + MsgInPos++; + } + else if (MsgInStarted) + { + MsgInBuf[MsgInPos] = NewByte; + if (NewByte == '*') + MsgCheckSumStartPos = MsgInPos; + MsgInPos++; + if (MsgCheckSumStartPos != SIZE_MAX and MsgCheckSumStartPos + 3 == MsgInPos) + { // We have full checksum and so full message + MsgInBuf[MsgInPos] = 0; // add null termination + if (NMEA0183Msg.SetMessageCor(MsgInBuf)) + { + NMEA0183Msg.SourceID = SourceID; + result = true; + } + MsgInStarted = false; + MsgInPos = 0; + MsgCheckSumStartPos = SIZE_MAX; + } + if (MsgInPos >= MAX_NMEA0183_MSG_BUF_LEN) + { // Too may chars in message. Start from beginning + MsgInStarted = false; + MsgInPos = 0; + MsgCheckSumStartPos = SIZE_MAX; + } + } + } + + return result; + } +}; diff --git a/lib/obp60task/obp60task.cpp b/lib/obp60task/obp60task.cpp index 106bead..97634a2 100644 --- a/lib/obp60task/obp60task.cpp +++ b/lib/obp60task/obp60task.cpp @@ -28,8 +28,12 @@ #include "Logo_OBP_400x300_sw.h" // OBP Logo #include "OBP60QRWiFi.h" // Functions lib for WiFi QR code +#include "ObpNmea0183.h" +#include "GwNmea0183Msg.h" + tNMEA0183Msg NMEA0183Msg; -tNMEA0183 NMEA0183; +ObpNmea0183 NMEA0183; // Fixed Lib for NMEA0183 +// tNMEA0183 NMEA0183; // Old lib with problems for NMEA0183 Adafruit_BME280 bme280; // Evironment sensor BME280 Adafruit_BMP280 bmp280; // Evironment sensor BMEP280 @@ -520,6 +524,7 @@ void OBP60Task(GwApi *api){ long starttime6 = millis(); // Environment sensor update all 1s while (true){ + delay(10); // Fixed the problem with NMEA0183 and GPS sentences Timer1.update(); // Update for Timer1 Timer2.update(); // Update for Timer2 if(millis() > starttime0 + 100){ From 22fe6d0102c9167f8094edda4b87683e26649c85 Mon Sep 17 00:00:00 2001 From: norbert-walter Date: Wed, 16 Mar 2022 14:52:15 +0100 Subject: [PATCH 2/3] Finishing rudder page --- lib/obp60task/PageRudderPosition.cpp | 85 ++++++++++++---------------- 1 file changed, 35 insertions(+), 50 deletions(-) diff --git a/lib/obp60task/PageRudderPosition.cpp b/lib/obp60task/PageRudderPosition.cpp index ba01534..44385df 100644 --- a/lib/obp60task/PageRudderPosition.cpp +++ b/lib/obp60task/PageRudderPosition.cpp @@ -25,13 +25,9 @@ public: GwConfigHandler *config = commonData.config; GwLog *logger=commonData.logger; - static String svalue1old = ""; static String unit1old = ""; - static String svalue2old = ""; - static String unit2old = ""; - - double value1 = 0; - double value2 = 0; + double value1 = 0.1; + double value1old = 0.1; // Get config data String lengthformat = config->getString(config->lengthFormat); @@ -42,37 +38,19 @@ public: String backlightMode = config->getString(config->backlight); int timezone = config->getInt(config->timeZone); - // Get boat values for GPS time - GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue) + // Get boat values for rudder position + GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list String name1 = bvalue1->getName().c_str(); // Value name name1 = name1.substring(0, 6); // String length limit for value name - if(simulation == false){ - value1 = bvalue1->value; // Value as double in SI unit - } - else{ - value1 = 38160; // Simulation data for time value 11:36 in seconds - } // Other simulation data see OBP60Formater.cpp + value1 = bvalue1->value; // Raw value without unit convertion bool valid1 = bvalue1->valid; // Valid information 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 if(valid1 == true){ - svalue1old = svalue1; // Save old value + value1old = value1; // Save old value unit1old = unit1; // Save old unit } - // Get boat values for GPS date - GwApi::BoatValue *bvalue2 = pageData.values[1]; // First element in list (only one value by PageOneValue) - String name2 = bvalue2->getName().c_str(); // Value name - name2 = name2.substring(0, 6); // String length limit for value name - value2 = bvalue2->value; // Value as double in SI unit - bool valid2 = bvalue2->valid; // Valid information - 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 - if(valid2 == true){ - svalue2old = svalue2; // Save old value - unit2old = unit2; // Save old unit - } - // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ setBlinkingLED(false); @@ -81,7 +59,7 @@ public: // Logging boat values if (bvalue1 == NULL) return; - LOG_DEBUG(GwLog::LOG,"Drawing at PageRudderPosition, %s:%f, %s:%f", name1, value1, name2, value2); + LOG_DEBUG(GwLog::LOG,"Drawing at PageRudderPosition, %s:%f", name1, value1); // Draw page //*********************************************************** @@ -118,12 +96,12 @@ public: // Scaling values float x = 200 + (rWindGraphic-30)*sin(i/180.0*pi); // x-coordinate dots float y = 150 - (rWindGraphic-30)*cos(i/180.0*pi); // y-coordinate cots - const char *ii = ""; + const char *ii = " "; switch (i) { - case 0: ii=""; break; - case 30 : ii=""; break; - case 60 : ii=""; break; + case 0: ii=" "; break; // Use a blank for a empty scale value + case 30 : ii=" "; break; + case 60 : ii=" "; break; case 90 : ii="45"; break; case 120 : ii="30"; break; case 150 : ii="15"; break; @@ -131,8 +109,8 @@ public: case 210 : ii="15"; break; case 240 : ii="30"; break; case 270 : ii="45"; break; - case 300 : ii="0"; break; - case 330 : ii="0"; break; + case 300 : ii=" "; break; + case 330 : ii=" "; break; default: break; } @@ -167,34 +145,41 @@ public: 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2), 200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),pixelcolor); } + } - // Print Unit in RudderPosition + // Print label display.setTextColor(textcolor); + display.setFont(&Ubuntu_Bold16pt7b); + display.setCursor(80, 70); + display.print("Rudder Position"); // Label + + // Print Unit in RudderPosition if(holdvalues == false){ display.setFont(&Ubuntu_Bold12pt7b); display.setCursor(175, 110); - display.print(unit2); // Unit + display.print(unit1); // Unit } else{ display.setFont(&Ubuntu_Bold12pt7b); display.setCursor(175, 110); - display.print(unit2old); // Unit + display.print(unit1old); // Unit } - // RudderPosition values - double hour = 0; - double minute = 0; - hour = (value1 / 3600.0); - if(hour > 12) hour = hour - 12.0; - hour = hour + timezone; - minute = (hour - int(hour)) * 3600.0 / 60.0; + // Calculate rudder position + if(holdvalues == true && valid1 == false){ + value1 = 2 * pi - ((value1old * 2) + pi); + } + else{ + value1 = 2 * pi - ((value1 * 2) + pi); + } - // Draw hour pointer + // Draw rudder position pointer float startwidth = 8; // Start width of pointer + if(valid1 == true || holdvalues == true || simulation == true){ - float sinx=sin(hour * 30.0 * pi / 180); // Hour - float cosx=cos(hour * 30.0 * pi / 180); + float sinx=sin(value1); + float cosx=cos(value1); // Normal pointer // Pointer as triangle with center base 2*width float xx1 = -startwidth; @@ -253,9 +238,9 @@ static Page *createPage(CommonData &common){ * and will will provide the names of the fixed values we need */ PageDescription registerPageRudderPosition( - "RudderPosition", // Page name + "RudderPosition", // Page name createPage, // Action 0, // Number of bus values depends on selection in Web configuration - {"GPST", "GPSD"}, // Bus values we need in the page + {"RPOS"}, // Bus values we need in the page true // Show display header on/off ); \ No newline at end of file From 7903d520e189b037af68bf07ab907adb6b3e2c49 Mon Sep 17 00:00:00 2001 From: norbert-walter Date: Wed, 16 Mar 2022 18:55:50 +0100 Subject: [PATCH 3/3] Add environment sensor HTU21, BMP085 and BMP0180 --- lib/obp60task/OBP60Hardware.h | 8 ++++--- lib/obp60task/config.json | 3 +++ lib/obp60task/obp60task.cpp | 45 ++++++++++++++++++++++++++++------- lib/obp60task/platformio.ini | 1 + 4 files changed, 46 insertions(+), 11 deletions(-) diff --git a/lib/obp60task/OBP60Hardware.h b/lib/obp60task/OBP60Hardware.h index 64a98dc..a4d9064 100644 --- a/lib/obp60task/OBP60Hardware.h +++ b/lib/obp60task/OBP60Hardware.h @@ -12,11 +12,13 @@ // Extension Port MCP23017 #define MCP23017_I2C_ADDR 0x20 // Addr. 0 is 0x20 // BME280 - #define BME280_I2C_ADDR 0x76 // Addr. 0x76 + #define BME280_I2C_ADDR 0x76 // Addr. 0x76 (0x77) // BMP280 #define BMP280_I2C_ADDR 0x77 // Addr. 0x77 - // SHT21 - #define SHT21_I2C_ADDR 0x40 // Addr. 0x40 + // BMP085 / BMP180 + #define BMP280_I2C_ADDR 0x77 // Addr. 0x77 (fix) + // SHT21 / HUT21 + #define SHT21_I2C_ADDR 0x40 // Addr. 0x40 (fix) // SPI (E-Ink display, Extern Bus) #define OBP_SPI_CS 5 #define OBP_SPI_DC 17 diff --git a/lib/obp60task/config.json b/lib/obp60task/config.json index 32c8dfd..4c44b38 100644 --- a/lib/obp60task/config.json +++ b/lib/obp60task/config.json @@ -251,6 +251,9 @@ "off", "BME280", "BMP280", + "BMP180", + "BMP085", + "HTU21", "SHT21" ], "category": "OBP60 Hardware", diff --git a/lib/obp60task/obp60task.cpp b/lib/obp60task/obp60task.cpp index 97634a2..5991b0a 100644 --- a/lib/obp60task/obp60task.cpp +++ b/lib/obp60task/obp60task.cpp @@ -9,6 +9,7 @@ #include // Adafruit Lib for sensors #include // Adafruit Lib for BME280 #include // Adafruit Lib for BMP280 +#include // Adafruit Lib for BMP085 and BMP180 #include // Lib for SHT21/HTU21 #include // NMEA2000 #include @@ -36,15 +37,17 @@ ObpNmea0183 NMEA0183; // Fixed Lib for NMEA0183 // tNMEA0183 NMEA0183; // Old lib with problems for NMEA0183 Adafruit_BME280 bme280; // Evironment sensor BME280 -Adafruit_BMP280 bmp280; // Evironment sensor BMEP280 -HTU21D sht21(HTU21D_RES_RH12_TEMP14); // Environment sensor SHT21 identical to HTU21 +Adafruit_BMP280 bmp280; // Evironment sensor BMP280 +Adafruit_BMP085 bmp085; //Evironment sensor BMP085 and BMP180 +HTU21D sht21(HTU21D_RES_RH12_TEMP14); // Environment sensor SHT21 and HTU21 // Global vars bool initComplete = false; // Initialization complete int taskRunCounter = 0; // Task couter for loop section bool gps_ready = false; // GPS initialized and ready to use bool BME280_ready = false; // BME280 initialized and ready to use -bool BMP280_ready = false; // BMP20 initialized and ready to use +bool BMP280_ready = false; // BMP280 initialized and ready to use +bool BMP180_ready = false; // BMP180 initialized and ready to use bool SHT21_ready = false; // SHT21 initialized and ready to use double airhumidity = 0; // Air Humitity value from environment sensor double airtemperature = 0; // Air Temperature value from environment sensor @@ -218,12 +221,23 @@ void OBP60Init(GwApi *api){ BMP280_ready = true; } } - else if(String(envSensors) == "SHT21"){ - if (!sht21.begin()) { - api->getLogger()->logDebug(GwLog::ERROR,"Modul SHT21 not found, check wiring"); + else if(String(envSensors) == "BMP085" || String(envSensors) == "BMP180"){ + if (!bmp085.begin()) { + api->getLogger()->logDebug(GwLog::ERROR,"Modul BMP085/BMP180 not found, check wiring"); } else{ - api->getLogger()->logDebug(GwLog::DEBUG,"Modul SHT21 found"); + api->getLogger()->logDebug(GwLog::DEBUG,"Modul BMP085/BMP180 found"); + airtemperature = bmp085.readTemperature(); + airpressure =bmp085.readPressure()/100; + BMP180_ready = true; + } + } + else if(String(envSensors) == "HTU21" || String(envSensors) == "SHT21"){ + if (!sht21.begin()) { + api->getLogger()->logDebug(GwLog::ERROR,"Modul HTU21/SHT21 not found, check wiring"); + } + else{ + api->getLogger()->logDebug(GwLog::DEBUG,"Modul HTU21/SHT21 found"); airhumidity = sht21.readCompensatedHumidity(); airtemperature = sht21.readTemperature(); SHT21_ready = true; @@ -681,7 +695,22 @@ void OBP60Task(GwApi *api){ api->sendN2kMessage(N2kMsg); } } - else if(envsensor == "SHT21" && BME280_ready == true){ + else if((envsensor == "BMP085" || envsensor == "BMP180") && BMP180_ready == true){ + airtemperature = bmp085.readTemperature(); + commonData.data.airTemperature = airtemperature; // Data take over to page + airpressure =bmp085.readPressure()/100; + commonData.data.airPressure = airpressure; // Data take over to page + // Send to NMEA200 bus + if(!isnan(airtemperature)){ + SetN2kPGN130312(N2kMsg, 0, 0,(tN2kTempSource) TempSource, CToKelvin(airtemperature), N2kDoubleNA); + api->sendN2kMessage(N2kMsg); + } + if(!isnan(airpressure)){ + SetN2kPGN130314(N2kMsg, 0, 0, (tN2kPressureSource) mBarToPascal(PressureSource), airpressure); + api->sendN2kMessage(N2kMsg); + } + } + else if((envsensor == "SHT21" || envsensor == "HTU21") && SHT21_ready == true){ airhumidity = sht21.readCompensatedHumidity(); commonData.data.airHumidity = airhumidity; // Data take over to page airtemperature = sht21.readTemperature(); diff --git a/lib/obp60task/platformio.ini b/lib/obp60task/platformio.ini index 6be486b..b1a435c 100644 --- a/lib/obp60task/platformio.ini +++ b/lib/obp60task/platformio.ini @@ -15,6 +15,7 @@ lib_deps = sstaub/Ticker@4.4.0 adafruit/Adafruit BMP280 Library@2.6.2 adafruit/Adafruit BME280 Library@2.2.2 + adafruit/Adafruit BMP085 Library@1.2.1 enjoyneering/HTU21D@1.2.1 build_flags= -D BOARD_NODEMCU32S_OBP60