add XDR min interval, N2K min interval, add N2K_LOAD_LEVEL and N2K_CERTIFICATION_LEVEL
This commit is contained in:
parent
b01dabf8cc
commit
3e73f6b80c
|
@ -20,6 +20,8 @@
|
||||||
#ifdef BOARD_M5ATOM
|
#ifdef BOARD_M5ATOM
|
||||||
#define ESP32_CAN_TX_PIN GPIO_NUM_22
|
#define ESP32_CAN_TX_PIN GPIO_NUM_22
|
||||||
#define ESP32_CAN_RX_PIN GPIO_NUM_19
|
#define ESP32_CAN_RX_PIN GPIO_NUM_19
|
||||||
|
//150mA if we power from the bus
|
||||||
|
#define N2K_LOAD_LEVEL 3
|
||||||
//if using tail485
|
//if using tail485
|
||||||
#define GWSERIAL_TX 26
|
#define GWSERIAL_TX 26
|
||||||
#define GWSERIAL_RX 32
|
#define GWSERIAL_RX 32
|
||||||
|
|
|
@ -49,7 +49,8 @@ class NMEA0183DataToN2KFunctions : public NMEA0183DataToN2K
|
||||||
private:
|
private:
|
||||||
MyAisDecoder *aisDecoder=NULL;
|
MyAisDecoder *aisDecoder=NULL;
|
||||||
ConverterList<NMEA0183DataToN2KFunctions, SNMEA0183Msg> converters;
|
ConverterList<NMEA0183DataToN2KFunctions, SNMEA0183Msg> converters;
|
||||||
std::map<unsigned long,unsigned long> lastSends;
|
std::map<String,unsigned long> lastSends;
|
||||||
|
unsigned long minSendInterval=50;
|
||||||
class WaypointNumber{
|
class WaypointNumber{
|
||||||
public:
|
public:
|
||||||
unsigned long id;
|
unsigned long id;
|
||||||
|
@ -92,22 +93,26 @@ private:
|
||||||
waypointMap[wpName]=newWp;
|
waypointMap[wpName]=newWp;
|
||||||
return newWp.id;
|
return newWp.id;
|
||||||
}
|
}
|
||||||
bool send(tN2kMsg &msg,unsigned long minDiff=50){
|
bool send(tN2kMsg &msg,String key,unsigned long minDiff){
|
||||||
unsigned long now=millis();
|
unsigned long now=millis();
|
||||||
unsigned long pgn=msg.PGN;
|
unsigned long pgn=msg.PGN;
|
||||||
auto it=lastSends.find(pgn);
|
if (key == "") key=String(msg.PGN);
|
||||||
|
auto it=lastSends.find(key);
|
||||||
if (it == lastSends.end()){
|
if (it == lastSends.end()){
|
||||||
lastSends[pgn]=now;
|
lastSends[key]=now;
|
||||||
sender(msg);
|
sender(msg);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((it->second + minDiff) <= now){
|
if ((it->second + minDiff) <= now){
|
||||||
lastSends[pgn]=now;
|
lastSends[key]=now;
|
||||||
sender(msg);
|
sender(msg);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool send(tN2kMsg &msg, String key=""){
|
||||||
|
send(msg,key,minSendInterval);
|
||||||
|
}
|
||||||
bool updateDouble(GwBoatItem<double> *target,double v, int sourceId){
|
bool updateDouble(GwBoatItem<double> *target,double v, int sourceId){
|
||||||
if (v != NMEA0183DoubleNA){
|
if (v != NMEA0183DoubleNA){
|
||||||
return target->update(v,sourceId);
|
return target->update(v,sourceId);
|
||||||
|
@ -256,7 +261,7 @@ private:
|
||||||
}
|
}
|
||||||
if (shouldSend){
|
if (shouldSend){
|
||||||
SetN2kWindSpeed(n2kMsg,1,WindSpeed,WindAngle,n2kRef);
|
SetN2kWindSpeed(n2kMsg,1,WindSpeed,WindAngle,n2kRef);
|
||||||
send(n2kMsg);
|
send(n2kMsg,String(n2kMsg.PGN)+String((int)n2kRef));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void convertVWR(const SNMEA0183Msg &msg)
|
void convertVWR(const SNMEA0183Msg &msg)
|
||||||
|
@ -297,7 +302,7 @@ private:
|
||||||
if (shouldSend)
|
if (shouldSend)
|
||||||
{
|
{
|
||||||
SetN2kWindSpeed(n2kMsg, 1, WindSpeed, WindAngle, N2kWind_Apparent);
|
SetN2kWindSpeed(n2kMsg, 1, WindSpeed, WindAngle, N2kWind_Apparent);
|
||||||
send(n2kMsg);
|
send(n2kMsg,String(n2kMsg.PGN)+String((int)N2kWind_Apparent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,11 +346,11 @@ private:
|
||||||
if (shouldSend)
|
if (shouldSend)
|
||||||
{
|
{
|
||||||
SetN2kWindSpeed(n2kMsg, 1, WindSpeed, WindAngle, N2kWind_True_North);
|
SetN2kWindSpeed(n2kMsg, 1, WindSpeed, WindAngle, N2kWind_True_North);
|
||||||
send(n2kMsg);
|
send(n2kMsg,String(n2kMsg.PGN)+String((int)N2kWind_True_North));
|
||||||
}
|
}
|
||||||
if (WindAngleMagnetic != NMEA0183DoubleNA && shouldSend){
|
if (WindAngleMagnetic != NMEA0183DoubleNA && shouldSend){
|
||||||
SetN2kWindSpeed(n2kMsg, 1, WindSpeed, WindAngleMagnetic, N2kWind_Magnetic);
|
SetN2kWindSpeed(n2kMsg, 1, WindSpeed, WindAngleMagnetic, N2kWind_Magnetic);
|
||||||
send(n2kMsg,0); //force sending
|
send(n2kMsg,String(n2kMsg.PGN)+String((int)N2kWind_Magnetic));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,7 +439,7 @@ private:
|
||||||
if (! boatData->DepthTransducer->update(DepthBelowTransducer)) return;
|
if (! boatData->DepthTransducer->update(DepthBelowTransducer)) return;
|
||||||
tN2kMsg n2kMsg;
|
tN2kMsg n2kMsg;
|
||||||
SetN2kWaterDepth(n2kMsg,1,DepthBelowTransducer,Offset);
|
SetN2kWaterDepth(n2kMsg,1,DepthBelowTransducer,Offset);
|
||||||
send(n2kMsg);
|
send(n2kMsg,String(n2kMsg.PGN)+String((Offset != N2kDoubleNA)?1:0));
|
||||||
}
|
}
|
||||||
typedef enum {
|
typedef enum {
|
||||||
DBS,
|
DBS,
|
||||||
|
@ -469,7 +474,7 @@ private:
|
||||||
if (! boatData->DepthTransducer->update(Depth,msg.sourceId)) return;
|
if (! boatData->DepthTransducer->update(Depth,msg.sourceId)) return;
|
||||||
tN2kMsg n2kMsg;
|
tN2kMsg n2kMsg;
|
||||||
SetN2kWaterDepth(n2kMsg,1,Depth,N2kDoubleNA);
|
SetN2kWaterDepth(n2kMsg,1,Depth,N2kDoubleNA);
|
||||||
send(n2kMsg);
|
send(n2kMsg,String(n2kMsg.PGN)+String(0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//we can only send if we have a valid depth beloww tranducer
|
//we can only send if we have a valid depth beloww tranducer
|
||||||
|
@ -489,7 +494,7 @@ private:
|
||||||
}
|
}
|
||||||
tN2kMsg n2kMsg;
|
tN2kMsg n2kMsg;
|
||||||
SetN2kWaterDepth(n2kMsg,1,Depth,offset);
|
SetN2kWaterDepth(n2kMsg,1,Depth,offset);
|
||||||
send(n2kMsg);
|
send(n2kMsg,String(n2kMsg.PGN)+String((offset != N2kDoubleNA)?1:0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -853,16 +858,18 @@ public:
|
||||||
return converters.handledKeys();
|
return converters.handledKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
NMEA0183DataToN2KFunctions(GwLog *logger, GwBoatData *boatData, N2kSender callback)
|
NMEA0183DataToN2KFunctions(GwLog *logger, GwBoatData *boatData, N2kSender callback, unsigned long minSendInterval)
|
||||||
: NMEA0183DataToN2K(logger, boatData, callback)
|
: NMEA0183DataToN2K(logger, boatData, callback)
|
||||||
{
|
{
|
||||||
|
this->minSendInterval=minSendInterval;
|
||||||
aisDecoder= new MyAisDecoder(logger,this->sender);
|
aisDecoder= new MyAisDecoder(logger,this->sender);
|
||||||
registerConverters();
|
registerConverters();
|
||||||
LOG_DEBUG(GwLog::LOG, "NMEA0183DataToN2KFunctions: registered %d converters", converters.numConverters());
|
LOG_DEBUG(GwLog::LOG, "NMEA0183DataToN2KFunctions: registered %d converters", converters.numConverters());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
NMEA0183DataToN2K* NMEA0183DataToN2K::create(GwLog *logger,GwBoatData *boatData,N2kSender callback){
|
NMEA0183DataToN2K* NMEA0183DataToN2K::create(GwLog *logger,GwBoatData *boatData,N2kSender callback,
|
||||||
return new NMEA0183DataToN2KFunctions(logger, boatData,callback);
|
unsigned long minSendInterval){
|
||||||
|
return new NMEA0183DataToN2KFunctions(logger, boatData,callback,minSendInterval);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ class NMEA0183DataToN2K{
|
||||||
virtual unsigned long *handledPgns()=0;
|
virtual unsigned long *handledPgns()=0;
|
||||||
virtual int numConverters()=0;
|
virtual int numConverters()=0;
|
||||||
virtual String handledKeys()=0;
|
virtual String handledKeys()=0;
|
||||||
static NMEA0183DataToN2K* create(GwLog *logger,GwBoatData *boatData,N2kSender callback);
|
static NMEA0183DataToN2K* create(GwLog *logger,GwBoatData *boatData,N2kSender callback,
|
||||||
|
unsigned long minSendInterval);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
|
@ -36,7 +36,6 @@
|
||||||
N2kDataToNMEA0183::N2kDataToNMEA0183(GwLog * logger, GwBoatData *boatData,
|
N2kDataToNMEA0183::N2kDataToNMEA0183(GwLog * logger, GwBoatData *boatData,
|
||||||
tSendNMEA0183MessageCallback callback, int id,String talkerId)
|
tSendNMEA0183MessageCallback callback, int id,String talkerId)
|
||||||
{
|
{
|
||||||
SendNMEA0183MessageCallback=0;
|
|
||||||
this->SendNMEA0183MessageCallback=callback;
|
this->SendNMEA0183MessageCallback=callback;
|
||||||
strncpy(this->talkerId,talkerId.c_str(),2);
|
strncpy(this->talkerId,talkerId.c_str(),2);
|
||||||
this->talkerId[2]=0;
|
this->talkerId[2]=0;
|
||||||
|
@ -65,27 +64,45 @@ class N2kToNMEA0183Functions : public N2kDataToNMEA0183
|
||||||
{
|
{
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int minXdrInterval=100; //minimal interval between 2 sends of the same transducer
|
||||||
GwXDRMappings *xdrMappings;
|
GwXDRMappings *xdrMappings;
|
||||||
ConverterList<N2kToNMEA0183Functions,tN2kMsg> converters;
|
ConverterList<N2kToNMEA0183Functions,tN2kMsg> converters;
|
||||||
|
std::map<String,unsigned long> lastSendTransducers;
|
||||||
static const unsigned long RMCPeriod = 500;
|
static const unsigned long RMCPeriod = 500;
|
||||||
tNMEA0183Msg xdrMessage;
|
tNMEA0183Msg xdrMessage;
|
||||||
bool xdrOpened=false;
|
bool xdrOpened=false;
|
||||||
|
int xdrCount=0;
|
||||||
|
|
||||||
bool addToXdr(String entry){
|
bool addToXdr(GwXDRFoundMapping::XdrEntry entry){
|
||||||
|
auto it=lastSendTransducers.find(entry.transducer);
|
||||||
|
unsigned long now=millis();
|
||||||
|
if (it != lastSendTransducers.end()){
|
||||||
|
if ((it->second + minXdrInterval) > now) return false;
|
||||||
|
}
|
||||||
|
lastSendTransducers[entry.transducer]=now;
|
||||||
if (! xdrOpened){
|
if (! xdrOpened){
|
||||||
xdrMessage.Init("XDR",talkerId);
|
xdrMessage.Init("XDR",talkerId);
|
||||||
xdrOpened=true;
|
xdrOpened=true;
|
||||||
|
xdrCount=0;
|
||||||
}
|
}
|
||||||
int len=entry.length();
|
int len=entry.entry.length();
|
||||||
if (! xdrMessage.AddStrField(entry.c_str())){
|
if (! xdrMessage.AddStrField(entry.entry.c_str())){
|
||||||
SendMessage(xdrMessage);
|
SendMessage(xdrMessage);
|
||||||
xdrMessage.Init("XDR",talkerId);
|
xdrMessage.Init("XDR",talkerId);
|
||||||
xdrMessage.AddStrField(entry.c_str());
|
xdrMessage.AddStrField(entry.entry.c_str());
|
||||||
|
xdrCount=1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
xdrCount++;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool finalizeXdr(){
|
bool finalizeXdr(){
|
||||||
if (! xdrOpened) return false;
|
if (! xdrOpened) return false;
|
||||||
|
if ( xdrCount < 1){
|
||||||
|
xdrOpened=false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
SendMessage(xdrMessage);
|
SendMessage(xdrMessage);
|
||||||
xdrOpened=false;
|
xdrOpened=false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -1451,7 +1468,7 @@ private:
|
||||||
public:
|
public:
|
||||||
N2kToNMEA0183Functions(GwLog *logger, GwBoatData *boatData,
|
N2kToNMEA0183Functions(GwLog *logger, GwBoatData *boatData,
|
||||||
tSendNMEA0183MessageCallback callback, int sourceId,
|
tSendNMEA0183MessageCallback callback, int sourceId,
|
||||||
String talkerId, GwXDRMappings *xdrMappings)
|
String talkerId, GwXDRMappings *xdrMappings, int minXdrInterval)
|
||||||
: N2kDataToNMEA0183(logger, boatData, callback,sourceId,talkerId)
|
: N2kDataToNMEA0183(logger, boatData, callback,sourceId,talkerId)
|
||||||
{
|
{
|
||||||
LastPosSend = 0;
|
LastPosSend = 0;
|
||||||
|
@ -1461,6 +1478,7 @@ private:
|
||||||
this->logger = logger;
|
this->logger = logger;
|
||||||
this->boatData = boatData;
|
this->boatData = boatData;
|
||||||
this->xdrMappings=xdrMappings;
|
this->xdrMappings=xdrMappings;
|
||||||
|
this->minXdrInterval=minXdrInterval;
|
||||||
registerConverters();
|
registerConverters();
|
||||||
}
|
}
|
||||||
virtual void loop()
|
virtual void loop()
|
||||||
|
@ -1476,8 +1494,9 @@ private:
|
||||||
|
|
||||||
|
|
||||||
N2kDataToNMEA0183* N2kDataToNMEA0183::create(GwLog *logger, GwBoatData *boatData,
|
N2kDataToNMEA0183* N2kDataToNMEA0183::create(GwLog *logger, GwBoatData *boatData,
|
||||||
tSendNMEA0183MessageCallback callback, int sourceId,String talkerId, GwXDRMappings *xdrMappings){
|
tSendNMEA0183MessageCallback callback, int sourceId,String talkerId, GwXDRMappings *xdrMappings,
|
||||||
|
int minXdrInterval){
|
||||||
LOG_DEBUG(GwLog::LOG,"creating N2kToNMEA0183");
|
LOG_DEBUG(GwLog::LOG,"creating N2kToNMEA0183");
|
||||||
return new N2kToNMEA0183Functions(logger,boatData,callback, sourceId,talkerId,xdrMappings);
|
return new N2kToNMEA0183Functions(logger,boatData,callback, sourceId,talkerId,xdrMappings,minXdrInterval);
|
||||||
}
|
}
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
|
|
@ -48,7 +48,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static N2kDataToNMEA0183* create(GwLog *logger, GwBoatData *boatData, tSendNMEA0183MessageCallback callback,
|
static N2kDataToNMEA0183* create(GwLog *logger, GwBoatData *boatData, tSendNMEA0183MessageCallback callback,
|
||||||
int sourceId,String talkerId, GwXDRMappings *xdrMappings);
|
int sourceId,String talkerId, GwXDRMappings *xdrMappings,int minXdrInterval=100);
|
||||||
virtual void HandleMsg(const tN2kMsg &N2kMsg) = 0;
|
virtual void HandleMsg(const tN2kMsg &N2kMsg) = 0;
|
||||||
virtual void loop();
|
virtual void loop();
|
||||||
virtual ~N2kDataToNMEA0183(){}
|
virtual ~N2kDataToNMEA0183(){}
|
||||||
|
|
|
@ -208,10 +208,11 @@ String GwXDRMappingDef::getTransducerName(int instance)
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
String GwXDRFoundMapping::buildXdrEntry(double value)
|
GwXDRFoundMapping::XdrEntry GwXDRFoundMapping::buildXdrEntry(double value)
|
||||||
{
|
{
|
||||||
char buffer[40];
|
char buffer[40];
|
||||||
String name = getTransducerName();
|
XdrEntry rt;
|
||||||
|
rt.transducer = getTransducerName();
|
||||||
if (type->tonmea)
|
if (type->tonmea)
|
||||||
{
|
{
|
||||||
value = (*(type->tonmea))(value);
|
value = (*(type->tonmea))(value);
|
||||||
|
@ -220,9 +221,10 @@ String GwXDRFoundMapping::buildXdrEntry(double value)
|
||||||
type->xdrtype.c_str(),
|
type->xdrtype.c_str(),
|
||||||
value,
|
value,
|
||||||
type->xdrunit.c_str(),
|
type->xdrunit.c_str(),
|
||||||
name.c_str());
|
rt.transducer.c_str());
|
||||||
buffer[39] = 0;
|
buffer[39] = 0;
|
||||||
return String(buffer);
|
rt.entry=String(buffer);
|
||||||
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
GwXDRMappings::GwXDRMappings(GwLog *logger, GwConfigHandler *config)
|
GwXDRMappings::GwXDRMappings(GwLog *logger, GwConfigHandler *config)
|
||||||
|
@ -441,7 +443,7 @@ String GwXDRMappings::getXdrEntry(String mapping, double value,int instance){
|
||||||
found.instanceId=instance;
|
found.instanceId=instance;
|
||||||
if (first) first=false;
|
if (first) first=false;
|
||||||
else rt+=",";
|
else rt+=",";
|
||||||
rt+=found.buildXdrEntry(value);
|
rt+=found.buildXdrEntry(value).entry;
|
||||||
type = findType(code, &typeIndex);
|
type = findType(code, &typeIndex);
|
||||||
}
|
}
|
||||||
delete def;
|
delete def;
|
||||||
|
|
|
@ -147,6 +147,11 @@ class GwXDRMapping{
|
||||||
};
|
};
|
||||||
class GwXDRFoundMapping : public GwBoatItemNameProvider{
|
class GwXDRFoundMapping : public GwBoatItemNameProvider{
|
||||||
public:
|
public:
|
||||||
|
class XdrEntry{
|
||||||
|
public:
|
||||||
|
String entry;
|
||||||
|
String transducer;
|
||||||
|
};
|
||||||
GwXDRMappingDef *definition=NULL;
|
GwXDRMappingDef *definition=NULL;
|
||||||
GwXDRType *type=NULL;
|
GwXDRType *type=NULL;
|
||||||
int instanceId=-1;
|
int instanceId=-1;
|
||||||
|
@ -166,7 +171,7 @@ class GwXDRFoundMapping : public GwBoatItemNameProvider{
|
||||||
String getTransducerName(){
|
String getTransducerName(){
|
||||||
return definition->getTransducerName(instanceId);
|
return definition->getTransducerName(instanceId);
|
||||||
}
|
}
|
||||||
String buildXdrEntry(double value);
|
XdrEntry buildXdrEntry(double value);
|
||||||
//boat Data info
|
//boat Data info
|
||||||
virtual String getBoatItemName(){
|
virtual String getBoatItemName(){
|
||||||
return String("xdr")+getTransducerName();
|
return String("xdr")+getTransducerName();
|
||||||
|
|
26
src/main.cpp
26
src/main.cpp
|
@ -31,8 +31,17 @@
|
||||||
//#define FALLBACK_SERIAL
|
//#define FALLBACK_SERIAL
|
||||||
const unsigned long HEAP_REPORT_TIME=2000; //set to 0 to disable heap reporting
|
const unsigned long HEAP_REPORT_TIME=2000; //set to 0 to disable heap reporting
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include "GwApi.h"
|
||||||
#include "GwHardware.h"
|
#include "GwHardware.h"
|
||||||
|
|
||||||
|
#ifndef N2K_LOAD_LEVEL
|
||||||
|
#define N2K_LOAD_LEVEL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef N2K_CERTIFICATION_LEVEL
|
||||||
|
#define N2K_CERTIFICATION_LEVEL 0xff
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <NMEA2000_CAN.h> // This will automatically choose right CAN library and create suitable NMEA2000 object
|
#include <NMEA2000_CAN.h> // This will automatically choose right CAN library and create suitable NMEA2000 object
|
||||||
#include <ActisenseReader.h>
|
#include <ActisenseReader.h>
|
||||||
#include <Seasmart.h>
|
#include <Seasmart.h>
|
||||||
|
@ -65,8 +74,6 @@ const unsigned long HEAP_REPORT_TIME=2000; //set to 0 to disable heap reporting
|
||||||
#include "GwUserCode.h"
|
#include "GwUserCode.h"
|
||||||
|
|
||||||
|
|
||||||
#include "GwApi.h"
|
|
||||||
|
|
||||||
//NMEA message channels
|
//NMEA message channels
|
||||||
#define N2K_CHANNEL_ID 0
|
#define N2K_CHANNEL_ID 0
|
||||||
#define USB_CHANNEL_ID 1
|
#define USB_CHANNEL_ID 1
|
||||||
|
@ -699,13 +706,19 @@ void setup() {
|
||||||
[](const tNMEA0183Msg &msg, int sourceId){
|
[](const tNMEA0183Msg &msg, int sourceId){
|
||||||
SendNMEA0183Message(msg,sourceId,false);
|
SendNMEA0183Message(msg,sourceId,false);
|
||||||
}
|
}
|
||||||
, N2K_CHANNEL_ID,config.getString(config.talkerId,String("GP")),&xdrMappings);
|
, N2K_CHANNEL_ID,
|
||||||
|
config.getString(config.talkerId,String("GP")),
|
||||||
|
&xdrMappings,
|
||||||
|
config.getInt(config.minXdrInterval,100)
|
||||||
|
);
|
||||||
|
|
||||||
toN2KConverter= NMEA0183DataToN2K::create(&logger,&boatData,[](const tN2kMsg &msg)->bool{
|
toN2KConverter= NMEA0183DataToN2K::create(&logger,&boatData,[](const tN2kMsg &msg)->bool{
|
||||||
logger.logDebug(GwLog::DEBUG+2,"send N2K %ld",msg.PGN);
|
logger.logDebug(GwLog::DEBUG+2,"send N2K %ld",msg.PGN);
|
||||||
handleN2kMessage(msg,N2KT_MSGOUT);
|
handleN2kMessage(msg,N2KT_MSGOUT);
|
||||||
return true;
|
return true;
|
||||||
});
|
},
|
||||||
|
config.getInt(config.min2KInterval,50)
|
||||||
|
);
|
||||||
|
|
||||||
NMEA2000.SetN2kCANMsgBufSize(8);
|
NMEA2000.SetN2kCANMsgBufSize(8);
|
||||||
NMEA2000.SetN2kCANReceiveFrameBufSize(250);
|
NMEA2000.SetN2kCANReceiveFrameBufSize(250);
|
||||||
|
@ -719,7 +732,10 @@ void setup() {
|
||||||
100, // Manufacturer's product code
|
100, // Manufacturer's product code
|
||||||
systemName->asCString(), // Manufacturer's Model ID
|
systemName->asCString(), // Manufacturer's Model ID
|
||||||
VERSION, // Manufacturer's Software version code
|
VERSION, // Manufacturer's Software version code
|
||||||
VERSION // Manufacturer's Model version
|
VERSION, // Manufacturer's Model version,
|
||||||
|
N2K_LOAD_LEVEL,
|
||||||
|
0xffff, //Version
|
||||||
|
N2K_CERTIFICATION_LEVEL
|
||||||
);
|
);
|
||||||
// Set device information
|
// Set device information
|
||||||
NMEA2000.SetDeviceInformation(id, // Unique number. Use e.g. Serial number. Id is generated from MAC-Address
|
NMEA2000.SetDeviceInformation(id, // Unique number. Use e.g. Serial number. Id is generated from MAC-Address
|
||||||
|
|
|
@ -123,6 +123,24 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "minXdrInterval",
|
||||||
|
"label":"min XDR interval",
|
||||||
|
"type": "number",
|
||||||
|
"default": "100",
|
||||||
|
"check": "checkMinXdrInterval",
|
||||||
|
"description": "min interval in ms between 2 XDR records with the same transducer (> 10)",
|
||||||
|
"category": "converter"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "min2KInterval",
|
||||||
|
"label":"min N2K interval",
|
||||||
|
"type": "number",
|
||||||
|
"default": "50",
|
||||||
|
"check": "checkMin2KInterval",
|
||||||
|
"description": "min interval in ms between 2 NMEA 2000 records with the same PGN (> 5)",
|
||||||
|
"category": "converter"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "usbActisense",
|
"name": "usbActisense",
|
||||||
"label": "USB mode",
|
"label": "USB mode",
|
||||||
|
|
10
web/index.js
10
web/index.js
|
@ -124,6 +124,16 @@ function checkApPass(v) {
|
||||||
return "password must be at least 8 characters";
|
return "password must be at least 8 characters";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function checkMinXdrInterval(v){
|
||||||
|
let vv=parseInt(v);
|
||||||
|
if (isNaN(vv)) return "is not a number";
|
||||||
|
if (vv < 10) return "must be >= 10";
|
||||||
|
}
|
||||||
|
function checkMin2KInterval(v){
|
||||||
|
let vv=parseInt(v);
|
||||||
|
if (isNaN(vv)) return "is not a number";
|
||||||
|
if (vv < 5) return "must be >= 5";
|
||||||
|
}
|
||||||
function checkXDR(v,allValues){
|
function checkXDR(v,allValues){
|
||||||
if (! v) return;
|
if (! v) return;
|
||||||
let parts=v.split(',');
|
let parts=v.split(',');
|
||||||
|
|
Loading…
Reference in New Issue