From 3bbd9ef965249fd23ab89a674b9eb52e939fa40d Mon Sep 17 00:00:00 2001 From: andreas Date: Mon, 18 Oct 2021 19:20:00 +0200 Subject: [PATCH] separate boat data, integrate with web server --- lib/boatData/GwBoatData.cpp | 54 +++++++++++ lib/boatData/GwBoatData.h | 67 +++++++++++++ .../nmea2kto0183}/N2kDataToNMEA0183.cpp | 92 +++++++++--------- {src => lib/nmea2kto0183}/N2kDataToNMEA0183.h | 20 +++- src/BoatData.h | 38 -------- src/main.cpp | 97 ++----------------- 6 files changed, 190 insertions(+), 178 deletions(-) create mode 100644 lib/boatData/GwBoatData.cpp create mode 100644 lib/boatData/GwBoatData.h rename {src => lib/nmea2kto0183}/N2kDataToNMEA0183.cpp (81%) rename {src => lib/nmea2kto0183}/N2kDataToNMEA0183.h (89%) delete mode 100644 src/BoatData.h diff --git a/lib/boatData/GwBoatData.cpp b/lib/boatData/GwBoatData.cpp new file mode 100644 index 0000000..cf217b5 --- /dev/null +++ b/lib/boatData/GwBoatData.cpp @@ -0,0 +1,54 @@ +#include "GwBoatData.h" + +GwBoatItem *GwBoatData::find(String name,bool doCreate){ + GwBoatItemMap::iterator it; + if ((it=values.find(name)) != values.end()){ + return it->second; + } + if (! doCreate) return NULL; + GwBoatItem *ni=new GwBoatItem(); + values[name]=ni; + return ni; +} +GwBoatData::GwBoatData(GwLog *logger){ + +} +GwBoatData::~GwBoatData(){ + GwBoatItemMap::iterator it; + for (it=values.begin() ; it != values.end();it++){ + delete it->second; + } +} +void GwBoatData::update(String name,const char *value){ + GwBoatItem *i=find(name); + i->update(value); +} +void GwBoatData::update(String name, String value){ + GwBoatItem *i=find(name); + i->update(value); +} +void GwBoatData::update(String name, long value){ + GwBoatItem *i=find(name); + i->update(value); +} +void GwBoatData::update(String name, double value){ + GwBoatItem *i=find(name); + i->update(value); +} +void GwBoatData::update(String name, bool value){ + GwBoatItem *i=find(name); + i->update(value); +} +String GwBoatData::toJson() const { + long minTime=millis() - maxAge; + DynamicJsonDocument json(800); + GwBoatItemMap::const_iterator it; + for (it=values.begin() ; it != values.end();it++){ + if (it->second->isValid(minTime)){ + json[it->first]=it->second->getValue(); + } + } + String buf; + serializeJson(json,buf); + return buf; +} \ No newline at end of file diff --git a/lib/boatData/GwBoatData.h b/lib/boatData/GwBoatData.h new file mode 100644 index 0000000..27bc2bf --- /dev/null +++ b/lib/boatData/GwBoatData.h @@ -0,0 +1,67 @@ +#ifndef _GWBOATDATA_H +#define _GWBOATDATA_H + +#include "GwLog.h" +#include +#include +#include +#define GW_BOAT_VALUE_LEN 32 +class GwBoatItem{ + private: + char value[GW_BOAT_VALUE_LEN]; + long lastSet; + void uls(){ + lastSet=millis(); + } + public: + const char * getValue() const{return value;} + long getLastSet() const {return lastSet;} + bool isValid(long minTime) const {return lastSet > minTime;} + GwBoatItem(){ + value[0]=0; + lastSet=-1; + } + void update(String nv){ + strncpy(value,nv.c_str(),GW_BOAT_VALUE_LEN-1); + uls(); + } + void update(const char * nv){ + strncpy(value,nv,GW_BOAT_VALUE_LEN-1); + } + void update(long nv){ + ltoa(nv,value,10); + uls(); + } + void update(bool nv){ + if (nv) strcpy_P(value,PSTR("true")); + else strcpy_P(value,PSTR("false")); + uls(); + } + void update(double nv){ + dtostrf(nv,3,7,value); + uls(); + } + void invalidate(){ + lastSet=0; + } + +}; +class GwBoatData{ + typedef std::map GwBoatItemMap; + private: + const long maxAge=60000; //max age for valid data in ms + GwLog *logger; + GwBoatItemMap values; + GwBoatItem *find(String name, bool doCreate=true); + public: + GwBoatData(GwLog *logger); + ~GwBoatData(); + void update(String name,const char *value); + void update(String name, String value); + void update(String name, long value); + void update(String name, bool value); + void update(String name, double value); + String toJson() const; + +}; +#endif \ No newline at end of file diff --git a/src/N2kDataToNMEA0183.cpp b/lib/nmea2kto0183/N2kDataToNMEA0183.cpp similarity index 81% rename from src/N2kDataToNMEA0183.cpp rename to lib/nmea2kto0183/N2kDataToNMEA0183.cpp index d146a32..1b7629b 100644 --- a/src/N2kDataToNMEA0183.cpp +++ b/lib/nmea2kto0183/N2kDataToNMEA0183.cpp @@ -26,12 +26,11 @@ #include #include "N2kDataToNMEA0183.h" -#include "BoatData.h" const double radToDeg = 180.0 / M_PI; //***************************************************************************** -void tN2kDataToNMEA0183::HandleMsg(const tN2kMsg &N2kMsg) { +void N2kDataToNMEA0183::HandleMsg(const tN2kMsg &N2kMsg) { switch (N2kMsg.PGN) { case 127250UL: HandleHeading(N2kMsg); case 127258UL: HandleVariation(N2kMsg); @@ -48,18 +47,21 @@ void tN2kDataToNMEA0183::HandleMsg(const tN2kMsg &N2kMsg) { } //***************************************************************************** -long tN2kDataToNMEA0183::Update(tBoatData *BoatData) { +void N2kDataToNMEA0183::loop() { + unsigned long now=millis(); + if ( now < (lastLoopTime + 100)) return; + lastLoopTime=now; SendRMC(); - if ( LastHeadingTime + 2000 < millis() ) Heading = N2kDoubleNA; - if ( LastCOGSOGTime + 2000 < millis() ) { + if ( (LastHeadingTime + 2000) < now ) Heading = N2kDoubleNA; + if ( (LastCOGSOGTime + 2000) < now ) { COG = N2kDoubleNA; SOG = N2kDoubleNA; } - if ( LastPositionTime + 4000 < millis() ) { + if ( (LastPositionTime + 4000) < now ) { Latitude = N2kDoubleNA; Longitude = N2kDoubleNA; } - if ( LastWindTime + 2000 < millis() ) { + if ( ( LastWindTime + 2000) < now ) { AWS = N2kDoubleNA; AWA = N2kDoubleNA; TWS = N2kDoubleNA; @@ -67,45 +69,39 @@ long tN2kDataToNMEA0183::Update(tBoatData *BoatData) { TWD = N2kDoubleNA; } - BoatData->Latitude=Latitude; - BoatData->Longitude=Longitude; - BoatData->Altitude=Altitude; - BoatData->Heading=Heading * radToDeg; - BoatData->COG=COG * radToDeg; - BoatData->SOG=SOG * 3600.0/1852.0; - BoatData->STW=STW * 3600.0/1852.0; - BoatData->AWS=AWS * 3600.0/1852.0; - BoatData->TWS=TWS * 3600.0/1852.0; - BoatData->MaxAws=MaxAws * 3600.0/1852.0;; - BoatData->MaxTws=MaxTws * 3600.0/1852.0;; - BoatData->AWA=AWA * radToDeg; - BoatData->TWA=TWA * radToDeg; - BoatData->TWD=TWD * radToDeg; - BoatData->TripLog=TripLog / 1825.0; - BoatData->Log=Log / 1825.0; - BoatData->RudderPosition=RudderPosition * radToDeg; - BoatData->WaterTemperature=KelvinToC(WaterTemperature) ; - BoatData->WaterDepth=WaterDepth; - BoatData->Variation=Variation *radToDeg; - BoatData->GPSTime=SecondsSinceMidnight; - BoatData->DaysSince1970=DaysSince1970; + boatData->update(F("Latitude"),Latitude); + boatData->update(F("Longitude"),Longitude); + boatData->update(F("Altitude"),Altitude); + boatData->update(F("Heading"),Heading * radToDeg); + boatData->update(F("COG"),COG * radToDeg); + boatData->update(F("SOG"),SOG * 3600.0/1852.0); + boatData->update(F("STW"),STW * 3600.0/1852.0); + boatData->update(F("AWS"),AWS * 3600.0/1852.0); + boatData->update(F("TWS"),TWS * 3600.0/1852.0); + boatData->update(F("MaxAws"),MaxAws * 3600.0/1852.0); + boatData->update(F("MaxTws"),MaxTws * 3600.0/1852.0); + boatData->update(F("AWA"),AWA * radToDeg); + boatData->update(F("TWA"),TWA * radToDeg); + boatData->update(F("TWD"),TWD * radToDeg); + boatData->update(F("TripLog"),TripLog / 1825.0); + boatData->update(F("Log"),Log / 1825.0); + boatData->update(F("RudderPosition"),RudderPosition * radToDeg); + boatData->update(F("WaterTemperature"),KelvinToC(WaterTemperature)) ; + boatData->update(F("WaterDepth"),WaterDepth); + boatData->update(F("Variation"),Variation *radToDeg); + boatData->update(F("GPSTime"),SecondsSinceMidnight); + boatData->update(F("DaysSince1970"),(long)DaysSince1970); - -if (SecondsSinceMidnight!=N2kDoubleNA && DaysSince1970!=N2kUInt16NA){ - return((DaysSince1970*3600*24)+SecondsSinceMidnight); // Needed for SD Filename and time - } else { - return(0); // Needed for SD Filename and time - } } //***************************************************************************** -void tN2kDataToNMEA0183::SendMessage(const tNMEA0183Msg &NMEA0183Msg) { +void N2kDataToNMEA0183::SendMessage(const tNMEA0183Msg &NMEA0183Msg) { if ( pNMEA0183 != 0 ) pNMEA0183->SendMessage(NMEA0183Msg); if ( SendNMEA0183MessageCallback != 0 ) SendNMEA0183MessageCallback(NMEA0183Msg); } //***************************************************************************** -void tN2kDataToNMEA0183::HandleHeading(const tN2kMsg &N2kMsg) { +void N2kDataToNMEA0183::HandleHeading(const tN2kMsg &N2kMsg) { unsigned char SID; tN2kHeadingReference ref; double _Deviation = 0; @@ -125,7 +121,7 @@ void tN2kDataToNMEA0183::HandleHeading(const tN2kMsg &N2kMsg) { } //***************************************************************************** -void tN2kDataToNMEA0183::HandleVariation(const tN2kMsg &N2kMsg) { +void N2kDataToNMEA0183::HandleVariation(const tN2kMsg &N2kMsg) { unsigned char SID; tN2kMagneticVariation Source; uint16_t DaysSince1970; @@ -134,7 +130,7 @@ void tN2kDataToNMEA0183::HandleVariation(const tN2kMsg &N2kMsg) { } //***************************************************************************** -void tN2kDataToNMEA0183::HandleBoatSpeed(const tN2kMsg &N2kMsg) { +void N2kDataToNMEA0183::HandleBoatSpeed(const tN2kMsg &N2kMsg) { unsigned char SID; double WaterReferenced; double GroundReferenced; @@ -151,7 +147,7 @@ void tN2kDataToNMEA0183::HandleBoatSpeed(const tN2kMsg &N2kMsg) { } //***************************************************************************** -void tN2kDataToNMEA0183::HandleDepth(const tN2kMsg &N2kMsg) { +void N2kDataToNMEA0183::HandleDepth(const tN2kMsg &N2kMsg) { unsigned char SID; double DepthBelowTransducer; double Offset; @@ -172,7 +168,7 @@ void tN2kDataToNMEA0183::HandleDepth(const tN2kMsg &N2kMsg) { } //***************************************************************************** -void tN2kDataToNMEA0183::HandlePosition(const tN2kMsg &N2kMsg) { +void N2kDataToNMEA0183::HandlePosition(const tN2kMsg &N2kMsg) { if ( ParseN2kPGN129025(N2kMsg, Latitude, Longitude) ) { LastPositionTime = millis(); @@ -180,7 +176,7 @@ void tN2kDataToNMEA0183::HandlePosition(const tN2kMsg &N2kMsg) { } //***************************************************************************** -void tN2kDataToNMEA0183::HandleCOGSOG(const tN2kMsg &N2kMsg) { +void N2kDataToNMEA0183::HandleCOGSOG(const tN2kMsg &N2kMsg) { unsigned char SID; tN2kHeadingReference HeadingReference; tNMEA0183Msg NMEA0183Msg; @@ -199,7 +195,7 @@ void tN2kDataToNMEA0183::HandleCOGSOG(const tN2kMsg &N2kMsg) { } //***************************************************************************** -void tN2kDataToNMEA0183::HandleGNSS(const tN2kMsg &N2kMsg) { +void N2kDataToNMEA0183::HandleGNSS(const tN2kMsg &N2kMsg) { unsigned char SID; tN2kGNSStype GNSStype; tN2kGNSSmethod GNSSmethod; @@ -220,7 +216,7 @@ void tN2kDataToNMEA0183::HandleGNSS(const tN2kMsg &N2kMsg) { } //***************************************************************************** -void tN2kDataToNMEA0183::HandleWind(const tN2kMsg &N2kMsg) { +void N2kDataToNMEA0183::HandleWind(const tN2kMsg &N2kMsg) { unsigned char SID; tN2kWindReference WindReference; tNMEA0183WindReference NMEA0183Reference = NMEA0183Wind_True; @@ -283,7 +279,7 @@ void tN2kDataToNMEA0183::HandleWind(const tN2kMsg &N2kMsg) { } } //***************************************************************************** - void tN2kDataToNMEA0183::SendRMC() { + void N2kDataToNMEA0183::SendRMC() { if ( NextRMCSend <= millis() && !N2kIsNA(Latitude) ) { tNMEA0183Msg NMEA0183Msg; if ( NMEA0183SetRMC(NMEA0183Msg, SecondsSinceMidnight, Latitude, Longitude, COG, SOG, DaysSince1970, Variation) ) { @@ -295,7 +291,7 @@ void tN2kDataToNMEA0183::HandleWind(const tN2kMsg &N2kMsg) { //***************************************************************************** - void tN2kDataToNMEA0183::HandleLog(const tN2kMsg & N2kMsg) { + void N2kDataToNMEA0183::HandleLog(const tN2kMsg & N2kMsg) { uint16_t DaysSince1970; double SecondsSinceMidnight; @@ -314,7 +310,7 @@ void tN2kDataToNMEA0183::HandleWind(const tN2kMsg &N2kMsg) { } //***************************************************************************** - void tN2kDataToNMEA0183::HandleRudder(const tN2kMsg & N2kMsg) { + void N2kDataToNMEA0183::HandleRudder(const tN2kMsg & N2kMsg) { unsigned char Instance; tN2kRudderDirectionOrder RudderDirectionOrder; @@ -337,7 +333,7 @@ void tN2kDataToNMEA0183::HandleWind(const tN2kMsg &N2kMsg) { } //***************************************************************************** - void tN2kDataToNMEA0183::HandleWaterTemp(const tN2kMsg & N2kMsg) { + void N2kDataToNMEA0183::HandleWaterTemp(const tN2kMsg & N2kMsg) { unsigned char SID; double OutsideAmbientAirTemperature; diff --git a/src/N2kDataToNMEA0183.h b/lib/nmea2kto0183/N2kDataToNMEA0183.h similarity index 89% rename from src/N2kDataToNMEA0183.h rename to lib/nmea2kto0183/N2kDataToNMEA0183.h index 78c8a1c..9b8aed6 100644 --- a/src/N2kDataToNMEA0183.h +++ b/lib/nmea2kto0183/N2kDataToNMEA0183.h @@ -24,12 +24,15 @@ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include -#include "BoatData.h" + +#include +#include //------------------------------------------------------------------------------ -class tN2kDataToNMEA0183 : public tNMEA2000::tMsgHandler { +class N2kDataToNMEA0183 : public tNMEA2000::tMsgHandler { public: using tSendNMEA0183MessageCallback=void (*)(const tNMEA0183Msg &NMEA0183Msg); + protected: static const unsigned long RMCPeriod=500; @@ -69,6 +72,10 @@ protected: unsigned long LastPosSend; unsigned long LastWindTime; unsigned long NextRMCSend; + unsigned long lastLoopTime; + + GwLog *logger; + GwBoatData *boatData; tNMEA0183 *pNMEA0183; tSendNMEA0183MessageCallback SendNMEA0183MessageCallback; @@ -92,22 +99,25 @@ protected: void SendMessage(const tNMEA0183Msg &NMEA0183Msg); public: - tN2kDataToNMEA0183(tNMEA2000 *_pNMEA2000, tNMEA0183 *_pNMEA0183) : tNMEA2000::tMsgHandler(0,_pNMEA2000) { + N2kDataToNMEA0183(GwLog * logger, GwBoatData *boatData, tNMEA2000 *NMEA2000, tNMEA0183 *NMEA0183) : tNMEA2000::tMsgHandler(0,NMEA2000) { SendNMEA0183MessageCallback=0; - pNMEA0183=_pNMEA0183; + pNMEA0183=NMEA0183; Latitude=N2kDoubleNA; Longitude=N2kDoubleNA; Altitude=N2kDoubleNA; Variation=N2kDoubleNA; Heading=N2kDoubleNA; COG=N2kDoubleNA; SOG=N2kDoubleNA; SecondsSinceMidnight=N2kDoubleNA; DaysSince1970=N2kUInt16NA; LastPosSend=0; + lastLoopTime=0; NextRMCSend=millis()+RMCPeriod; LastHeadingTime=0; LastCOGSOGTime=0; LastPositionTime=0; LastWindTime=0; + this->logger=logger; + this->boatData=boatData; } void HandleMsg(const tN2kMsg &N2kMsg); void SetSendNMEA0183MessageCallback(tSendNMEA0183MessageCallback _SendNMEA0183MessageCallback) { SendNMEA0183MessageCallback=_SendNMEA0183MessageCallback; } - long Update(tBoatData *BoatData); + void loop(); }; diff --git a/src/BoatData.h b/src/BoatData.h deleted file mode 100644 index 60868c3..0000000 --- a/src/BoatData.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef _BoatData_H_ -#define _BoatData_H_ - -struct tBoatData { - unsigned long DaysSince1970; // Days since 1970-01-01 - - double Heading,SOG,COG,STW,Variation,AWS,TWS,MaxAws,MaxTws,AWA,TWA,AWD,TWD,TripLog,Log,RudderPosition,WaterTemperature, - WaterDepth, GPSTime,// Secs since midnight, - Latitude, Longitude, Altitude; - -public: - tBoatData() { - Heading=0; - Latitude=0; - Longitude=0; - SOG=0; - COG=0; - STW=0; - AWS=0; - TWS=0; - MaxAws=0; - MaxTws=0; - AWA=0; - TWA=0; - TWD=0; - TripLog=0; - Log=0; - RudderPosition=0; - WaterTemperature=0; - WaterDepth=0; - Variation=0; - Altitude=0; - GPSTime=0; - DaysSince1970=0; - }; -}; - -#endif // _BoatData_H_ diff --git a/src/main.cpp b/src/main.cpp index 6eff578..64de437 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,27 +28,24 @@ #include "N2kDataToNMEA0183.h" -#include "BoatData.h" #include "GwLog.h" #include "GWConfig.h" #include "GWWifi.h" #include "GwSocketServer.h" +#include "GwBoatData.h" -#define ENABLE_DEBUG_LOG 0 // Debug log, set to 1 to enable AIS forward on USB-Serial / 2 for ADC voltage to support calibration #define UDP_Forwarding 0 // Set to 1 for forwarding AIS from serial2 to UDP brodcast -#define NMEA_TO_SERIAL 1 -#define HighTempAlarm 12 // Alarm level for fridge temperature (higher) -#define LowVoltageAlarm 11 // Alarm level for battery voltage (lower) GwLog logger(LOG_SERIAL); GwConfigHandler config(&logger); GwWifi gwWifi(&config,&logger); GwSocketServer socketServer(&config,&logger); +GwBoatData boatData(&logger); //counter @@ -63,9 +60,6 @@ const int udpPort = 2000; // port 2000 lets think Navionics it is an DY WLN10 de // Create UDP instance WiFiUDP udp; -// Struct to update BoatData. See BoatData.h for content -tBoatData BoatData; - int NodeAddress; // To store last Node Address Preferences preferences; // Nonvolatile storage on ESP32 - To store LastDeviceAddress @@ -78,10 +72,7 @@ const size_t MaxClients = 10; bool SendNMEA0183Conversion = true; // Do we send NMEA2000 -> NMEA0183 conversion bool SendSeaSmart = false; // Do we send NMEA2000 messages in SeaSmart format -WiFiServer json(90); - - -tN2kDataToNMEA0183 nmea0183Converter(&NMEA2000, 0); +N2kDataToNMEA0183 nmea0183Converter(&logger, &boatData,&NMEA2000, 0); // Set the information for other bus devices, which messages we support const unsigned long TransmitMessages[] PROGMEM = {127489L, // Engine dynamic @@ -127,11 +118,6 @@ tNMEA0183Msg NMEA0183Msg; tNMEA0183 NMEA0183; -void debug_log(char* str) { -#if ENABLE_DEBUG_LOG == 1 - Serial.println(str); -#endif -} #define JSON_OK "{\"status\":\"OK\"}" //embedded files @@ -168,6 +154,10 @@ void js_config(){ webserver.send(200,F("application/json"),config.toJson()); } +void js_boatData(){ + webserver.send(200,F("application/json"),boatData.toJson()); +} + void web_setConfig(){ bool ok=true; String error; @@ -235,10 +225,6 @@ void setup() { // Start TCP server socketServer.begin(); - // Start JSON server - json.begin(); - - // Start Web Server webserver.on("/", web_index); webserver.on("/api/reset", js_reset); @@ -246,6 +232,7 @@ void setup() { webserver.on("/api/config",js_config); webserver.on("/api/setConfig",web_setConfig); webserver.on("/api/resetConfig",web_resetConfig); + webserver.on("/api/boatData",js_boatData); webserver.onNotFound(handleNotFound); webserver.begin(); @@ -353,74 +340,12 @@ void SendN2kEngine() { } } - - - -void handle_json() { - - WiFiClient client = json.available(); - - // Do we have a client? - if (!client) return; - - // Serial.println(F("New client")); - - // Read the request (we ignore the content in this example) - while (client.available()) client.read(); - - // Allocate JsonBuffer - // Use arduinojson.org/assistant to compute the capacity. - StaticJsonDocument<800> root; - - root["Latitude"] = BoatData.Latitude; - root["Longitude"] = BoatData.Longitude; - root["Heading"] = BoatData.Heading; - root["COG"] = BoatData.COG; - root["SOG"] = BoatData.SOG; - root["STW"] = BoatData.STW; - root["AWS"] = BoatData.AWS; - root["TWS"] = BoatData.TWS; - root["MaxAws"] = BoatData.MaxAws; - root["MaxTws"] = BoatData.MaxTws; - root["AWA"] = BoatData.AWA; - root["TWA"] = BoatData.TWA; - root["TWD"] = BoatData.TWD; - root["TripLog"] = BoatData.TripLog; - root["Log"] = BoatData.Log; - root["RudderPosition"] = BoatData.RudderPosition; - root["WaterTemperature"] = BoatData.WaterTemperature; - root["WaterDepth"] = BoatData.WaterDepth; - root["Variation"] = BoatData.Variation; - root["Altitude"] = BoatData.Altitude; - root["GPSTime"] = BoatData.GPSTime; - root["DaysSince1970"] = BoatData.DaysSince1970; - - - //Serial.print(F("Sending: ")); - //serializeJson(root, Serial); - //Serial.println(); - - // Write response headers - client.println("HTTP/1.0 200 OK"); - client.println("Content-Type: application/json"); - client.println("Connection: close"); - client.println(); - - // Write JSON document - serializeJsonPretty(root, client); - - // Disconnect - client.stop(); -} - - long lastLog=millis(); void loop() { unsigned int size; int wifi_retry; webserver.handleClient(); gwWifi.loop(); - handle_json(); if (NMEA0183.GetMessage(NMEA0183Msg)) { // Get AIS NMEA sentences from serial2 @@ -428,9 +353,7 @@ void loop() { NMEA0183Msg.GetMessage(buff, MAX_NMEA0183_MESSAGE_SIZE); // send to buffer -#if ENABLE_DEBUG_LOG == 1 - Serial.println(buff); -#endif + #if UDP_Forwarding == 1 size = strlen(buff); @@ -453,7 +376,7 @@ void loop() { Serial.printf("Address Change: New Address=%d\n", SourceAddress); } - nmea0183Converter.Update(&BoatData); + nmea0183Converter.loop(); // Dummy to empty input buffer to avoid board to stuck with e.g. NMEA Reader if ( Serial.available() ) {