completely moved to dynamic boatData, first tests
This commit is contained in:
parent
e1e3928062
commit
940d7ea957
|
@ -8,21 +8,24 @@
|
||||||
#define GW_BOAT_VALUE_LEN 32
|
#define GW_BOAT_VALUE_LEN 32
|
||||||
class GwBoatItemBase{
|
class GwBoatItemBase{
|
||||||
public:
|
public:
|
||||||
static const long INVALID_TIME=60000;
|
static const unsigned long INVALID_TIME=60000;
|
||||||
typedef std::map<String,GwBoatItemBase*> GwBoatItemMap;
|
typedef std::map<String,GwBoatItemBase*> GwBoatItemMap;
|
||||||
protected:
|
protected:
|
||||||
long lastSet;
|
unsigned long lastSet=0;
|
||||||
long invalidTime=INVALID_TIME;
|
unsigned long invalidTime=INVALID_TIME;
|
||||||
void uls(){
|
void uls(){
|
||||||
lastSet=millis();
|
lastSet=millis();
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
long getLastSet() const {return lastSet;}
|
unsigned long getLastSet() const {return lastSet;}
|
||||||
bool isValid(long now) const {
|
bool isValid(unsigned long now=0) const {
|
||||||
|
if (lastSet == 0) return false;
|
||||||
|
if (invalidTime == 0) return true;
|
||||||
|
if (now == 0) now=millis();
|
||||||
return (lastSet + invalidTime) >= now;
|
return (lastSet + invalidTime) >= now;
|
||||||
}
|
}
|
||||||
GwBoatItemBase(long invalidTime=INVALID_TIME){
|
GwBoatItemBase(unsigned long invalidTime=INVALID_TIME){
|
||||||
lastSet=-1;
|
lastSet=0;
|
||||||
this->invalidTime=invalidTime;
|
this->invalidTime=invalidTime;
|
||||||
}
|
}
|
||||||
virtual ~GwBoatItemBase(){}
|
virtual ~GwBoatItemBase(){}
|
||||||
|
@ -39,7 +42,8 @@ template<class T> class GwBoatItem : public GwBoatItemBase{
|
||||||
T data;
|
T data;
|
||||||
Formatter fmt;
|
Formatter fmt;
|
||||||
public:
|
public:
|
||||||
GwBoatItem(long invalidTime=INVALID_TIME,Formatter fmt=NULL): GwBoatItemBase(invalidTime){
|
GwBoatItem(unsigned long invalidTime=INVALID_TIME,Formatter fmt=NULL):
|
||||||
|
GwBoatItemBase(invalidTime){
|
||||||
this->fmt=fmt;
|
this->fmt=fmt;
|
||||||
}
|
}
|
||||||
virtual ~GwBoatItem(){}
|
virtual ~GwBoatItem(){}
|
||||||
|
@ -51,6 +55,10 @@ template<class T> class GwBoatItem : public GwBoatItemBase{
|
||||||
if (! useFormatter || fmt == NULL) return data;
|
if (! useFormatter || fmt == NULL) return data;
|
||||||
return (*fmt)(data);
|
return (*fmt)(data);
|
||||||
}
|
}
|
||||||
|
T getDataWithDefault(T defaultv){
|
||||||
|
if (! isValid(millis())) return defaultv;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
virtual void toJsonDoc(DynamicJsonDocument *doc,String name){
|
virtual void toJsonDoc(DynamicJsonDocument *doc,String name){
|
||||||
(*doc)[name]=getData(true);
|
(*doc)[name]=getData(true);
|
||||||
}
|
}
|
||||||
|
@ -69,6 +77,10 @@ template<class T> class GwBoatItem : public GwBoatItemBase{
|
||||||
friend class GwBoatData;
|
friend class GwBoatData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* implement a get for a particular type of boatData
|
||||||
|
* will create a method get##name##Item that returns a GwBoatItem<type>
|
||||||
|
* */
|
||||||
#define GWBOATDATA_IMPL_ITEM(type,name) GwBoatItem<type> *get##name##Item(String iname,bool doCreate=true, \
|
#define GWBOATDATA_IMPL_ITEM(type,name) GwBoatItem<type> *get##name##Item(String iname,bool doCreate=true, \
|
||||||
long invalidTime=GwBoatItemBase::INVALID_TIME, GwBoatItem<type>::Formatter fmt=NULL){ \
|
long invalidTime=GwBoatItemBase::INVALID_TIME, GwBoatItem<type>::Formatter fmt=NULL){ \
|
||||||
return GwBoatItem<type>::findOrCreate(&values,iname, doCreate, \
|
return GwBoatItem<type>::findOrCreate(&values,iname, doCreate, \
|
||||||
|
@ -84,7 +96,8 @@ class GwBoatData{
|
||||||
~GwBoatData();
|
~GwBoatData();
|
||||||
String toJson() const;
|
String toJson() const;
|
||||||
GWBOATDATA_IMPL_ITEM(double,Double)
|
GWBOATDATA_IMPL_ITEM(double,Double)
|
||||||
GWBOATDATA_IMPL_ITEM(long,Long)
|
GWBOATDATA_IMPL_ITEM(long,Long)
|
||||||
|
GWBOATDATA_IMPL_ITEM(uint32_t,Uint32)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,24 +31,43 @@ const double radToDeg = 180.0 / M_PI;
|
||||||
|
|
||||||
static void updateDouble(GwBoatItem<double> *item,double value){
|
static void updateDouble(GwBoatItem<double> *item,double value){
|
||||||
if (value == N2kDoubleNA) return;
|
if (value == N2kDoubleNA) return;
|
||||||
|
if (! item) return;
|
||||||
item->update(value);
|
item->update(value);
|
||||||
}
|
}
|
||||||
static double formatCourse(double cv){
|
static double formatCourse(double cv){
|
||||||
return cv * radToDeg;
|
double rt=cv * radToDeg;
|
||||||
|
if (rt > 360) rt-=360;
|
||||||
|
if (rt <0) rt+=360;
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
static double formatWind(double cv){
|
||||||
|
double rt=formatCourse(cv);
|
||||||
|
if (rt > 180) rt=180-rt;
|
||||||
|
return rt;
|
||||||
}
|
}
|
||||||
static double formatKnots(double cv){
|
static double formatKnots(double cv){
|
||||||
return cv* 3600.0/1852.0;
|
return cv* 3600.0/1852.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t mtr2nm(uint32_t m){
|
||||||
|
return m/1852;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setMax(GwBoatItem<double> *maxItem,GwBoatItem<double> *item){
|
||||||
|
unsigned long now=millis();
|
||||||
|
if (! item->isValid(now)) return;
|
||||||
|
if(item->getData() > maxItem->getData() || ! maxItem->isValid(now)){
|
||||||
|
maxItem->update(item->getData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
N2kDataToNMEA0183::N2kDataToNMEA0183(GwLog * logger, GwBoatData *boatData, tNMEA2000 *NMEA2000, tNMEA0183 *NMEA0183) : tNMEA2000::tMsgHandler(0,NMEA2000){
|
N2kDataToNMEA0183::N2kDataToNMEA0183(GwLog * logger, GwBoatData *boatData, tNMEA2000 *NMEA2000, tNMEA0183 *NMEA0183) : tNMEA2000::tMsgHandler(0,NMEA2000){
|
||||||
SendNMEA0183MessageCallback=0;
|
SendNMEA0183MessageCallback=0;
|
||||||
pNMEA0183=NMEA0183;
|
pNMEA0183=NMEA0183;
|
||||||
Variation=N2kDoubleNA;
|
|
||||||
SecondsSinceMidnight=N2kDoubleNA; DaysSince1970=N2kUInt16NA;
|
|
||||||
LastPosSend=0;
|
LastPosSend=0;
|
||||||
lastLoopTime=0;
|
lastLoopTime=0;
|
||||||
NextRMCSend=millis()+RMCPeriod;
|
NextRMCSend=millis()+RMCPeriod;
|
||||||
LastWindTime=0;
|
|
||||||
this->logger=logger;
|
this->logger=logger;
|
||||||
this->boatData=boatData;
|
this->boatData=boatData;
|
||||||
heading=boatData->getDoubleItem(F("Heading"),true,2000,&formatCourse);
|
heading=boatData->getDoubleItem(F("Heading"),true,2000,&formatCourse);
|
||||||
|
@ -57,6 +76,22 @@ N2kDataToNMEA0183::N2kDataToNMEA0183(GwLog * logger, GwBoatData *boatData, tNMEA
|
||||||
altitude=boatData->getDoubleItem(F("Altitude"),true,4000);
|
altitude=boatData->getDoubleItem(F("Altitude"),true,4000);
|
||||||
cog=boatData->getDoubleItem(F("COG"),true,2000,&formatCourse);
|
cog=boatData->getDoubleItem(F("COG"),true,2000,&formatCourse);
|
||||||
sog=boatData->getDoubleItem(F("SOG"),true,2000,&formatKnots);
|
sog=boatData->getDoubleItem(F("SOG"),true,2000,&formatKnots);
|
||||||
|
stw=boatData->getDoubleItem(F("STW"),true,2000,&formatKnots);
|
||||||
|
variation=boatData->getDoubleItem(F("Variation"),true,2000,&formatCourse);
|
||||||
|
tws=boatData->getDoubleItem(F("TWS"),true,2000,&formatKnots);
|
||||||
|
twd=boatData->getDoubleItem(F("TWD"),true,2000,&formatCourse);
|
||||||
|
aws=boatData->getDoubleItem(F("AWS"),true,2000,&formatKnots);
|
||||||
|
awa=boatData->getDoubleItem(F("AWA"),true,2000,&formatWind);
|
||||||
|
awd=boatData->getDoubleItem(F("AWD"),true,2000,&formatCourse);
|
||||||
|
maxAws=boatData->getDoubleItem(F("MaxAws"),true,0,&formatKnots);
|
||||||
|
maxTws=boatData->getDoubleItem(F("MaxTws"),true,0,&formatKnots);
|
||||||
|
rudderPosition=boatData->getDoubleItem(F("RudderPosition"),true,2000,&formatCourse);
|
||||||
|
waterTemperature=boatData->getDoubleItem(F("WaterTemperature"),true,2000,&KelvinToC);
|
||||||
|
waterDepth=boatData->getDoubleItem(F("WaterDepth"),true,2000);
|
||||||
|
log=boatData->getUint32Item(F("Log"),true,0,mtr2nm);
|
||||||
|
tripLog=boatData->getUint32Item(F("TripLog"),true,0,mtr2nm);
|
||||||
|
daysSince1970=boatData->getUint32Item(F("DaysSince1970"),true,2000);
|
||||||
|
secondsSinceMidnight=boatData->getDoubleItem(F("SecondsSinceMidnight"),true,2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
@ -82,37 +117,6 @@ void N2kDataToNMEA0183::loop() {
|
||||||
if ( now < (lastLoopTime + 100)) return;
|
if ( now < (lastLoopTime + 100)) return;
|
||||||
lastLoopTime=now;
|
lastLoopTime=now;
|
||||||
SendRMC();
|
SendRMC();
|
||||||
if ( ( LastWindTime + 2000) < now ) {
|
|
||||||
AWS = N2kDoubleNA;
|
|
||||||
AWA = N2kDoubleNA;
|
|
||||||
TWS = N2kDoubleNA;
|
|
||||||
TWA = N2kDoubleNA;
|
|
||||||
TWD = N2kDoubleNA;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
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);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
@ -126,16 +130,16 @@ void N2kDataToNMEA0183::HandleHeading(const tN2kMsg &N2kMsg) {
|
||||||
unsigned char SID;
|
unsigned char SID;
|
||||||
tN2kHeadingReference ref;
|
tN2kHeadingReference ref;
|
||||||
double _Deviation = 0;
|
double _Deviation = 0;
|
||||||
double _Variation;
|
double Variation;
|
||||||
tNMEA0183Msg NMEA0183Msg;
|
tNMEA0183Msg NMEA0183Msg;
|
||||||
double Heading;
|
double Heading;
|
||||||
if ( ParseN2kHeading(N2kMsg, SID, Heading, _Deviation, _Variation, ref) ) {
|
if ( ParseN2kHeading(N2kMsg, SID, Heading, _Deviation, Variation, ref) ) {
|
||||||
if ( ref == N2khr_magnetic ) {
|
if ( ref == N2khr_magnetic ) {
|
||||||
if ( !N2kIsNA(_Variation) ) Variation = _Variation; // Update Variation
|
updateDouble(variation,Variation); // Update Variation
|
||||||
if ( !N2kIsNA(Heading) && !N2kIsNA(Variation) ) Heading -= Variation;
|
if ( !N2kIsNA(Heading) && variation->isValid(millis()) ) Heading -= variation->getData();
|
||||||
}
|
}
|
||||||
updateDouble(heading,Heading);
|
updateDouble(heading,Heading);
|
||||||
if ( NMEA0183SetHDG(NMEA0183Msg, Heading, _Deviation, Variation) ) {
|
if ( NMEA0183SetHDG(NMEA0183Msg, heading->getDataWithDefault(NMEA0183DoubleNA), _Deviation, variation->getDataWithDefault(NMEA0183DoubleNA)) ) {
|
||||||
SendMessage(NMEA0183Msg);
|
SendMessage(NMEA0183Msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,8 +150,10 @@ void N2kDataToNMEA0183::HandleVariation(const tN2kMsg &N2kMsg) {
|
||||||
unsigned char SID;
|
unsigned char SID;
|
||||||
tN2kMagneticVariation Source;
|
tN2kMagneticVariation Source;
|
||||||
uint16_t DaysSince1970;
|
uint16_t DaysSince1970;
|
||||||
|
double Variation;
|
||||||
ParseN2kMagneticVariation(N2kMsg, SID, Source, DaysSince1970, Variation);
|
ParseN2kMagneticVariation(N2kMsg, SID, Source, DaysSince1970, Variation);
|
||||||
|
updateDouble(variation,Variation);
|
||||||
|
if (DaysSince1970 != N2kUInt16NA && DaysSince1970 != 0) daysSince1970->update(DaysSince1970);
|
||||||
}
|
}
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
@ -159,8 +165,9 @@ void N2kDataToNMEA0183::HandleBoatSpeed(const tN2kMsg &N2kMsg) {
|
||||||
|
|
||||||
if ( ParseN2kBoatSpeed(N2kMsg, SID, WaterReferenced, GroundReferenced, SWRT) ) {
|
if ( ParseN2kBoatSpeed(N2kMsg, SID, WaterReferenced, GroundReferenced, SWRT) ) {
|
||||||
tNMEA0183Msg NMEA0183Msg;
|
tNMEA0183Msg NMEA0183Msg;
|
||||||
STW=WaterReferenced;
|
updateDouble(stw,WaterReferenced);
|
||||||
double MagneticHeading = ( heading->isValid(millis()) && !N2kIsNA(Variation) ? heading->getData() + Variation : NMEA0183DoubleNA);
|
unsigned long now=millis();
|
||||||
|
double MagneticHeading = ( heading->isValid(now) && variation->isValid(now)) ? heading->getData() + variation->getData() : NMEA0183DoubleNA;
|
||||||
if ( NMEA0183SetVHW(NMEA0183Msg, heading->getData(), MagneticHeading, WaterReferenced) ) {
|
if ( NMEA0183SetVHW(NMEA0183Msg, heading->getData(), MagneticHeading, WaterReferenced) ) {
|
||||||
SendMessage(NMEA0183Msg);
|
SendMessage(NMEA0183Msg);
|
||||||
}
|
}
|
||||||
|
@ -173,11 +180,11 @@ void N2kDataToNMEA0183::HandleDepth(const tN2kMsg &N2kMsg) {
|
||||||
double DepthBelowTransducer;
|
double DepthBelowTransducer;
|
||||||
double Offset;
|
double Offset;
|
||||||
double Range;
|
double Range;
|
||||||
|
double WaterDepth;
|
||||||
if ( ParseN2kWaterDepth(N2kMsg, SID, DepthBelowTransducer, Offset, Range) ) {
|
if ( ParseN2kWaterDepth(N2kMsg, SID, DepthBelowTransducer, Offset, Range) ) {
|
||||||
|
|
||||||
WaterDepth=DepthBelowTransducer+Offset;
|
WaterDepth=DepthBelowTransducer+Offset;
|
||||||
|
updateDouble(waterDepth,WaterDepth);
|
||||||
tNMEA0183Msg NMEA0183Msg;
|
tNMEA0183Msg NMEA0183Msg;
|
||||||
if ( NMEA0183SetDPT(NMEA0183Msg, DepthBelowTransducer, Offset) ) {
|
if ( NMEA0183SetDPT(NMEA0183Msg, DepthBelowTransducer, Offset) ) {
|
||||||
SendMessage(NMEA0183Msg);
|
SendMessage(NMEA0183Msg);
|
||||||
|
@ -206,12 +213,15 @@ void N2kDataToNMEA0183::HandleCOGSOG(const tN2kMsg &N2kMsg) {
|
||||||
double COG;
|
double COG;
|
||||||
double SOG;
|
double SOG;
|
||||||
if ( ParseN2kCOGSOGRapid(N2kMsg, SID, HeadingReference, COG, SOG) ) {
|
if ( ParseN2kCOGSOGRapid(N2kMsg, SID, HeadingReference, COG, SOG) ) {
|
||||||
cog->update(COG);
|
updateDouble(cog,COG);
|
||||||
sog->update(SOG);
|
updateDouble(sog,SOG);
|
||||||
double MCOG = ( !N2kIsNA(COG) && !N2kIsNA(Variation) ? COG - Variation : NMEA0183DoubleNA );
|
double MCOG = ( !N2kIsNA(COG) && variation->isValid()) ? COG - variation->getData() : NMEA0183DoubleNA ;
|
||||||
if ( HeadingReference == N2khr_magnetic ) {
|
if ( HeadingReference == N2khr_magnetic ) {
|
||||||
MCOG = COG;
|
MCOG = COG;
|
||||||
if ( !N2kIsNA(Variation) ) COG -= Variation;
|
if ( variation->isValid() ) {
|
||||||
|
COG -= variation->getData();
|
||||||
|
updateDouble(cog,COG);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( NMEA0183SetVTG(NMEA0183Msg, COG, MCOG, SOG) ) {
|
if ( NMEA0183SetVTG(NMEA0183Msg, COG, MCOG, SOG) ) {
|
||||||
SendMessage(NMEA0183Msg);
|
SendMessage(NMEA0183Msg);
|
||||||
|
@ -235,12 +245,16 @@ void N2kDataToNMEA0183::HandleGNSS(const tN2kMsg &N2kMsg) {
|
||||||
double Latitude;
|
double Latitude;
|
||||||
double Longitude;
|
double Longitude;
|
||||||
double Altitude;
|
double Altitude;
|
||||||
|
uint16_t DaysSince1970;
|
||||||
|
double SecondsSinceMidnight;
|
||||||
if ( ParseN2kGNSS(N2kMsg, SID, DaysSince1970, SecondsSinceMidnight, Latitude, Longitude, Altitude, GNSStype, GNSSmethod,
|
if ( ParseN2kGNSS(N2kMsg, SID, DaysSince1970, SecondsSinceMidnight, Latitude, Longitude, Altitude, GNSStype, GNSSmethod,
|
||||||
nSatellites, HDOP, PDOP, GeoidalSeparation,
|
nSatellites, HDOP, PDOP, GeoidalSeparation,
|
||||||
nReferenceStations, ReferenceStationType, ReferenceSationID, AgeOfCorrection) ) {
|
nReferenceStations, ReferenceStationType, ReferenceSationID, AgeOfCorrection) ) {
|
||||||
updateDouble(latitude,Latitude);
|
updateDouble(latitude,Latitude);
|
||||||
updateDouble(longitude,Longitude);
|
updateDouble(longitude,Longitude);
|
||||||
updateDouble(altitude,Altitude);
|
updateDouble(altitude,Altitude);
|
||||||
|
updateDouble(secondsSinceMidnight,SecondsSinceMidnight);
|
||||||
|
if (DaysSince1970 != N2kUInt16NA && DaysSince1970 !=0) daysSince1970->update(DaysSince1970);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,56 +267,47 @@ void N2kDataToNMEA0183::HandleWind(const tN2kMsg &N2kMsg) {
|
||||||
double x, y;
|
double x, y;
|
||||||
double WindAngle, WindSpeed;
|
double WindAngle, WindSpeed;
|
||||||
|
|
||||||
// double TWS, TWA, AWD;
|
|
||||||
|
|
||||||
if ( ParseN2kWindSpeed(N2kMsg, SID, WindSpeed, WindAngle, WindReference) ) {
|
if ( ParseN2kWindSpeed(N2kMsg, SID, WindSpeed, WindAngle, WindReference) ) {
|
||||||
tNMEA0183Msg NMEA0183Msg;
|
tNMEA0183Msg NMEA0183Msg;
|
||||||
LastWindTime = millis();
|
|
||||||
|
|
||||||
if ( WindReference == N2kWind_Apparent ) {
|
if ( WindReference == N2kWind_Apparent ) {
|
||||||
NMEA0183Reference = NMEA0183Wind_Apparent;
|
NMEA0183Reference = NMEA0183Wind_Apparent;
|
||||||
AWA=WindAngle;
|
updateDouble(awa,WindAngle);
|
||||||
AWS=WindSpeed;
|
updateDouble(aws,WindSpeed);
|
||||||
if (AWS > MaxAws) MaxAws=AWS;
|
setMax(maxAws,aws);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( NMEA0183SetMWV(NMEA0183Msg, WindAngle*radToDeg, NMEA0183Reference , WindSpeed)) SendMessage(NMEA0183Msg);
|
if ( NMEA0183SetMWV(NMEA0183Msg, formatCourse(WindAngle), NMEA0183Reference , WindSpeed)) SendMessage(NMEA0183Msg);
|
||||||
|
|
||||||
if (WindReference == N2kWind_Apparent && sog->isValid(millis())) { // Lets calculate and send TWS/TWA if SOG is available
|
if (WindReference == N2kWind_Apparent && sog->isValid()) { // Lets calculate and send TWS/TWA if SOG is available
|
||||||
|
|
||||||
AWD=WindAngle*radToDeg + heading->getData()*radToDeg;
|
|
||||||
if (AWD>360) AWD=AWD-360;
|
|
||||||
if (AWD<0) AWD=AWD+360;
|
|
||||||
|
|
||||||
x = WindSpeed * cos(WindAngle);
|
x = WindSpeed * cos(WindAngle);
|
||||||
y = WindSpeed * sin(WindAngle);
|
y = WindSpeed * sin(WindAngle);
|
||||||
|
|
||||||
TWA = atan2(y, -sog->getData() + x);
|
updateDouble(twd,atan2(y, -sog->getData() + x));
|
||||||
TWS = sqrt(( y*y) + ((- sog->getData()+x)*(-sog->getData()+x)));
|
updateDouble(tws,sqrt(( y*y) + ((- sog->getData()+x)*(-sog->getData()+x))));
|
||||||
|
|
||||||
if (TWS > MaxTws) MaxTws=TWS;
|
setMax(maxTws,tws);
|
||||||
|
|
||||||
TWA = TWA * radToDeg +360;
|
|
||||||
|
|
||||||
if (TWA>360) TWA=TWA-360;
|
|
||||||
if (TWA<0) TWA=TWA+360;
|
|
||||||
|
|
||||||
NMEA0183Reference = NMEA0183Wind_True;
|
NMEA0183Reference = NMEA0183Wind_True;
|
||||||
if ( NMEA0183SetMWV(NMEA0183Msg, TWA, NMEA0183Reference , TWS)) SendMessage(NMEA0183Msg);
|
if ( NMEA0183SetMWV(NMEA0183Msg,
|
||||||
|
formatCourse(twd->getData()),
|
||||||
|
NMEA0183Reference ,
|
||||||
|
tws->getDataWithDefault(NMEA0183DoubleNA))) SendMessage(NMEA0183Msg);
|
||||||
|
double magnetic=twd->getData();
|
||||||
|
if (variation->isValid()) magnetic-=variation->getData();
|
||||||
if ( !NMEA0183Msg.Init("MWD", "GP") ) return;
|
if ( !NMEA0183Msg.Init("MWD", "GP") ) return;
|
||||||
if ( !NMEA0183Msg.AddDoubleField(AWD) ) return;
|
if ( !NMEA0183Msg.AddDoubleField(formatCourse(twd->getData())) ) return;
|
||||||
if ( !NMEA0183Msg.AddStrField("T") ) return;
|
if ( !NMEA0183Msg.AddStrField("T") ) return;
|
||||||
if ( !NMEA0183Msg.AddDoubleField(AWD) ) return;
|
if ( !NMEA0183Msg.AddDoubleField(formatCourse(magnetic)) ) return;
|
||||||
if ( !NMEA0183Msg.AddStrField("M") ) return;
|
if ( !NMEA0183Msg.AddStrField("M") ) return;
|
||||||
if ( !NMEA0183Msg.AddDoubleField(TWS/0.514444) ) return;
|
if ( !NMEA0183Msg.AddDoubleField(tws->getData()/0.514444) ) return;
|
||||||
if ( !NMEA0183Msg.AddStrField("N") ) return;
|
if ( !NMEA0183Msg.AddStrField("N") ) return;
|
||||||
if ( !NMEA0183Msg.AddDoubleField(TWS) ) return;
|
if ( !NMEA0183Msg.AddDoubleField(tws->getData()) ) return;
|
||||||
if ( !NMEA0183Msg.AddStrField("M") ) return;
|
if ( !NMEA0183Msg.AddStrField("M") ) return;
|
||||||
|
|
||||||
SendMessage(NMEA0183Msg);
|
SendMessage(NMEA0183Msg);
|
||||||
|
|
||||||
TWA=TWA/radToDeg;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -312,7 +317,17 @@ void N2kDataToNMEA0183::HandleWind(const tN2kMsg &N2kMsg) {
|
||||||
long now=millis();
|
long now=millis();
|
||||||
if ( NextRMCSend <= millis() && latitude->isValid(now) ) {
|
if ( NextRMCSend <= millis() && latitude->isValid(now) ) {
|
||||||
tNMEA0183Msg NMEA0183Msg;
|
tNMEA0183Msg NMEA0183Msg;
|
||||||
if ( NMEA0183SetRMC(NMEA0183Msg, SecondsSinceMidnight, latitude->getData(), longitude->getData(), cog->getData(), sog->getData(), DaysSince1970, Variation) ) {
|
if ( NMEA0183SetRMC(NMEA0183Msg,
|
||||||
|
|
||||||
|
secondsSinceMidnight->getDataWithDefault(NMEA0183DoubleNA),
|
||||||
|
latitude->getDataWithDefault(NMEA0183DoubleNA),
|
||||||
|
longitude->getDataWithDefault(NMEA0183DoubleNA),
|
||||||
|
cog->getDataWithDefault(NMEA0183DoubleNA),
|
||||||
|
sog->getDataWithDefault(NMEA0183DoubleNA),
|
||||||
|
daysSince1970->getDataWithDefault(NMEA0183UInt32NA),
|
||||||
|
variation->getDataWithDefault(NMEA0183DoubleNA)
|
||||||
|
)
|
||||||
|
) {
|
||||||
SendMessage(NMEA0183Msg);
|
SendMessage(NMEA0183Msg);
|
||||||
}
|
}
|
||||||
SetNextRMCSend();
|
SetNextRMCSend();
|
||||||
|
@ -324,9 +339,11 @@ void N2kDataToNMEA0183::HandleWind(const tN2kMsg &N2kMsg) {
|
||||||
void N2kDataToNMEA0183::HandleLog(const tN2kMsg & N2kMsg) {
|
void N2kDataToNMEA0183::HandleLog(const tN2kMsg & N2kMsg) {
|
||||||
uint16_t DaysSince1970;
|
uint16_t DaysSince1970;
|
||||||
double SecondsSinceMidnight;
|
double SecondsSinceMidnight;
|
||||||
|
uint32_t Log,TripLog;
|
||||||
if ( ParseN2kDistanceLog(N2kMsg, DaysSince1970, SecondsSinceMidnight, Log, TripLog) ) {
|
if ( ParseN2kDistanceLog(N2kMsg, DaysSince1970, SecondsSinceMidnight, Log, TripLog) ) {
|
||||||
|
if (Log != N2kUInt32NA) log->update(Log);
|
||||||
|
if (TripLog != N2kUInt32NA) tripLog->update(TripLog);
|
||||||
|
if (DaysSince1970 != N2kUInt16NA && DaysSince1970 != 0) daysSince1970->update(DaysSince1970);
|
||||||
tNMEA0183Msg NMEA0183Msg;
|
tNMEA0183Msg NMEA0183Msg;
|
||||||
|
|
||||||
if ( !NMEA0183Msg.Init("VLW", "GP") ) return;
|
if ( !NMEA0183Msg.Init("VLW", "GP") ) return;
|
||||||
|
@ -345,15 +362,17 @@ void N2kDataToNMEA0183::HandleWind(const tN2kMsg &N2kMsg) {
|
||||||
unsigned char Instance;
|
unsigned char Instance;
|
||||||
tN2kRudderDirectionOrder RudderDirectionOrder;
|
tN2kRudderDirectionOrder RudderDirectionOrder;
|
||||||
double AngleOrder;
|
double AngleOrder;
|
||||||
|
double RudderPosition;
|
||||||
|
|
||||||
if ( ParseN2kRudder(N2kMsg, RudderPosition, Instance, RudderDirectionOrder, AngleOrder) ) {
|
if ( ParseN2kRudder(N2kMsg, RudderPosition, Instance, RudderDirectionOrder, AngleOrder) ) {
|
||||||
|
|
||||||
|
updateDouble(rudderPosition,RudderPosition);
|
||||||
if(Instance!=0) return;
|
if(Instance!=0) return;
|
||||||
|
|
||||||
tNMEA0183Msg NMEA0183Msg;
|
tNMEA0183Msg NMEA0183Msg;
|
||||||
|
|
||||||
if ( !NMEA0183Msg.Init("RSA", "GP") ) return;
|
if ( !NMEA0183Msg.Init("RSA", "GP") ) return;
|
||||||
if ( !NMEA0183Msg.AddDoubleField(RudderPosition * radToDeg) ) return;
|
if ( !NMEA0183Msg.AddDoubleField(formatCourse(RudderPosition)) ) return;
|
||||||
if ( !NMEA0183Msg.AddStrField("A") ) return;
|
if ( !NMEA0183Msg.AddStrField("A") ) return;
|
||||||
if ( !NMEA0183Msg.AddDoubleField(0.0) ) return;
|
if ( !NMEA0183Msg.AddDoubleField(0.0) ) return;
|
||||||
if ( !NMEA0183Msg.AddStrField("A") ) return;
|
if ( !NMEA0183Msg.AddStrField("A") ) return;
|
||||||
|
@ -368,9 +387,10 @@ void N2kDataToNMEA0183::HandleWind(const tN2kMsg &N2kMsg) {
|
||||||
unsigned char SID;
|
unsigned char SID;
|
||||||
double OutsideAmbientAirTemperature;
|
double OutsideAmbientAirTemperature;
|
||||||
double AtmosphericPressure;
|
double AtmosphericPressure;
|
||||||
|
double WaterTemperature;
|
||||||
if ( ParseN2kPGN130310(N2kMsg, SID, WaterTemperature, OutsideAmbientAirTemperature, AtmosphericPressure) ) {
|
if ( ParseN2kPGN130310(N2kMsg, SID, WaterTemperature, OutsideAmbientAirTemperature, AtmosphericPressure) ) {
|
||||||
|
|
||||||
|
updateDouble(waterTemperature,WaterTemperature);
|
||||||
tNMEA0183Msg NMEA0183Msg;
|
tNMEA0183Msg NMEA0183Msg;
|
||||||
|
|
||||||
if ( !NMEA0183Msg.Init("MTW", "GP") ) return;
|
if ( !NMEA0183Msg.Init("MTW", "GP") ) return;
|
||||||
|
|
|
@ -39,35 +39,33 @@ protected:
|
||||||
GwBoatItem<double> *latitude;
|
GwBoatItem<double> *latitude;
|
||||||
GwBoatItem<double> *longitude;
|
GwBoatItem<double> *longitude;
|
||||||
GwBoatItem<double> * altitude;
|
GwBoatItem<double> * altitude;
|
||||||
double Variation;
|
GwBoatItem<double> *variation;
|
||||||
GwBoatItem<double> *heading;
|
GwBoatItem<double> *heading;
|
||||||
GwBoatItem<double> *cog;
|
GwBoatItem<double> *cog;
|
||||||
GwBoatItem<double> *sog;
|
GwBoatItem<double> *sog;
|
||||||
double STW;
|
GwBoatItem<double> *stw;
|
||||||
|
|
||||||
double TWS;
|
GwBoatItem<double> *tws;
|
||||||
double TWA;
|
GwBoatItem<double> *twd;
|
||||||
double TWD;
|
|
||||||
|
|
||||||
double AWS;
|
GwBoatItem<double> *aws;
|
||||||
double AWA;
|
GwBoatItem<double> *awa;
|
||||||
double AWD;
|
GwBoatItem<double> *awd;
|
||||||
|
|
||||||
|
GwBoatItem<double> *maxAws;
|
||||||
|
GwBoatItem<double> *maxTws;
|
||||||
|
|
||||||
|
GwBoatItem<double> *rudderPosition;
|
||||||
|
GwBoatItem<double> *waterTemperature;
|
||||||
|
GwBoatItem<double> *waterDepth;
|
||||||
|
|
||||||
double MaxAws;
|
GwBoatItem<uint32_t> *tripLog;
|
||||||
double MaxTws;
|
GwBoatItem<uint32_t> *log;
|
||||||
|
GwBoatItem<uint32_t> *daysSince1970;
|
||||||
|
GwBoatItem<double> *secondsSinceMidnight;
|
||||||
|
|
||||||
double RudderPosition;
|
|
||||||
double WaterTemperature;
|
|
||||||
double WaterDepth;
|
|
||||||
|
|
||||||
uint32_t TripLog;
|
|
||||||
uint32_t Log;
|
|
||||||
|
|
||||||
uint16_t DaysSince1970;
|
|
||||||
double SecondsSinceMidnight;
|
|
||||||
|
|
||||||
unsigned long LastPosSend;
|
unsigned long LastPosSend;
|
||||||
unsigned long LastWindTime;
|
|
||||||
unsigned long NextRMCSend;
|
unsigned long NextRMCSend;
|
||||||
unsigned long lastLoopTime;
|
unsigned long lastLoopTime;
|
||||||
|
|
||||||
|
|
|
@ -210,7 +210,6 @@ void setup() {
|
||||||
webserver.on("/api/resetConfig",web_resetConfig);
|
webserver.on("/api/resetConfig",web_resetConfig);
|
||||||
webserver.on("/api/boatData",js_boatData);
|
webserver.on("/api/boatData",js_boatData);
|
||||||
webserver.onNotFound(handleNotFound);
|
webserver.onNotFound(handleNotFound);
|
||||||
|
|
||||||
webserver.begin();
|
webserver.begin();
|
||||||
Serial.println("HTTP server started");
|
Serial.println("HTTP server started");
|
||||||
|
|
||||||
|
@ -308,7 +307,6 @@ void loop() {
|
||||||
preferences.end();
|
preferences.end();
|
||||||
Serial.printf("Address Change: New Address=%d\n", SourceAddress);
|
Serial.printf("Address Change: New Address=%d\n", SourceAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
nmea0183Converter.loop();
|
nmea0183Converter.loop();
|
||||||
|
|
||||||
// Dummy to empty input buffer to avoid board to stuck with e.g. NMEA Reader
|
// Dummy to empty input buffer to avoid board to stuck with e.g. NMEA Reader
|
||||||
|
|
Loading…
Reference in New Issue