mirror of
https://github.com/thooge/esp32-nmea2000-obp60.git
synced 2025-12-15 15:03:07 +01:00
separate boat data, integrate with web server
This commit is contained in:
@@ -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_
|
||||
@@ -1,356 +0,0 @@
|
||||
/*
|
||||
N2kDataToNMEA0183.cpp
|
||||
|
||||
Copyright (c) 2015-2018 Timo Lappalainen, Kave Oy, www.kave.fi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <N2kMessages.h>
|
||||
#include <NMEA0183Messages.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "N2kDataToNMEA0183.h"
|
||||
#include "BoatData.h"
|
||||
|
||||
const double radToDeg = 180.0 / M_PI;
|
||||
|
||||
//*****************************************************************************
|
||||
void tN2kDataToNMEA0183::HandleMsg(const tN2kMsg &N2kMsg) {
|
||||
switch (N2kMsg.PGN) {
|
||||
case 127250UL: HandleHeading(N2kMsg);
|
||||
case 127258UL: HandleVariation(N2kMsg);
|
||||
case 128259UL: HandleBoatSpeed(N2kMsg);
|
||||
case 128267UL: HandleDepth(N2kMsg);
|
||||
case 129025UL: HandlePosition(N2kMsg);
|
||||
case 129026UL: HandleCOGSOG(N2kMsg);
|
||||
case 129029UL: HandleGNSS(N2kMsg);
|
||||
case 130306UL: HandleWind(N2kMsg);
|
||||
case 128275UL: HandleLog(N2kMsg);
|
||||
case 127245UL: HandleRudder(N2kMsg);
|
||||
case 130310UL: HandleWaterTemp(N2kMsg);
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
long tN2kDataToNMEA0183::Update(tBoatData *BoatData) {
|
||||
SendRMC();
|
||||
if ( LastHeadingTime + 2000 < millis() ) Heading = N2kDoubleNA;
|
||||
if ( LastCOGSOGTime + 2000 < millis() ) {
|
||||
COG = N2kDoubleNA;
|
||||
SOG = N2kDoubleNA;
|
||||
}
|
||||
if ( LastPositionTime + 4000 < millis() ) {
|
||||
Latitude = N2kDoubleNA;
|
||||
Longitude = N2kDoubleNA;
|
||||
}
|
||||
if ( LastWindTime + 2000 < millis() ) {
|
||||
AWS = N2kDoubleNA;
|
||||
AWA = N2kDoubleNA;
|
||||
TWS = N2kDoubleNA;
|
||||
TWA = N2kDoubleNA;
|
||||
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;
|
||||
|
||||
|
||||
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) {
|
||||
if ( pNMEA0183 != 0 ) pNMEA0183->SendMessage(NMEA0183Msg);
|
||||
if ( SendNMEA0183MessageCallback != 0 ) SendNMEA0183MessageCallback(NMEA0183Msg);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
void tN2kDataToNMEA0183::HandleHeading(const tN2kMsg &N2kMsg) {
|
||||
unsigned char SID;
|
||||
tN2kHeadingReference ref;
|
||||
double _Deviation = 0;
|
||||
double _Variation;
|
||||
tNMEA0183Msg NMEA0183Msg;
|
||||
|
||||
if ( ParseN2kHeading(N2kMsg, SID, Heading, _Deviation, _Variation, ref) ) {
|
||||
if ( ref == N2khr_magnetic ) {
|
||||
if ( !N2kIsNA(_Variation) ) Variation = _Variation; // Update Variation
|
||||
if ( !N2kIsNA(Heading) && !N2kIsNA(Variation) ) Heading -= Variation;
|
||||
}
|
||||
LastHeadingTime = millis();
|
||||
if ( NMEA0183SetHDG(NMEA0183Msg, Heading, _Deviation, Variation) ) {
|
||||
SendMessage(NMEA0183Msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
void tN2kDataToNMEA0183::HandleVariation(const tN2kMsg &N2kMsg) {
|
||||
unsigned char SID;
|
||||
tN2kMagneticVariation Source;
|
||||
uint16_t DaysSince1970;
|
||||
|
||||
ParseN2kMagneticVariation(N2kMsg, SID, Source, DaysSince1970, Variation);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
void tN2kDataToNMEA0183::HandleBoatSpeed(const tN2kMsg &N2kMsg) {
|
||||
unsigned char SID;
|
||||
double WaterReferenced;
|
||||
double GroundReferenced;
|
||||
tN2kSpeedWaterReferenceType SWRT;
|
||||
|
||||
if ( ParseN2kBoatSpeed(N2kMsg, SID, WaterReferenced, GroundReferenced, SWRT) ) {
|
||||
tNMEA0183Msg NMEA0183Msg;
|
||||
STW=WaterReferenced;
|
||||
double MagneticHeading = ( !N2kIsNA(Heading) && !N2kIsNA(Variation) ? Heading + Variation : NMEA0183DoubleNA);
|
||||
if ( NMEA0183SetVHW(NMEA0183Msg, Heading, MagneticHeading, WaterReferenced) ) {
|
||||
SendMessage(NMEA0183Msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
void tN2kDataToNMEA0183::HandleDepth(const tN2kMsg &N2kMsg) {
|
||||
unsigned char SID;
|
||||
double DepthBelowTransducer;
|
||||
double Offset;
|
||||
double Range;
|
||||
|
||||
if ( ParseN2kWaterDepth(N2kMsg, SID, DepthBelowTransducer, Offset, Range) ) {
|
||||
|
||||
WaterDepth=DepthBelowTransducer+Offset;
|
||||
|
||||
tNMEA0183Msg NMEA0183Msg;
|
||||
if ( NMEA0183SetDPT(NMEA0183Msg, DepthBelowTransducer, Offset) ) {
|
||||
SendMessage(NMEA0183Msg);
|
||||
}
|
||||
if ( NMEA0183SetDBx(NMEA0183Msg, DepthBelowTransducer, Offset) ) {
|
||||
SendMessage(NMEA0183Msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
void tN2kDataToNMEA0183::HandlePosition(const tN2kMsg &N2kMsg) {
|
||||
|
||||
if ( ParseN2kPGN129025(N2kMsg, Latitude, Longitude) ) {
|
||||
LastPositionTime = millis();
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
void tN2kDataToNMEA0183::HandleCOGSOG(const tN2kMsg &N2kMsg) {
|
||||
unsigned char SID;
|
||||
tN2kHeadingReference HeadingReference;
|
||||
tNMEA0183Msg NMEA0183Msg;
|
||||
|
||||
if ( ParseN2kCOGSOGRapid(N2kMsg, SID, HeadingReference, COG, SOG) ) {
|
||||
LastCOGSOGTime = millis();
|
||||
double MCOG = ( !N2kIsNA(COG) && !N2kIsNA(Variation) ? COG - Variation : NMEA0183DoubleNA );
|
||||
if ( HeadingReference == N2khr_magnetic ) {
|
||||
MCOG = COG;
|
||||
if ( !N2kIsNA(Variation) ) COG -= Variation;
|
||||
}
|
||||
if ( NMEA0183SetVTG(NMEA0183Msg, COG, MCOG, SOG) ) {
|
||||
SendMessage(NMEA0183Msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
void tN2kDataToNMEA0183::HandleGNSS(const tN2kMsg &N2kMsg) {
|
||||
unsigned char SID;
|
||||
tN2kGNSStype GNSStype;
|
||||
tN2kGNSSmethod GNSSmethod;
|
||||
unsigned char nSatellites;
|
||||
double HDOP;
|
||||
double PDOP;
|
||||
double GeoidalSeparation;
|
||||
unsigned char nReferenceStations;
|
||||
tN2kGNSStype ReferenceStationType;
|
||||
uint16_t ReferenceSationID;
|
||||
double AgeOfCorrection;
|
||||
|
||||
if ( ParseN2kGNSS(N2kMsg, SID, DaysSince1970, SecondsSinceMidnight, Latitude, Longitude, Altitude, GNSStype, GNSSmethod,
|
||||
nSatellites, HDOP, PDOP, GeoidalSeparation,
|
||||
nReferenceStations, ReferenceStationType, ReferenceSationID, AgeOfCorrection) ) {
|
||||
LastPositionTime = millis();
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
void tN2kDataToNMEA0183::HandleWind(const tN2kMsg &N2kMsg) {
|
||||
unsigned char SID;
|
||||
tN2kWindReference WindReference;
|
||||
tNMEA0183WindReference NMEA0183Reference = NMEA0183Wind_True;
|
||||
|
||||
double x, y;
|
||||
double WindAngle, WindSpeed;
|
||||
|
||||
// double TWS, TWA, AWD;
|
||||
|
||||
if ( ParseN2kWindSpeed(N2kMsg, SID, WindSpeed, WindAngle, WindReference) ) {
|
||||
tNMEA0183Msg NMEA0183Msg;
|
||||
LastWindTime = millis();
|
||||
|
||||
if ( WindReference == N2kWind_Apparent ) {
|
||||
NMEA0183Reference = NMEA0183Wind_Apparent;
|
||||
AWA=WindAngle;
|
||||
AWS=WindSpeed;
|
||||
if (AWS > MaxAws) MaxAws=AWS;
|
||||
}
|
||||
|
||||
if ( NMEA0183SetMWV(NMEA0183Msg, WindAngle*radToDeg, NMEA0183Reference , WindSpeed)) SendMessage(NMEA0183Msg);
|
||||
|
||||
if (WindReference == N2kWind_Apparent && SOG != N2kDoubleNA) { // Lets calculate and send TWS/TWA if SOG is available
|
||||
|
||||
AWD=WindAngle*radToDeg + Heading*radToDeg;
|
||||
if (AWD>360) AWD=AWD-360;
|
||||
if (AWD<0) AWD=AWD+360;
|
||||
|
||||
x = WindSpeed * cos(WindAngle);
|
||||
y = WindSpeed * sin(WindAngle);
|
||||
|
||||
TWA = atan2(y, -SOG + x);
|
||||
TWS = sqrt(( y*y) + ((-SOG+x)*(-SOG+x)));
|
||||
|
||||
if (TWS > MaxTws) MaxTws=TWS;
|
||||
|
||||
TWA = TWA * radToDeg +360;
|
||||
|
||||
if (TWA>360) TWA=TWA-360;
|
||||
if (TWA<0) TWA=TWA+360;
|
||||
|
||||
NMEA0183Reference = NMEA0183Wind_True;
|
||||
if ( NMEA0183SetMWV(NMEA0183Msg, TWA, NMEA0183Reference , TWS)) SendMessage(NMEA0183Msg);
|
||||
|
||||
if ( !NMEA0183Msg.Init("MWD", "GP") ) return;
|
||||
if ( !NMEA0183Msg.AddDoubleField(AWD) ) return;
|
||||
if ( !NMEA0183Msg.AddStrField("T") ) return;
|
||||
if ( !NMEA0183Msg.AddDoubleField(AWD) ) return;
|
||||
if ( !NMEA0183Msg.AddStrField("M") ) return;
|
||||
if ( !NMEA0183Msg.AddDoubleField(TWS/0.514444) ) return;
|
||||
if ( !NMEA0183Msg.AddStrField("N") ) return;
|
||||
if ( !NMEA0183Msg.AddDoubleField(TWS) ) return;
|
||||
if ( !NMEA0183Msg.AddStrField("M") ) return;
|
||||
|
||||
SendMessage(NMEA0183Msg);
|
||||
|
||||
TWA=TWA/radToDeg;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
//*****************************************************************************
|
||||
void tN2kDataToNMEA0183::SendRMC() {
|
||||
if ( NextRMCSend <= millis() && !N2kIsNA(Latitude) ) {
|
||||
tNMEA0183Msg NMEA0183Msg;
|
||||
if ( NMEA0183SetRMC(NMEA0183Msg, SecondsSinceMidnight, Latitude, Longitude, COG, SOG, DaysSince1970, Variation) ) {
|
||||
SendMessage(NMEA0183Msg);
|
||||
}
|
||||
SetNextRMCSend();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
void tN2kDataToNMEA0183::HandleLog(const tN2kMsg & N2kMsg) {
|
||||
uint16_t DaysSince1970;
|
||||
double SecondsSinceMidnight;
|
||||
|
||||
if ( ParseN2kDistanceLog(N2kMsg, DaysSince1970, SecondsSinceMidnight, Log, TripLog) ) {
|
||||
|
||||
tNMEA0183Msg NMEA0183Msg;
|
||||
|
||||
if ( !NMEA0183Msg.Init("VLW", "GP") ) return;
|
||||
if ( !NMEA0183Msg.AddDoubleField(Log / 1852.0) ) return;
|
||||
if ( !NMEA0183Msg.AddStrField("N") ) return;
|
||||
if ( !NMEA0183Msg.AddDoubleField(TripLog / 1852.0) ) return;
|
||||
if ( !NMEA0183Msg.AddStrField("N") ) return;
|
||||
|
||||
SendMessage(NMEA0183Msg);
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
void tN2kDataToNMEA0183::HandleRudder(const tN2kMsg & N2kMsg) {
|
||||
|
||||
unsigned char Instance;
|
||||
tN2kRudderDirectionOrder RudderDirectionOrder;
|
||||
double AngleOrder;
|
||||
|
||||
if ( ParseN2kRudder(N2kMsg, RudderPosition, Instance, RudderDirectionOrder, AngleOrder) ) {
|
||||
|
||||
if(Instance!=0) return;
|
||||
|
||||
tNMEA0183Msg NMEA0183Msg;
|
||||
|
||||
if ( !NMEA0183Msg.Init("RSA", "GP") ) return;
|
||||
if ( !NMEA0183Msg.AddDoubleField(RudderPosition * radToDeg) ) return;
|
||||
if ( !NMEA0183Msg.AddStrField("A") ) return;
|
||||
if ( !NMEA0183Msg.AddDoubleField(0.0) ) return;
|
||||
if ( !NMEA0183Msg.AddStrField("A") ) return;
|
||||
|
||||
SendMessage(NMEA0183Msg);
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
void tN2kDataToNMEA0183::HandleWaterTemp(const tN2kMsg & N2kMsg) {
|
||||
|
||||
unsigned char SID;
|
||||
double OutsideAmbientAirTemperature;
|
||||
double AtmosphericPressure;
|
||||
|
||||
if ( ParseN2kPGN130310(N2kMsg, SID, WaterTemperature, OutsideAmbientAirTemperature, AtmosphericPressure) ) {
|
||||
|
||||
tNMEA0183Msg NMEA0183Msg;
|
||||
|
||||
if ( !NMEA0183Msg.Init("MTW", "GP") ) return;
|
||||
if ( !NMEA0183Msg.AddDoubleField(KelvinToC(WaterTemperature))) return;
|
||||
if ( !NMEA0183Msg.AddStrField("C") ) return;
|
||||
|
||||
SendMessage(NMEA0183Msg);
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
N2kDataToNMEA0183.h
|
||||
|
||||
Copyright (c) 2015-2018 Timo Lappalainen, Kave Oy, www.kave.fi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <NMEA0183.h>
|
||||
#include <NMEA2000.h>
|
||||
|
||||
#include "BoatData.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class tN2kDataToNMEA0183 : public tNMEA2000::tMsgHandler {
|
||||
public:
|
||||
using tSendNMEA0183MessageCallback=void (*)(const tNMEA0183Msg &NMEA0183Msg);
|
||||
|
||||
protected:
|
||||
static const unsigned long RMCPeriod=500;
|
||||
double Latitude;
|
||||
double Longitude;
|
||||
double Altitude;
|
||||
double Variation;
|
||||
double Heading;
|
||||
double COG;
|
||||
double SOG;
|
||||
double STW;
|
||||
|
||||
double TWS;
|
||||
double TWA;
|
||||
double TWD;
|
||||
|
||||
double AWS;
|
||||
double AWA;
|
||||
double AWD;
|
||||
|
||||
double MaxAws;
|
||||
double MaxTws;
|
||||
|
||||
double RudderPosition;
|
||||
double WaterTemperature;
|
||||
double WaterDepth;
|
||||
|
||||
uint32_t TripLog;
|
||||
uint32_t Log;
|
||||
|
||||
uint16_t DaysSince1970;
|
||||
double SecondsSinceMidnight;
|
||||
|
||||
unsigned long LastHeadingTime;
|
||||
unsigned long LastCOGSOGTime;
|
||||
unsigned long LastPositionTime;
|
||||
unsigned long LastPosSend;
|
||||
unsigned long LastWindTime;
|
||||
unsigned long NextRMCSend;
|
||||
|
||||
tNMEA0183 *pNMEA0183;
|
||||
tSendNMEA0183MessageCallback SendNMEA0183MessageCallback;
|
||||
|
||||
protected:
|
||||
void HandleHeading(const tN2kMsg &N2kMsg); // 127250
|
||||
void HandleVariation(const tN2kMsg &N2kMsg); // 127258
|
||||
void HandleBoatSpeed(const tN2kMsg &N2kMsg); // 128259
|
||||
void HandleDepth(const tN2kMsg &N2kMsg); // 128267
|
||||
void HandlePosition(const tN2kMsg &N2kMsg); // 129025
|
||||
void HandleCOGSOG(const tN2kMsg &N2kMsg); // 129026
|
||||
void HandleGNSS(const tN2kMsg &N2kMsg); // 129029
|
||||
void HandleWind(const tN2kMsg &N2kMsg); // 130306
|
||||
void HandleLog(const tN2kMsg &N2kMsg); // 128275
|
||||
void HandleRudder(const tN2kMsg &N2kMsg); // 127245
|
||||
void HandleWaterTemp(const tN2kMsg &N2kMsg); // 130310
|
||||
|
||||
|
||||
void SetNextRMCSend() { NextRMCSend=millis()+RMCPeriod; }
|
||||
void SendRMC();
|
||||
void SendMessage(const tNMEA0183Msg &NMEA0183Msg);
|
||||
|
||||
public:
|
||||
tN2kDataToNMEA0183(tNMEA2000 *_pNMEA2000, tNMEA0183 *_pNMEA0183) : tNMEA2000::tMsgHandler(0,_pNMEA2000) {
|
||||
SendNMEA0183MessageCallback=0;
|
||||
pNMEA0183=_pNMEA0183;
|
||||
Latitude=N2kDoubleNA; Longitude=N2kDoubleNA; Altitude=N2kDoubleNA;
|
||||
Variation=N2kDoubleNA; Heading=N2kDoubleNA; COG=N2kDoubleNA; SOG=N2kDoubleNA;
|
||||
SecondsSinceMidnight=N2kDoubleNA; DaysSince1970=N2kUInt16NA;
|
||||
LastPosSend=0;
|
||||
NextRMCSend=millis()+RMCPeriod;
|
||||
LastHeadingTime=0;
|
||||
LastCOGSOGTime=0;
|
||||
LastPositionTime=0;
|
||||
LastWindTime=0;
|
||||
}
|
||||
void HandleMsg(const tN2kMsg &N2kMsg);
|
||||
void SetSendNMEA0183MessageCallback(tSendNMEA0183MessageCallback _SendNMEA0183MessageCallback) {
|
||||
SendNMEA0183MessageCallback=_SendNMEA0183MessageCallback;
|
||||
}
|
||||
long Update(tBoatData *BoatData);
|
||||
};
|
||||
97
src/main.cpp
97
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() ) {
|
||||
|
||||
Reference in New Issue
Block a user